diff --git a/Config/config.properties b/Config/config.properties
index da0b788..49cd969 100644
--- a/Config/config.properties
+++ b/Config/config.properties
@@ -10,7 +10,7 @@ AudioFile03 = pinkNoiseWav.wav
AudioFile04 = 04.mp3
AudioFile05 = 05.mp3
AudioVolumeOutput = 100
-SerialPort = /dev/ttyAMA0
+SerialPort = /dev/ttyTHS1
SerialBaudRate = 9600
PanTiltID = 1
WebUsername = admin
diff --git a/Html/html/index.js b/Html/html/index.js
index 4a4ea2e..97425cd 100644
--- a/Html/html/index.js
+++ b/Html/html/index.js
@@ -692,11 +692,12 @@ function process_command(dx){
* @type {{cpu_temperature: string, ram_usage: string, cpu: string, cpu0: string, cpu1: string, cpu2: string, cpu3: string}} systeminfo
*/
let systeminfo = JSON.parse(dx.data);
+ //console.log(systeminfo);
if (systeminfo.cpu_temperature && systeminfo.cpu_temperature.length>0) $('#cpu_temperature').html(`${systeminfo.cpu_temperature} °C`);
if (systeminfo.cpu && systeminfo.cpu.length>0) $('#cpu_usage').html(`${systeminfo.cpu} %`);
if (systeminfo.ram_usage && systeminfo.ram_usage.length>0) $('#ram_usage').html(`${systeminfo.ram_usage} %`);
- if (systeminfo.end0_TX && systeminfo.end0_TX.length>0) $('#ethernet_TX').html(systeminfo.end0_TX);
- if (systeminfo.end0_RX && systeminfo.end0_RX.length>0) $('#ethernet_RX').html(systeminfo.end0_RX);
+ if (systeminfo.enP8p1s0_TX && systeminfo.enP8p1s0_TX.length>0) $('#ethernet_TX').html(systeminfo.enP8p1s0_TX);
+ if (systeminfo.enP8p1s0_RX && systeminfo.enP8p1s0_RX.length>0) $('#ethernet_RX').html(systeminfo.enP8p1s0_RX);
break;
case "GET AUDIOFILES":
//console.log("Get Audio Files: "+dx.data);
diff --git a/config.properties b/config.properties
index 8a5537c..b648323 100644
--- a/config.properties
+++ b/config.properties
@@ -12,7 +12,7 @@ Camera_port=80
Camera_user=root
PanTiltID=1
SerialBaudRate=9600
-SerialPort=/dev/ttyAMA0
+SerialPort=/dev/ttyTHS1
WebHost=0.0.0.0
WebPassword=bandara
WebPort=8080
diff --git a/onnx/yolov8n.onnx b/onnx/yolo11n.onnx
similarity index 53%
rename from onnx/yolov8n.onnx
rename to onnx/yolo11n.onnx
index ade7079..cb0b371 100644
Binary files a/onnx/yolov8n.onnx and b/onnx/yolo11n.onnx differ
diff --git a/onnx/yolov8m.onnx b/onnx/yolov8m.onnx
deleted file mode 100644
index 1ad3394..0000000
Binary files a/onnx/yolov8m.onnx and /dev/null differ
diff --git a/pom.xml b/pom.xml
index 7243a9a..a4abf65 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,12 +57,13 @@
linux-arm64
+
org.bytedeco
tensorrt
8.6-1.5.10
- linux-arm64
+
org.bytedeco
cuda
@@ -70,6 +71,19 @@
linux-arm64
+
+ org.bytedeco
+ javacpp
+ 1.5.11
+ windows-x86_64
+
+
+ org.bytedeco
+ javacpp
+ 1.5.11
+ linux-arm64
+
+
com.corundumstudio.socketio
diff --git a/src/main/java/Audio/AudioFileProperties.java b/src/main/java/Audio/AudioFileProperties.java
index 3f41831..156a6e4 100644
--- a/src/main/java/Audio/AudioFileProperties.java
+++ b/src/main/java/Audio/AudioFileProperties.java
@@ -1,14 +1,33 @@
package Audio;
-public class AudioFileProperties {
- public final int handle;
- public final String filename;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class AudioFileProperties extends Structure {
+ public int handle;
+ public String filename;
public long Length;
public double duration;
- public AudioFileProperties(int handle, String filename){
+
+ public AudioFileProperties(Pointer p){
+ super(p);
+ read();
+ }
+
+ public AudioFileProperties(int handle, String filename, long length, double duration){
this.handle = handle;
this.filename = filename;
+ this.Length = length;
+ this.duration = duration;
+ write();
+ }
+
+ protected List getFieldOrder() {
+ return Arrays.asList("handle", "filename", "Length", "duration");
}
}
diff --git a/src/main/java/Audio/AudioPlayer.java b/src/main/java/Audio/AudioPlayer.java
index 8056569..97b3375 100644
--- a/src/main/java/Audio/AudioPlayer.java
+++ b/src/main/java/Audio/AudioPlayer.java
@@ -193,9 +193,9 @@ public class AudioPlayer {
int handle = bass.BASS_StreamCreateFile(false, ff.getAbsolutePath(), 0, 0,0);
if (handle!=0){
Logger.info("Audio file {} opened successfully", ff.getName());
- AudioFileProperties prop = new AudioFileProperties(handle, ff.getName());
- prop.Length = bass.BASS_ChannelGetLength(handle, Bass.BASS_POS_BYTE);
- prop.duration = bass.BASS_ChannelBytes2Seconds(handle, prop.Length);
+ long Length = bass.BASS_ChannelGetLength(handle, Bass.BASS_POS_BYTE);
+ double duration = bass.BASS_ChannelBytes2Seconds(handle, Length);
+ AudioFileProperties prop = new AudioFileProperties(handle, ff.getName(), Length, duration);
return prop;
} else Logger.error("Failed to open audio file {}, Error Code {}", ff.getAbsolutePath(), bass.BASS_ErrorGetCode());
} else Logger.info("AudioPlayer not initialized");
@@ -217,8 +217,39 @@ public class AudioPlayer {
} else Logger.info("Audio file {} closed successfully", prop.filename);
} else Logger.info("AudioPlayer not initialized");
}
+
}
+ PlaybackEvent playbackEvent = null;
+
+ Bass.SYNCPROC endproc = (handle, channel, data, user)->{
+ if (user!=null){
+ AudioFileProperties ap = new AudioFileProperties(user);
+ if (playbackEvent!=null){
+ playbackEvent.onPlaybackFinished(ap);
+ } else Logger.warn("endproc playbackEvent is null");
+ } else Logger.warn("endproc user is null");
+
+ };
+
+ Bass.SYNCPROC freeproc = (handle, channel, data, user)->{
+ if (user!=null){
+ AudioFileProperties ap = new AudioFileProperties(user);
+ if (playbackEvent!=null){
+ playbackEvent.onPlaybackFinished(ap);
+ } else Logger.warn("freeproc playbackEvent is null");
+ } else Logger.warn("freeproc user is null");
+ };
+
+ Bass.SYNCPROC failproc = (handle, channel, data, user)->{
+ if (user!=null){
+ AudioFileProperties ap = new AudioFileProperties(user);
+ if (playbackEvent!=null){
+ playbackEvent.onPlaybackFailure(ap, "Device Failure");
+ } else Logger.warn("failproc playbackEvent is null");
+ } else Logger.warn("failproc user is null");
+ };
+
/**
* Play Audio File
* @param prop AudioFileProperties object to play
@@ -226,23 +257,23 @@ public class AudioPlayer {
* @param event PlaybackEvent object to handle playback event
*/
public void PlayAudioFile(AudioFileProperties prop, boolean looping, PlaybackEvent event){
+ this.playbackEvent = null;
if (inited){
if (prop!=null){
if (bass.BASS_ChannelStart(prop.handle)){
+ this.playbackEvent = event;
playbackhandle = prop.handle;
+// SyncProcValue spv = new SyncProcValue(prop);
+// spv.write();
bass.BASS_ChannelSetAttribute(prop.handle, Bass.BASS_ATTRIB_VOL, playbackvolume);
if (looping) bass.BASS_ChannelFlags(prop.handle, Bass.BASS_SAMPLE_LOOP, Bass.BASS_SAMPLE_LOOP);
if (event!=null) event.onPlaybackStart(prop);
- int devfailsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_DEV_FAIL,0, (handle, channel, data, user)->{
- if (event!=null) event.onPlaybackFailure(prop, "Device Failure");
- }, null);
+ int devfailsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_DEV_FAIL,0, failproc, prop.getPointer());
if (devfailsync==0) Logger.error("Failed to set Device Failure Sync, Error Code {}", bass.BASS_ErrorGetCode());
- int endsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_END, 0, (handle, channel, data, user)->{
- if (looping) {
- if (event!=null) event.onPlaybackLooped(prop);
- } else if (event!=null) event.onPlaybackFinished(prop);
- }, null);
+ int endsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_END , 0, endproc, prop.getPointer());
if (endsync==0) Logger.error("Failed to set End Sync, Error Code {}", bass.BASS_ErrorGetCode());
+ int freesync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_FREE , 0, freeproc, prop.getPointer());
+ if (freesync==0) Logger.error("Failed to set Free Sync, Error Code {}", bass.BASS_ErrorGetCode());
} else {
if (event!=null) event.onPlaybackFailure(prop, String.format("Failed to play audio file %s, Error Code %d", prop.filename, bass.BASS_ErrorGetCode()));
}
@@ -254,4 +285,23 @@ public class AudioPlayer {
}
}
+// static class SyncProcValue extends Structure{
+// public AudioFileProperties ap;
+// public SyncProcValue(AudioFileProperties ap){
+// this.ap = ap;
+// }
+//
+// public SyncProcValue(Pointer p){
+// super(p);
+// read();
+// }
+//
+// @Override
+// protected List getFieldOrder() {
+// return Arrays.asList("ap");
+// }
+//
+//
+// }
+
}
diff --git a/src/main/java/Audio/Bass.java b/src/main/java/Audio/Bass.java
index 59c4862..af58651 100644
--- a/src/main/java/Audio/Bass.java
+++ b/src/main/java/Audio/Bass.java
@@ -2,6 +2,8 @@ package Audio;
import com.sun.jna.*;
+import java.util.Objects;
+
@SuppressWarnings("unused")
public interface Bass extends Library {
diff --git a/src/main/java/Audio/MultiUSBAudioPlayer.java b/src/main/java/Audio/MultiUSBAudioPlayer.java
new file mode 100644
index 0000000..a9b1107
--- /dev/null
+++ b/src/main/java/Audio/MultiUSBAudioPlayer.java
@@ -0,0 +1,323 @@
+package Audio;
+
+import lombok.Getter;
+import org.tinylog.Logger;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MultiUSBAudioPlayer {
+ private final Bass bass;
+ private int[] deviceid;
+ @Getter
+ private boolean inited = false;
+
+ PlaybackHandlewithId[] playbackhandle;
+ float playbackvolume = 1.0f;
+ List playbackdevices = new ArrayList<>();
+
+ /**
+ * Create Multi USB Audio Player
+ */
+ public MultiUSBAudioPlayer() {
+ bass = Bass.Instance;
+ Logger.info("Bass Version = {}", Integer.toHexString(bass.BASS_GetVersion()));
+ }
+
+ /**
+ * Unload Multi USB Audio Player
+ */
+ public void Unload(){
+ if (inited){
+ if (deviceid!=null && deviceid.length>0){
+ for(int id: deviceid){
+ Logger.info("Freeing Device {}", id);
+ bass.BASS_SetDevice(id);
+ bass.BASS_Free();
+ }
+ }
+
+ }
+ deviceid = null;
+ inited = false;
+ }
+
+ /**
+ * Detect Output Devices
+ */
+ public void DetectOutputDevices(){
+ Logger.info("Detecting Output Devices...");
+ int ii = 1;
+ playbackdevices.clear();
+ while (true){
+ Bass.BASS_DEVICEINFO info = new Bass.BASS_DEVICEINFO();
+ if (bass.BASS_GetDeviceInfo(ii, info)){
+ //Logger.info("Device {} = {}, flags = {}", ii, info.name, Integer.toHexString(info.flags));
+ playbackdevices.add(new BassDeviceInfoWithId(ii, info));
+ ii++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Find playback devices with name
+ * @param name specific name
+ * @return array of device id
+ */
+ public int[] FindDeviceIDWithName(String name){
+ if (playbackdevices!=null && !playbackdevices.isEmpty()){
+ List result = new ArrayList<>();
+ for(BassDeviceInfoWithId dev : playbackdevices){
+ if (dev.info.name.toLowerCase().contains(name.toLowerCase())){
+ result.add(dev.id);
+ }
+ }
+ return result.stream().mapToInt(i->i).toArray();
+ }
+ return new int[0];
+ }
+
+ /**
+ * Open Devices
+ * @param device list of device id
+ * @param freq frequency
+ * @return true if any device is successfully initialized
+ */
+ public boolean OpenDevice(int[] device, int freq){
+ if (device!=null && device.length>0){
+ int flag = Bass.BASS_DEVICE_REINIT | Bass.BASS_DEVICE_16BITS | Bass.BASS_DEVICE_MONO | Bass.BASS_DEVICE_FREQ;
+
+ List validdevice = new ArrayList<>();
+ for(int i : device){
+ boolean result = bass.BASS_Init(i, freq, flag);
+ if (result){
+ Logger.info("Device {} initialized", i);
+ validdevice.add(i);
+ inited = true;
+ } else {
+ Logger.error("Failed to initialize device {}", i);
+ }
+ }
+ deviceid = validdevice.stream().mapToInt(i->i).toArray();
+ return inited;
+ }
+ return false;
+ }
+
+ /**
+ * Set Master Output Volume
+ * Master Output Volume related to the system volume (Alsamixer on Linux, Volume Mixer on Windows)
+ * @param value volume value, 0-100
+ */
+ public void setMasterVolume(int value){
+ if (value<0) value = 0;
+ if (value>100) value = 100;
+ if (inited){
+ if (deviceid!=null && deviceid.length>0){
+ for(int id : deviceid){
+ bass.BASS_SetDevice(id);
+ if (!bass.BASS_SetVolume(value/100.0f)){
+ Logger.error("Failed to set Master Volume to {}, Error Code {}", value, bass.BASS_ErrorGetCode());
+ } else Logger.info("Master Volume set to {}", value);
+ }
+ } else Logger.error("No device initialized");
+ } else Logger.info("MultiUSBAudioPlayer not initialized");
+ }
+
+ /**
+ * Get Playback Volume
+ * is the volume of the currently playing audio file
+ * @return 0 - 100
+ */
+ public int getPlaybackvolume(){
+ if (playbackvolume<0)
+ return 0;
+ else if (playbackvolume>1.0f)
+ return 100;
+ else
+ return (int)(playbackvolume*100);
+ }
+
+ /**
+ * Set Playback Volume
+ * is the volume of the currently playing audio file
+ * @param value 0 - 100
+ */
+ public void setPlaybackvolume(int value){
+ if (value<0) value = 0;
+ if (value>100) value = 100;
+ playbackvolume = value/100.0f;
+ if (playbackhandle!=null && playbackhandle.length>0){
+ for(PlaybackHandlewithId ph : playbackhandle){
+ if (ph.handle.handle!=0){
+ bass.BASS_SetDevice(ph.id);
+ bass.BASS_ChannelSetAttribute(ph.handle.handle, Bass.BASS_ATTRIB_VOL, playbackvolume);
+ }
+ }
+ }
+ }
+
+ private float lastplaybackvolume = 1.0f;
+
+ /**
+ * Set Playback Volume to 0
+ */
+ public void Mute(){
+ lastplaybackvolume = playbackvolume;
+ setPlaybackvolume(0);
+ }
+
+ /**
+ * Set Playback Volume to last volume before Mute
+ */
+ public void Unmute(){
+ setPlaybackvolume((int)lastplaybackvolume*100);
+ }
+
+ /**
+ * Open Audio File
+ * @param ff audio file name to open
+ * @return AudioFileProperties object or null if failed
+ */
+ public PlaybackHandlewithId[] OpenAudioFile(File ff){
+ if (inited){
+ AudioFileProperties prop;
+ List phs = new ArrayList<>();
+ for(int id: deviceid){
+ bass.BASS_SetDevice(id);
+ int handle = bass.BASS_StreamCreateFile(false, ff.getAbsolutePath(), 0, 0,0);
+ if (handle!=0){
+ long Length = bass.BASS_ChannelGetLength(handle, Bass.BASS_POS_BYTE);
+ double duration = bass.BASS_ChannelBytes2Seconds(handle, Length);
+ prop = new AudioFileProperties(handle, ff.getName(), Length, duration);
+ PlaybackHandlewithId ph = new PlaybackHandlewithId(id, prop);
+ phs.add(ph);
+ }
+ }
+ if (!phs.isEmpty()){
+ playbackhandle = phs.toArray(new PlaybackHandlewithId[0]);
+ Logger.info("Audio file {} opened successfully", ff.getName());
+ return playbackhandle;
+ } else {
+ Logger.error("Failed to open audio file {}, Error Code {}", ff.getName(), bass.BASS_ErrorGetCode());
+ }
+ } else Logger.info("AudioPlayer not initialized");
+ return new PlaybackHandlewithId[0];
+ }
+
+ /**
+ * Close Audio File
+ * @param prop AudioFileProperties object to close
+ */
+ public void CloseAudioFile(PlaybackHandlewithId[] prop) {
+ if (inited) {
+ if (prop != null && prop.length>0) {
+ for(PlaybackHandlewithId ph : prop){
+ if (ph.handle.handle!=0){
+ bass.BASS_SetDevice(ph.id);
+ if (!bass.BASS_ChannelFree(ph.handle.handle)){
+ Logger.error("Failed to close audio file {}, Error Code {}", ph.handle.filename, bass.BASS_ErrorGetCode());
+ } else {
+ Logger.info("Audio file {} closed successfully", ph.handle.filename);
+ }
+ bass.BASS_Stop();
+
+ }
+ }
+ } else Logger.info("AudioPlayer not initialized");
+ }
+ }
+
+ PlaybackEvent playbackEvent = null;
+
+ Bass.SYNCPROC endproc = (handle, channel, data, user)->{
+ if (user!=null){
+ AudioFileProperties ap = new AudioFileProperties(user);
+ if (playbackEvent!=null){
+ playbackEvent.onPlaybackFinished(ap);
+ } else Logger.warn("endproc playbackEvent is null");
+ } else Logger.warn("endproc user is null");
+
+ };
+
+ Bass.SYNCPROC freeproc = (handle, channel, data, user)->{
+ if (user!=null){
+ AudioFileProperties ap = new AudioFileProperties(user);
+ if (playbackEvent!=null){
+ playbackEvent.onPlaybackFinished(ap);
+ } else Logger.warn("freeproc playbackEvent is null");
+ } else Logger.warn("freeproc user is null");
+ };
+
+ Bass.SYNCPROC failproc = (handle, channel, data, user)->{
+ if (user!=null){
+ AudioFileProperties ap = new AudioFileProperties(user);
+ if (playbackEvent!=null){
+ playbackEvent.onPlaybackFailure(ap, "Device Failure");
+ } else Logger.warn("failproc playbackEvent is null");
+ } else Logger.warn("failproc user is null");
+ };
+
+
+ /**
+ * Play Audio File
+ * @param prop AudioFileProperties object to play
+ * @param looping set true to loop the audio file
+ * @param event PlaybackEvent object to handle playback event
+ */
+ public void PlayAudioFile(PlaybackHandlewithId[] prop, boolean looping, PlaybackEvent event){
+ if (inited){
+ if (prop!=null && prop.length>0){
+ this.playbackEvent = event;
+ for(PlaybackHandlewithId ph : prop){
+ if (ph.handle.handle!=0){
+ bass.BASS_SetDevice(ph.id);
+ bass.BASS_Start();
+ if (bass.BASS_ChannelStart(ph.handle.handle)) {
+
+ bass.BASS_ChannelSetAttribute(ph.handle.handle, Bass.BASS_ATTRIB_VOL, playbackvolume);
+ if (looping) bass.BASS_ChannelFlags(ph.handle.handle, Bass.BASS_SAMPLE_LOOP, Bass.BASS_SAMPLE_LOOP);
+ if (event != null) event.onPlaybackStart(ph.handle);
+ int devfailsync = bass.BASS_ChannelSetSync(ph.handle.handle, Bass.BASS_SYNC_DEV_FAIL, 0, failproc, ph.handle.getPointer());
+ if (devfailsync == 0) Logger.error("Failed to set Device Failure Sync, Error Code {}", bass.BASS_ErrorGetCode());
+ int endsync = bass.BASS_ChannelSetSync(ph.handle.handle, Bass.BASS_SYNC_END, 0, endproc, ph.handle.getPointer());
+ if (endsync == 0) Logger.error("Failed to set End Sync, Error Code {}", bass.BASS_ErrorGetCode());
+ int freesync = bass.BASS_ChannelSetSync(ph.handle.handle, Bass.BASS_SYNC_FREE, 0, freeproc, ph.handle.getPointer());
+ if (freesync == 0) Logger.error("Failed to set Free Sync, Error Code {}", bass.BASS_ErrorGetCode());
+ } else {
+ if (event != null){
+ event.onPlaybackFailure(ph.handle, String.format("Failed to play audio file %s, Error Code %d", ph.handle.filename, bass.BASS_ErrorGetCode()));
+ }
+ }
+ }
+
+ }
+ } else {
+ if (event!=null) event.onPlaybackFailure(null, "AudioFileProperties is null");
+ }
+ } else {
+ if (event!=null) event.onPlaybackFailure(null, "AudioPlayer not initialized");
+ }
+ }
+
+ public static class PlaybackHandlewithId{
+ public final int id;
+ public final AudioFileProperties handle;
+ public PlaybackHandlewithId(int id, AudioFileProperties handle){
+ this.id = id;
+ this.handle = handle;
+ }
+ }
+
+ static class BassDeviceInfoWithId{
+ public final int id;
+ public final Bass.BASS_DEVICEINFO info;
+ public BassDeviceInfoWithId(int id, Bass.BASS_DEVICEINFO info){
+ this.id = id;
+ this.info = info;
+ }
+ }
+}
diff --git a/src/main/java/Camera/GrabbingTask.java b/src/main/java/Camera/GrabbingTask.java
index 8f3a724..a0520e2 100644
--- a/src/main/java/Camera/GrabbingTask.java
+++ b/src/main/java/Camera/GrabbingTask.java
@@ -39,6 +39,7 @@ public class GrabbingTask implements Runnable {
// for FPS calculation
private int intendedFps = 10;
+ private final boolean useYolo;
private final YoloDetector yolo;
@SuppressWarnings("SameParameterValue")
@@ -89,11 +90,12 @@ public class GrabbingTask implements Runnable {
- public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber, int fps) {
+ public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber, int fps, boolean useYolo) {
this.isGrabbing = isGrabbing;
this.grabber = grabber;
if (fps>0) intendedFps = fps;
- yolo = new YoloDetector();
+ this.useYolo = useYolo;
+ if (useYolo) yolo = new YoloDetector(); else yolo = null;
}
@@ -116,37 +118,52 @@ public class GrabbingTask implements Runnable {
Frame resizedFrame = SomeCodes.CoreMatConverter.convert(resized);
updateLQFrame(resizedFrame);
updateLQBase64(SomeCodes.MatToBase64(resized));
- } else System.out.println("processFrame resized size is 0");
- DetectYolo(mat);
+
+ if (useYolo){
+ DetectYolo(resized);
+ }
+ } else Logger.error("processFrame resized size is 0");
resized.release();
- } else System.out.println("processFrame Mat size is 0");
+ } else Logger.error("processFrame Mat size is 0");
mat.release();
} catch (Exception e){
- Logger.error("Error processing frame: "+e.getMessage());
+ if (SomeCodes.ValidString(e.getMessage())) {
+ if (!e.getMessage().startsWith("unknown exception")) {
+ Logger.error("Error processing frame: "+e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
}
} else {
- System.out.println("processFrame have null frame");
+ Logger.warn("processFrame have null frame");
updateMessage("processFrame have null frame");
}
}
private void DetectYolo(Mat mat){
- if (mat!=null && mat.cols()>0 && mat.rows()>0){
- //System.out.println("DetectYolo mat cols = "+mat.cols()+", rows = "+mat.rows());
- try{
- Mat[] processed = yolo.Detect(mat);
- Mat yolomat = yolo.Process(mat, processed[0], processed[1]);
- Frame yoloFrame = SomeCodes.CoreMatConverter.convert(yolomat);
- updateYoloFrame(yoloFrame);
- updateYoloBase64(SomeCodes.MatToBase64(yolomat));
+ if (yolo!=null){
+ if (mat!=null && mat.cols()>0 && mat.rows()>0){
+ try {
+ // [0] = predict, [1] = mask
+ Mat[] processed = yolo.Detect(mat);
+ // gambar dalam bentuk Mat
+ Mat yolomat = yolo.Process(mat, processed[0], processed[1]);
+ // convert jadi frame
+ Frame yoloFrame = SomeCodes.MatToFrame(yolomat);
+ updateYoloFrame(yoloFrame);
+ updateYoloBase64(SomeCodes.MatToBase64(yolomat));
+
+ } catch (Exception e) {
+ Logger.error("error processing YOLO, Message : " + e.getMessage());
+ updateYoloFrame(null);
+ updateYoloBase64("");
+ }
+
+ } else Logger.error("DetectYolo mat is null");
+ }
- } catch (Exception e){
- System.out.println("error processing YOLO, Message : "+e.getMessage());
- updateYoloFrame(null);
- updateYoloBase64("");
- }
- } else System.out.println("DetectYolo mat is null");
}
@@ -173,11 +190,14 @@ public class GrabbingTask implements Runnable {
Thread.yield();
Frame frame = grabber.grab();
if (framecount0){
- Logger.info("CUDA enabled devices found: " + cudacount);
- opencv_core.printCudaDeviceInfo(0);
- } else {
- Logger.info("No CUDA enabled devices found");
- }
+ public RtspGrabber(String ip, String path, boolean useYolo) {
+ this.useYolo = useYolo;
+
this.rtspUrl = "rtsp://" + ip + path;
Logger.info("RtspGrabber created with url: " + rtspUrl);
}
@@ -146,7 +142,7 @@ public class RtspGrabber {
@NotNull
private GrabbingTask getGrabbingTask() {
- GrabbingTask tt = new GrabbingTask(isGrabbing, grabber,10);
+ GrabbingTask tt = new GrabbingTask(isGrabbing, grabber,10, useYolo);
tt.setOnMessageUpdate(Logger::info);
tt.setOnHQFrameUpdate(value -> {
if (value!=null){
diff --git a/src/main/java/Camera/YoloDetector.java b/src/main/java/Camera/YoloDetector.java
index 24ccba9..c17d6e7 100644
--- a/src/main/java/Camera/YoloDetector.java
+++ b/src/main/java/Camera/YoloDetector.java
@@ -7,6 +7,7 @@ import org.opencv.core.*;
import org.opencv.dnn.Dnn;
import org.opencv.dnn.Net;
import org.opencv.imgproc.Imgproc;
+import org.tinylog.Logger;
import java.io.BufferedReader;
@@ -26,18 +27,20 @@ public class YoloDetector {
// Non-maximum suppression threshold
private final float nms_threshold = 0.4f;
+
public YoloDetector() {
NetLoaded = false;
net = null;
classes = null;
- String onnxfile = SomeCodes.ExtractResource("/yolov8n.onnx", SomeCodes.currentDirectory);
+ String onnxfile = SomeCodes.ExtractResource("/yolo11n.onnx", SomeCodes.currentDirectory);
String namesfile = SomeCodes.ExtractResource("/coco.names", SomeCodes.currentDirectory);
if (SomeCodes.ValidFile(onnxfile)){
if (SomeCodes.ValidFile(namesfile)){
net = Dnn.readNetFromONNX(onnxfile);
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
+ //net.setPreferableBackend(Dnn.DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(Dnn.DNN_TARGET_CPU);
-
+ //net.setPreferableTarget(Dnn.DNN_TARGET_NPU);
classes = new ArrayList<>();
if (namesfile!=null){
@@ -47,72 +50,87 @@ public class YoloDetector {
classes.add(line);
}
} catch (Exception e){
- System.out.println("Error: reading names file");
+ Logger.error("reading names file, Exception : ",e.getMessage());
}
}
if (!net.empty()){
if (!classes.isEmpty()){
NetLoaded = true;
- } else System.out.println("Error: names file is empty");
- } else System.out.println("Error: net is empty");
- } else System.out.println("Error: names file not found");
- } else System.out.println("Error: onnx file not found");
+ } else Logger.error("names file is empty");
+ } else Logger.error("net is empty");
+ } else Logger.error("names file not found");
+ } else Logger.error("onnx file not found");
}
+ // Source : https://blog.csdn.net/taoli188/article/details/134720614
public Mat[] Detect(Mat frame){
- if (NetLoaded){
- Size inputSize = new Size(640, 640);
- Scalar mean = new Scalar(0, 0, 0, 0);
- float scaleFactor = 1.0f/255.0f;
- boolean swapRB = true;
- boolean crop = true;
+ try{
+ if (NetLoaded){
+ Size inputSize = new Size(640, 640);
+ Scalar mean = new Scalar(0, 0, 0, 0);
+ float scaleFactor = 1.0f/255.0f;
+ boolean swapRB = true;
+ boolean crop = false;
- Mat blob = Dnn.blobFromImage(frame, scaleFactor, inputSize, mean , swapRB, crop, CV_32F);
- //Mat blob = Dnn.blobFromImage(frame, scaleFactor, inputSize);
- net.setInput(blob);
+ Mat blob = Dnn.blobFromImage(frame, scaleFactor, inputSize, mean , swapRB, crop, CV_32F);
+ //Mat blob = Dnn.blobFromImage(frame, scaleFactor, inputSize);
+ net.setInput(blob);
- Mat predict = net.forward();
- Mat mask = predict.reshape(0,1).reshape(0, predict.size(1));
+ Mat predict = net.forward();
+ Mat mask = predict.reshape(0,1).reshape(0, predict.size(1));
- return new Mat[]{predict,mask};
- } else {
- System.out.println("Error: Net not loaded");
+ return new Mat[]{predict,mask};
+ } else {
+ Logger.error("Net not loaded");
+ return new Mat[0];
+ }
+ } catch (Exception e){
+ Logger.error("Error detecting: "+e.getMessage());
return new Mat[0];
}
+
}
public Mat Process(Mat frame, Mat predict, Mat mask){
- double width = frame.cols() / 640.0;
- double height = frame.rows() / 640.0;
- Rect2d[] rect2d = new Rect2d[mask.cols()];
- float[] scoref = new float[mask.cols()];
- int[] classid = new int[mask.cols()];
+ try{
+ double width = frame.cols() / 640.0;
+ double height = frame.rows() / 640.0;
+ Rect2d[] rect2d = new Rect2d[mask.cols()];
+ float[] scoref = new float[mask.cols()];
+ int[] classid = new int[mask.cols()];
- for(int i=0;i0 && port<65536;
}
@@ -124,46 +132,33 @@ public class SomeCodes {
}
}
- public static String MatToBase64(Mat mat){
- if (mat!=null){
- if (mat.cols()>0 && mat.rows()>0){
- byte[] mob = new byte[mat.cols()*mat.rows()*mat.channels()];
- opencv_imgcodecs.imencode(".jpg", mat, mob);
- return base64encoder.encodeToString(mob);
- }
- }
- return "";
- }
-
public static String MatToBase64(org.opencv.core.Mat mat){
if (mat!=null){
if (mat.cols()>0 && mat.rows()>0){
- MatOfByte mob = new MatOfByte();
- Imgcodecs.imencode(".jpg", mat, mob);
- String base64 = base64encoder.encodeToString(mob.toArray());
- mob.release();
- return base64;
+ try{
+ MatOfByte mob = new MatOfByte();
+ Imgcodecs.imencode(".jpg", mat, mob);
+ String base64 = base64encoder.encodeToString(mob.toArray());
+ mob.release();
+ return base64;
+ } catch (Exception e){
+ Logger.error("Error converting Mat to Base64: "+e.getMessage());
+ }
}
}
return "";
}
- // Function ini pakai opencv, bukan javacv, jadi perlu Loader.load(opencv_java.class) di awal
- // lebih optimal untuk konversi frame ke base64
- public static String FrameToBase64(Frame frame){
- if (frame!=null && frame.imageWidth>0 && frame.imageHeight>0){
- org.opencv.core.Mat converted = CoreMatConverter.convert(frame);
- if (converted!=null && converted.cols()>0 && converted.rows()>0){
- //System.out.println("FrameToBase64 use converted Mat, cols: "+converted.cols()+", rows: "+converted.rows());
- return MatToBase64(converted);
- }
- Mat xx = CoreMatConverter.convertToMat(frame);
- if (xx!=null && xx.cols()>0 && xx.rows()>0){
- //System.out.println("FrameToBase64 use xx Mat, cols: "+xx.cols()+", rows: "+xx.rows());
- return MatToBase64(xx);
+ public static Frame MatToFrame(org.opencv.core.Mat mat){
+ if (mat!=null && mat.cols()>0 && mat.rows()>0){
+ try{
+ return CoreMatConverter.convert(mat);
+ } catch (Exception e){
+ Logger.error("Error converting Mat to Frame: "+e.getMessage());
}
}
- return "";
+
+ return null;
}
diff --git a/src/main/java/SBC/JetsonOrinPins.java b/src/main/java/SBC/JetsonOrinPins.java
index 04af4ca..facb89a 100644
--- a/src/main/java/SBC/JetsonOrinPins.java
+++ b/src/main/java/SBC/JetsonOrinPins.java
@@ -1,31 +1,31 @@
package SBC;
/**
- * Source : ...
+ * Source : ...
*/
public enum JetsonOrinPins {
- Pin07(7,"MCLK05",106),
+ Pin07(7,"AUDIO_MCLK",144),
Pin11(11,"UART1_RTS",112),
- Pin12(12,"I2S2_CLK",50),
- Pin13(13,"GPIO32",108),
- Pin15(15,"GPIO27",85),
- Pin16(16,"GPIO8",9),
- Pin18(18,"GPIO35",43),
- Pin19(19,"SPI1_MOSI",135),
- Pin21(21,"SPI1_MISO",134),
- Pin22(22,"GPIO17",96),
- Pin23(23,"SPI1_SCK",133),
- Pin24(24,"SPI1_CS0",136),
- Pin25(25,"SPI1_CS1",137),
- Pin29(29,"CAN0_RX",1),
- Pin31(31,"CAN0_TX",0),
- Pin32(32,"GPIO9",8),
- Pin33(33,"CAN1_TX",2),
- Pin35(35,"I2S_FS",53),
+ Pin12(12,"I2S0_SCLK",50),
+ Pin13(13,"SPI1_SCK",122),
+ Pin15(15,"GPIO12",85),
+ Pin16(16,"SPI1_CS1",126),
+ Pin18(18,"SPI1_CS0",125),
+ Pin19(19,"SPI0_MOSI",135),
+ Pin21(21,"SPI0_MISO",134),
+ Pin22(22,"SPI1_MISO",123),
+ Pin23(23,"SPI0_SCK",133),
+ Pin24(24,"SPI0_CS0",136),
+ Pin25(26,"SPI0_CS1",137),
+ Pin29(29,"GPIO01",105),
+ Pin31(31,"GPIO11",106),
+ Pin32(32,"GPIO07",41),
+ Pin33(33,"GPIO13",43),
+ Pin35(35,"I2S0_FS",53),
Pin36(36,"UART1_CTS",113),
- Pin37(37,"CAN1_RX",3),
- Pin38(38,"I2S_SDIN",52),
- Pin40(40,"I2S_SDOUT",51);
+ Pin37(37,"SPI1_MOSI",124),
+ Pin38(38,"I2S0_SDIN",52),
+ Pin40(40,"I2S0_SDOUT",51);
public final int pin;
public final String name;
public final int gpionumber;
diff --git a/src/main/java/SBC/LibGpioD.java b/src/main/java/SBC/LibGpioD.java
new file mode 100644
index 0000000..f9184c2
--- /dev/null
+++ b/src/main/java/SBC/LibGpioD.java
@@ -0,0 +1,20 @@
+package SBC;
+
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+
+public interface LibGpioD extends Library {
+ String CHIP_NAME = "/dev/gpiochip0"; // First GPIO chip
+ LibGpioD Instance = Native.load("gpiod", LibGpioD.class);
+
+ Pointer gpiod_chip_open(String chipname);
+ void gpiod_chip_close(Pointer chip);
+
+ Pointer gpiod_line_get(Pointer chip, int offset);
+ int gpiod_line_request_output(Pointer line, String consumer, int default_val);
+ int gpiod_line_request_input(Pointer line, String consumer);
+ int gpiod_line_set_value(Pointer line, int value);
+ int gpiod_line_get_value(Pointer line);
+ void gpiod_line_release(Pointer line);
+}
diff --git a/src/main/java/SBC/PCF8574.java b/src/main/java/SBC/PCF8574.java
index 9d991c9..9ef8665 100644
--- a/src/main/java/SBC/PCF8574.java
+++ b/src/main/java/SBC/PCF8574.java
@@ -2,10 +2,11 @@ package SBC;
import lombok.Getter;
+
@SuppressWarnings("unused")
public class PCF8574 extends I2C_Device{
- private byte data = 0x00;
+ private Byte data = 0;
private final @Getter String[] pinNames = new String[8];
/**
@@ -92,8 +93,10 @@ public class PCF8574 extends I2C_Device{
public boolean SetPin(int pin){
if (pin<0 || pin>7) return false;
if (super.isOpened()){
- byte temp = (byte) (data | (1<0;
+ synchronized (data){
+ data = (byte) (data | (1<0;
+ }
}
return false;
}
@@ -120,8 +123,10 @@ public class PCF8574 extends I2C_Device{
public boolean ClearPin(int pin){
if (pin<0 || pin>7) return false;
if (super.isOpened()){
- byte temp = (byte) (data & ~(1<0;
+ synchronized (data){
+ data = (byte) (data & ~(1<0;
+ }
}
return false;
}
diff --git a/src/main/java/SBC/SystemInformation.java b/src/main/java/SBC/SystemInformation.java
index d5d045f..ed05346 100644
--- a/src/main/java/SBC/SystemInformation.java
+++ b/src/main/java/SBC/SystemInformation.java
@@ -32,7 +32,7 @@ public class SystemInformation {
File ff = new File("/proc/net/dev");
if (ff.isFile() && ff.canRead()){
List result = new ArrayList<>();
- final Pattern pattern = Pattern.compile("\\s+(.*):\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
+ final Pattern pattern = Pattern.compile("\\s*(.*):\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
try{
String[] lines = Files.readString(ff.toPath()).split("\n");
for (String line : lines){
diff --git a/src/main/java/id/co/gtc/Main.java b/src/main/java/id/co/gtc/Main.java
index ce72913..277c6c7 100644
--- a/src/main/java/id/co/gtc/Main.java
+++ b/src/main/java/id/co/gtc/Main.java
@@ -1,9 +1,6 @@
package id.co.gtc;
-import Audio.AudioFileProperties;
-import Audio.AudioPlayer;
-import Audio.Bass;
-import Audio.PlaybackEvent;
+import Audio.*;
import Camera.PanTiltController;
import Camera.RtspGrabber;
import Camera.VapixProtocol;
@@ -12,6 +9,7 @@ import SBC.*;
import Web.*;
import com.google.gson.JsonObject;
import com.sun.jna.Platform;
+import com.sun.jna.Pointer;
import org.bytedeco.opencv.global.opencv_core;
import org.tinylog.Logger;
@@ -24,11 +22,20 @@ import java.util.concurrent.Executors;
import static Other.SomeCodes.*;
public class Main {
+ //change parameter ini untuk single audio output atau multi audio output
+ private static final boolean use_multiusb_audio = true;
+ private static MultiUSBAudioPlayer multiUSBAudioPlayer;
+ private static MultiUSBAudioPlayer.PlaybackHandlewithId[] playbackHandles;
private static AudioPlayer audioPlayer;
- private static WebServer webServer;
- private static RtspGrabber rtspGrabber;
- private static PanTiltController panTiltController;
private static AudioFileProperties audioFileProperties;
+
+ private static WebServer webServer;
+
+ //change parameter ini untuk menggunakan Yolo atau tidak
+ private static final boolean use_Yolo = true;
+ private static RtspGrabber rtspGrabber;
+
+ private static PanTiltController panTiltController;
private static VapixProtocol vapixProtocol;
private static Timer timer;
private static int cpuTemperature;
@@ -52,7 +59,11 @@ public class Main {
public static void main(String[] args) {
System.setProperty("jna.debug_load", "false");
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
- if (audioPlayer!=null) audioPlayer.Unload();
+ if (use_multiusb_audio) {
+ if (multiUSBAudioPlayer != null) multiUSBAudioPlayer.Unload();
+ } else {
+ if (audioPlayer != null) audioPlayer.Unload();
+ }
if (webServer!=null) webServer.Stop();
if (rtspGrabber!=null) rtspGrabber.Stop();
if (panTiltController!=null) panTiltController.Close();
@@ -77,10 +88,11 @@ public class Main {
if (pcf8574!=null){
pcf8574.Close();
}
+ Logger.info("Application Stopped");
}));
- System.out.println("Current Directory : "+currentDirectory);
+ Logger.info("Current Directory : "+currentDirectory);
//init_gpio();
@@ -91,7 +103,13 @@ public class Main {
init_audiofiles();
init_Vapix();
- init_audio();
+ if (use_multiusb_audio) {
+ Logger.info("Using MultiUSB Audio");
+ init_multiusb_audio();
+ } else {
+ Logger.info("Using USB Audio");
+ init_audio();
+ }
init_pantiltcontroller();
init_webserver();
@@ -105,28 +123,76 @@ public class Main {
Logger.info("I2C Bus opened");
pcf8574 = new PCF8574(i2c_bus.getI2c_handle(), 0x27);
if (pcf8574.Open_Slave()){
- System.out.println("PCF8574 opened");
+ Logger.info("PCF8574 opened");
pcf8574.AllOff();
- pcf8574.setPinName(0, "Amplifier Power");
- pcf8574.setPinName(1, "Led Web");
- pcf8574.setPinName(2, "Led IP Camera");
- pcf8574.setPinName(3, "Led Pan Tilt");
- pcf8574.setPinName(4, "Max485 Direction");
+// pcf8574.setPinName(0, "Amplifier Power");
+// pcf8574.setPinName(1, "Led Web");
+// pcf8574.setPinName(2, "Led IP Camera");
+// pcf8574.setPinName(3, "Led Pan Tilt");
+// pcf8574.setPinName(4, "Max485 Direction");
gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
} else {
- System.out.println("Failed to open PCF8574");
+ Logger.error("Failed to open PCF8574");
}
} else {
- System.out.println("Failed to open I2C Bus");
+ Logger.error("Failed to open I2C Bus");
}
- } else System.out.println("PCF8574 not supported on this platform");
+ } else Logger.error("PCF8574 not supported on this platform");
}
- @Deprecated
+ // Untuk test libgpiod
+ // use for jetpack 6.x
@SuppressWarnings("unused")
private static void init_gpio(){
+ LibGpioD gpio;
+ Pointer openPointer;
+ // Source : https://jetsonhacks.com/nvidia-jetson-orin-nano-gpio-header-pinout/
+ int gpio_MOSI = 135;
+ int gpio_MISO = 134;
+ if (Platform.isLinux()){
+ gpio = LibGpioD.Instance;
+ openPointer = gpio.gpiod_chip_open(LibGpioD.CHIP_NAME);
+ if (openPointer!=null){
+ Logger.info("GPIO Chip opened : {}", LibGpioD.CHIP_NAME);
+ Pointer miso = gpio.gpiod_line_get(openPointer, gpio_MISO);
+ if (miso!=null){
+ Logger.info("GPIO Line MISO opened : {}", gpio_MISO);
+ if (gpio.gpiod_line_request_input(miso, "MISO")!=0){
+ Logger.error("Failed to set MISO as input");
+ } else {
+ Logger.info("MISO opened");
+ Logger.info("MISO value : {}", gpio.gpiod_line_get_value(miso));
+ }
+ gpio.gpiod_line_release(miso);
+ Logger.info("GPIO Line MISO released : {}", gpio_MISO);
+ } else Logger.error("Failed to open GPIO Line : {}", gpio_MISO);
+ Pointer mosi = gpio.gpiod_line_get(openPointer, gpio_MOSI);
+ if (mosi!=null){
+ Logger.info("GPIO Line MOSI opened : {}", gpio_MOSI);
+ if (gpio.gpiod_line_request_output(mosi, "MOSI", 0)!=0){
+ Logger.error("Failed to set MOSI as output");
+ } else {
+ Logger.info("MOSI opened");
+ int result = gpio.gpiod_line_set_value(mosi, 1);
+ if (result!=0){
+ Logger.error("Failed to set MOSI value : {}", result);
+ } else Logger.info("Success set MOSI value : 1");
+ }
+ gpio.gpiod_line_release(mosi);
+ Logger.info("GPIO Line MOSI released : {}", gpio_MOSI);
+ } else Logger.error("Failed to open GPIO Line : {}", gpio_MOSI);
+ gpio.gpiod_chip_close(openPointer);
+ Logger.info("GPIO Chip closed : {}", LibGpioD.CHIP_NAME);
+ } else Logger.error("Failed to open GPIO Chip : {}", LibGpioD.CHIP_NAME);
+ } else Logger.info("GPIO not supported on this platform");
+ }
+
+
+ // use for jetpack 4.x and 5.x
+ @SuppressWarnings("unused")
+ private static void init_gpio_sysfs(){
if (Platform.isLinux()){
if (GPIO.HaveGPIO()){
gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
@@ -141,7 +207,7 @@ public class Main {
GPIO.SetValue(LedPanTilt,false);
GPIO.SetValue(Max485Direction,false);
}
- } else System.out.println("GPIO not supported on this platform");
+ } else Logger.info("GPIO not supported on this platform");
}
@@ -169,11 +235,11 @@ public class Main {
if (Max485Direction!=null){
GPIO.SetValue(Max485Direction, isTransmit);
} else if (pcf8574!=null && pcf8574.isOpened()){
- if (isTransmit){
- pcf8574.SetPin("Max485 Direction");
- } else {
- pcf8574.ClearPin("Max485 Direction");
- }
+// if (isTransmit){
+// pcf8574.SetPin("Max485 Direction");
+// } else {
+// pcf8574.ClearPin("Max485 Direction");
+// }
}
}
@@ -182,7 +248,7 @@ public class Main {
if (LedPanTilt!=null){
Blink(LedPanTilt);
} else if (pcf8574!=null && pcf8574.isOpened()){
- Blink("Led Pan Tilt");
+ Blink(1);
}
}
@@ -190,7 +256,7 @@ public class Main {
if (LedWeb!=null){
Blink(LedWeb);
} else if (pcf8574!=null && pcf8574.isOpened()){
- Blink("Led Web");
+ Blink(3);
}
}
@@ -198,38 +264,47 @@ public class Main {
if (LedIpCamera!=null){
Blink(LedIpCamera);
} else if (pcf8574!=null && pcf8574.isOpened()){
- Blink("Led IP Camera");
+ Blink(2);
}
}
private static void AmplifierControl(boolean isON){
if (AmplifierPower!=null){
+ Logger.info("GPIO Amplifier Power : ",isON);
GPIO.SetValue(AmplifierPower, isON);
} else if (pcf8574!=null && pcf8574.isOpened()){
if (isON){
- pcf8574.SetPin("Amplifier Power");
+ Logger.info("PCF8574 Amplifier Power ON");
+ pcf8574.SetPin(6);
+ pcf8574.SetPin(5);
+ pcf8574.SetPin(4);
} else {
- pcf8574.ClearPin("Amplifier Power");
+ Logger.info("PCF8574 Amplifier Power OFF");
+ pcf8574.ClearPin(6);
+ pcf8574.ClearPin(5);
+ pcf8574.ClearPin(4);
}
}
}
- private static void Blink(String pinName){
+ private static void Blink(int pin){
if (pcf8574!=null && pcf8574.isOpened()){
if (gpioExecutor!=null){
gpioExecutor.submit(()->{
- pcf8574.SetPin(pinName);
+ pcf8574.SetPin(pin);
try {
Thread.sleep(20);
} catch (InterruptedException ignored) {
}
- pcf8574.ClearPin(pinName);
+ pcf8574.ClearPin(pin);
});
}
}
}
+
+
private static void Blink(JetsonOrinPins pin){
if (pin!=null){
if (gpioExecutor!=null){
@@ -322,15 +397,15 @@ public class Main {
private static void init_Vapix(){
Properties config = SomeCodes.LoadProperties("config.properties");
- System.out.println("Saved Configuration for Camera");
+ Logger.info("Saved Configuration for Camera");
String ip = config.getProperty("Camera_ip");
String port = config.getProperty("Camera_port");
String username = config.getProperty("Camera_user");
String password = config.getProperty("Camera_password");
- System.out.println("Camera IP : "+ip);
- System.out.println("Camera Port : "+port);
- System.out.println("Camera Username : "+username);
- System.out.println("Camera Password : "+password);
+ Logger.info("Camera IP : "+ip);
+ Logger.info("Camera Port : "+port);
+ Logger.info("Camera Username : "+username);
+ Logger.info("Camera Password : "+password);
if (ValidString(ip)){
if (ValidPortNumber(port)){
@@ -356,27 +431,7 @@ public class Main {
} else Logger.error( "Camera IP is not valid string");
}
- private static void test_pantiltcontroller(){
- System.out.println("Pan Tilt Controller Test");
- panTiltController.PanLeft((byte)0x20);
- System.out.println("Pan Left");
- Sleep(2000);
- panTiltController.PanRight((byte)0x20);
- System.out.println("Pan Right");
- Sleep(2000);
- panTiltController.StopMovement();
- System.out.println("Stop Movement");
- panTiltController.TiltUp((byte)0x20);
- System.out.println("Tilt Up");
- Sleep(2000);
- panTiltController.TiltDown((byte)0x20);
- System.out.println("Tilt Down");
- Sleep(2000);
- panTiltController.StopMovement();
- System.out.println("Stop Movement");
- panTiltController.GoToPreset((byte)0);
- System.out.println("Go To Preset 0");
- }
+
private static void init_pantiltcontroller() {
Properties config = SomeCodes.LoadProperties("config.properties");
@@ -391,7 +446,7 @@ public class Main {
if (ValidInteger(baudrate)){
if (ValidInteger(PanTiltID)){
panTiltController = new PanTiltController(portname, Integer.parseInt(baudrate), Integer.parseInt(PanTiltID));
- if (panTiltController.isOpen()) test_pantiltcontroller();
+ //if (panTiltController.isOpen()) test_pantiltcontroller();
}
} else Logger.error("Invalid PTZ Baudrate");
} else Logger.error("Invalid PTZ Port");
@@ -402,21 +457,42 @@ public class Main {
// check if really activated
useOpenCL = opencv_core.useOpenCL();
Logger.info("OpenCL available={}, activated={}", haveOpenCL, useOpenCL);
+ int cudacount = opencv_core.getCudaEnabledDeviceCount();
+ if (cudacount>0){
+ Logger.info("CUDA enabled devices found: " + cudacount);
+ opencv_core.printCudaDeviceInfo(0);
+ } else {
+ Logger.info("No CUDA enabled devices found");
+ }
Properties config = SomeCodes.LoadProperties("config.properties");
String targetip = config.getProperty("Camera_ip");
String rtsppath = config.getProperty("Camera_Rtsp_path");
- System.out.println("Camera IP : "+targetip);
- System.out.println("Camera Rtsp Path : "+rtsppath);
+ Logger.info("Camera IP : "+targetip);
+ Logger.info("Camera Rtsp Path : "+rtsppath);
rtspGrabber = null;
if (ValidString(targetip)){
if (ValidString(rtsppath)){
if (IpIsReachable(targetip)){
Logger.info("Camera IP : "+targetip+" is reachable");
- rtspGrabber = new RtspGrabber(targetip, rtsppath);
+ rtspGrabber = new RtspGrabber(targetip, rtsppath, use_Yolo);
rtspGrabber.Start(true, 1920, 1080);
- } else System.out.println("Camera IP : "+targetip+" is not reachable");
- } else System.out.println("Camera Path : "+rtsppath+" is not valid string");
- } else System.out.println("Camera IP : "+targetip+" is not valid string");
+ } else Logger.warn("Camera IP : "+targetip+" is not reachable");
+ } else Logger.warn("Camera Path : "+rtsppath+" is not valid string");
+ } else Logger.warn("Camera IP : "+targetip+" is not valid string");
+ }
+
+ private static void init_multiusb_audio(){
+ multiUSBAudioPlayer = new MultiUSBAudioPlayer();
+ multiUSBAudioPlayer.DetectOutputDevices();
+ int[] devs = multiUSBAudioPlayer.FindDeviceIDWithName("USB");
+ if (devs!=null && devs.length>0){
+ Logger.info("MultiUSB Audio Device found : {}", IntArrayToString(devs));
+ if (multiUSBAudioPlayer.OpenDevice(devs, 48000)){
+ multiUSBAudioPlayer.setMasterVolume(100);
+ multiUSBAudioPlayer.setPlaybackvolume(100);
+ Logger.info("MultiUSB Audio Device ID={} opened", IntArrayToString(devs));
+ } else Logger.error("Failed to open MultiUSB Audio Device ID={}", IntArrayToString(devs));
+ } else Logger.error("MultiUSB Audio Device not found");
}
private static void init_audio() {
@@ -494,10 +570,18 @@ public class Main {
return new WebsocketReply("STOP MOVEMENT", "");
// Audio Related Commands
case "MUTE":
- if (audioPlayer!=null) audioPlayer.Mute();
+ if (use_multiusb_audio){
+ if (multiUSBAudioPlayer!=null) multiUSBAudioPlayer.Mute();
+ } else {
+ if (audioPlayer!=null) audioPlayer.Mute();
+ }
return new WebsocketReply("MUTE", "");
case "UNMUTE":
- if (audioPlayer!=null) audioPlayer.Unmute();
+ if (use_multiusb_audio){
+ if (multiUSBAudioPlayer!=null) multiUSBAudioPlayer.Unmute();
+ } else {
+ if (audioPlayer!=null) audioPlayer.Unmute();
+ }
return new WebsocketReply("UNMUTE", "");
case "SET VOLUME" :
int volume=-1;
@@ -507,11 +591,20 @@ public class Main {
if (volume>100) volume = 100;
}
if (volume>=0){
- if (audioPlayer!=null) audioPlayer.setPlaybackvolume(volume);
- return new WebsocketReply("SET VOLUME", String.valueOf(volume));
+ if (use_multiusb_audio){
+ if (multiUSBAudioPlayer!=null) multiUSBAudioPlayer.setPlaybackvolume(volume);
+ } else{
+ if (audioPlayer!=null) audioPlayer.setPlaybackvolume(volume);
+ }
+ return new WebsocketReply("SET VOLUME", String.valueOf(volume));
} else return new WebsocketReply("SET VOLUME", "Invalid Volume Value");
case "GET VOLUME" :
- int vol = audioPlayer!=null ? audioPlayer.getPlaybackvolume() : 0;
+ int vol = 0;
+ if (use_multiusb_audio){
+ if (multiUSBAudioPlayer!=null) vol = multiUSBAudioPlayer.getPlaybackvolume();
+ } else {
+ if (audioPlayer!=null) vol = audioPlayer.getPlaybackvolume();
+ }
return new WebsocketReply("GET VOLUME", String.valueOf(vol));
case "PLAY AUDIO" :
if (ValidInteger(command.data)){
@@ -520,25 +613,45 @@ public class Main {
if (ValidString(filename)){
File filetoplay = new File(Path.of(currentDirectory, "audiofiles", filename).toString());
if (filetoplay.isFile()){
- AudioFileProperties afp = audioPlayer.OpenAudioFile(filetoplay);
- if (afp!=null){
- audioFileProperties = afp;
- audioPlayer.PlayAudioFile(afp, true, pe);
- //AmplifierControl(true);
- return new WebsocketReply("PLAY AUDIO", afp.filename);
+ if (use_multiusb_audio){
+ MultiUSBAudioPlayer.PlaybackHandlewithId[] phs = multiUSBAudioPlayer.OpenAudioFile(filetoplay);
+ if (phs!=null && phs.length>0){
+ playbackHandles = phs;
+ multiUSBAudioPlayer.PlayAudioFile(phs, true, pe);
+ return new WebsocketReply("PLAY AUDIO", filename);
+ }
+ return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
+ } else {
+ AudioFileProperties afp = audioPlayer.OpenAudioFile(filetoplay);
+ if (afp!=null){
+ audioFileProperties = afp;
+ audioPlayer.PlayAudioFile(afp, true, pe);
+ //AmplifierControl(true);
+ return new WebsocketReply("PLAY AUDIO", afp.filename);
+ } else return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
+ }
- } else return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
} else return new WebsocketReply("PLAY AUDIO", "Audio file not found : "+filename);
} else return new WebsocketReply("PLAY AUDIO", String.format("AudioFile with ID %02d not found", id));
} else return new WebsocketReply("PLAY AUDIO", "Invalid Audio ID");
case "STOP AUDIO" :
- if (audioFileProperties!=null){
- audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
- String filename = audioFileProperties.filename;
- audioFileProperties = null;
- //AmplifierControl(false);
- return new WebsocketReply("STOP AUDIO", filename);
- } else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
+ if (use_multiusb_audio){
+ if (playbackHandles!=null && playbackHandles.length>0){
+ multiUSBAudioPlayer.CloseAudioFile(playbackHandles);
+ String filename = playbackHandles[0].handle.filename;
+ playbackHandles = null;
+ return new WebsocketReply("STOP AUDIO", filename);
+ } else return new WebsocketReply("STOP AUDIO", "No playbackHandles");
+ } else {
+ if (audioFileProperties!=null){
+ audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
+ String filename = audioFileProperties.filename;
+ audioFileProperties = null;
+ //AmplifierControl(false);
+ return new WebsocketReply("STOP AUDIO", filename);
+ } else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
+ }
+
// ZOOM Related Commands
case "GET MAX ZOOM":
if (vapixProtocol!=null){
@@ -551,29 +664,43 @@ public class Main {
return new WebsocketReply("GET ZOOM", String.valueOf(vapixProtocol.GetCurrentZoomValue()));
} else return new WebsocketReply("GET ZOOM", "VapixProtocol not initialized");
case "SET ZOOM":
- if (vapixProtocol.PTZEnabled()){
- if (ValidInteger(command.data)){
- int zoom = Integer.parseInt(command.data);
- if (zoomvapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
- if (vapixProtocol.Zoom(1, zoom)){
+ if (vapixProtocol!=null){
+ if (vapixProtocol.PTZEnabled()){
+ if (ValidInteger(command.data)){
+ int zoom = Integer.parseInt(command.data);
+ if (zoomvapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
Blink_LedIpCamera();
- return new WebsocketReply("ZOOM", String.valueOf(zoom));
- } else return new WebsocketReply("ZOOM", "Failed to zoom");
- } else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
- } else return new WebsocketReply("ZOOM", "Zoom not supported");
+ if (vapixProtocol.Zoom(1, zoom)){
+ return new WebsocketReply("ZOOM", String.valueOf(zoom));
+ } else return new WebsocketReply("ZOOM", "Failed to zoom");
+ } else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
+ } else return new WebsocketReply("ZOOM", "Zoom not supported");
+ }
+
// Live Streaming Related Commands
case "GET BASE64":
if (rtspGrabber!=null){
- return switch (command.data) {
- case "YOLO" ->
- new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
- case "LQ" ->
- new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
- case "HQ" ->
- new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastYoloBase64(), rtspGrabber.HQStreamingStatus());
- default -> new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
- };
+ if (use_Yolo){
+ return switch (command.data) {
+ case "HQ" ->
+ new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
+ case "LQ" ->
+ new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
+ case "YOLO" ->
+ new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastYoloBase64(), rtspGrabber.LQStreamingStatus());
+ default -> new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
+ };
+ } else {
+ return switch (command.data) {
+ case "HQ" ->
+ new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
+ case "LQ" ->
+ new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
+ default -> new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
+ };
+ }
+
} else return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
case "GET RESOLUTION":
if (vapixProtocol!=null){