mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2025-04-16 22:16:34 +00:00
Merge branch 'main' of https://github.com/PAMGuard/PAMGuard
This commit is contained in:
commit
7665c1257f
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.pamguard</groupId>
|
||||
<artifactId>Pamguard</artifactId>
|
||||
<version>2.02.16</version>
|
||||
<version>2.02.16a</version>
|
||||
<name>Pamguard</name>
|
||||
<description>Pamguard using Maven to control dependencies</description>
|
||||
<url>www.pamguard.org</url>
|
||||
|
@ -246,11 +246,11 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
private int nStarts;
|
||||
private RestartRunnable restartRunnable;
|
||||
private boolean batchFirst = true; // flag for starting batch offline tasks.
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of URLClassLoader, to handle loading of plugins
|
||||
*/
|
||||
// private static PluginClassloader classLoader;
|
||||
// private static PluginClassloader classLoader;
|
||||
|
||||
private PamController(int runMode, Object object) {
|
||||
|
||||
@ -285,7 +285,27 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
guiFrameManager = PamGUIManager.createGUI(this, object);
|
||||
guiFrameManager.init(); // perform any start up processes for the GUI.
|
||||
|
||||
installFolder = getInstallLocation();
|
||||
|
||||
setupPamguard();
|
||||
|
||||
setupGarbageCollector();
|
||||
|
||||
// if (PamGUIManager.getGUIType() == PamGUIManager.NOGUI) {
|
||||
// }
|
||||
|
||||
// diagnosticTimer = new Timer(1000, new DiagnosticTimer());
|
||||
// diagnosticTimer.start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the location of the install folder. Note that this will be system dependent.
|
||||
* @return the location of the install folder.
|
||||
*/
|
||||
private String getInstallLocation() {
|
||||
// figure out the installation folder
|
||||
String installFolder = null;
|
||||
try {
|
||||
File theURL = new File(
|
||||
this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
|
||||
@ -296,15 +316,18 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
installFolder = null;
|
||||
}
|
||||
|
||||
setupPamguard();
|
||||
//if a Mac AND we are inside the applications folder then
|
||||
if (System.getProperty("os.name").startsWith("Mac")) {
|
||||
String macAppFolder = new String("/Applications/PAMGuard.app/Contents");
|
||||
|
||||
if (installFolder.startsWith(macAppFolder)) {
|
||||
//PAMGuard is running form a .app bundle in the Applications directory on macOS
|
||||
installFolder = macAppFolder + File.separator;
|
||||
}
|
||||
//otherwise the install folder stays the same as we are using an IDE
|
||||
}
|
||||
|
||||
setupGarbageCollector();
|
||||
|
||||
// if (PamGUIManager.getGUIType() == PamGUIManager.NOGUI) {
|
||||
// }
|
||||
|
||||
// diagnosticTimer = new Timer(1000, new DiagnosticTimer());
|
||||
// diagnosticTimer.start();
|
||||
return installFolder;
|
||||
}
|
||||
|
||||
class DiagnosticTimer implements ActionListener {
|
||||
@ -549,9 +572,9 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
* to update existing settings That should probably be done here before the
|
||||
* final calls to setup processes, etc.
|
||||
*/
|
||||
// if (getRunMode() == RUN_PAMVIEW && PamSettingManager.remote_psf != null) {
|
||||
// loadOtherSettings(PamSettingManager.remote_psf);
|
||||
// }
|
||||
// if (getRunMode() == RUN_PAMVIEW && PamSettingManager.remote_psf != null) {
|
||||
// loadOtherSettings(PamSettingManager.remote_psf);
|
||||
// }
|
||||
|
||||
/*
|
||||
* Get any other required modules for this run mode.
|
||||
@ -731,9 +754,9 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
// }
|
||||
|
||||
void setupProcesses() {
|
||||
// for (int i = 0; i < pamControlledUnits.size(); i++) {
|
||||
// pamControlledUnits.get(i).setupControlledUnit();
|
||||
// }
|
||||
// for (int i = 0; i < pamControlledUnits.size(); i++) {
|
||||
// pamControlledUnits.get(i).setupControlledUnit();
|
||||
// }
|
||||
pamConfiguration.setupProcesses();
|
||||
}
|
||||
|
||||
@ -872,7 +895,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
System.err.println("Exception while loading " + moduleName);
|
||||
//this.removeControlledUnt(unitBeingLoaded);
|
||||
this.clearLoadedUnit();
|
||||
|
||||
|
||||
}
|
||||
if (unitBeingLoaded == null) {
|
||||
return null;
|
||||
@ -962,22 +985,22 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
return false;
|
||||
}
|
||||
|
||||
// private boolean reOrderModules(int[] newOrder) {
|
||||
//
|
||||
// if (pamControlledUnits.size() != newOrder.length) return false;
|
||||
//
|
||||
// ArrayList<PamControlledUnit> newList = new ArrayList<PamControlledUnit>();
|
||||
//
|
||||
// for (int i = 0; i < newOrder.length; i++) {
|
||||
//
|
||||
// newList.add(pamControlledUnits.get(newOrder[i]));
|
||||
//
|
||||
// }
|
||||
//
|
||||
// pamControlledUnits = newList;
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
// private boolean reOrderModules(int[] newOrder) {
|
||||
//
|
||||
// if (pamControlledUnits.size() != newOrder.length) return false;
|
||||
//
|
||||
// ArrayList<PamControlledUnit> newList = new ArrayList<PamControlledUnit>();
|
||||
//
|
||||
// for (int i = 0; i < newOrder.length; i++) {
|
||||
//
|
||||
// newList.add(pamControlledUnits.get(newOrder[i]));
|
||||
//
|
||||
// }
|
||||
//
|
||||
// pamControlledUnits = newList;
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Swaps the positions of two modules in the main list of modules and also swaps
|
||||
@ -1155,7 +1178,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
* later in the AWT event queue.
|
||||
*/
|
||||
public void startLater() {
|
||||
// SwingUtilities.invokeLater(new StartLater(true));
|
||||
// SwingUtilities.invokeLater(new StartLater(true));
|
||||
startLater(true);
|
||||
}
|
||||
|
||||
@ -1316,17 +1339,17 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
* off, etc.
|
||||
* This get's handled even if there is a worker thread.
|
||||
*/
|
||||
// String reprocessString = GlobalArguments.getParam(ReprocessStoreChoice.paramName);
|
||||
// ReprocessStoreChoice reprocesschoice = null;
|
||||
// if (reprocessString != null) {
|
||||
// try {
|
||||
// reprocesschoice = ReprocessStoreChoice.valueOf(reprocessString);
|
||||
// }
|
||||
// catch (Exception e) {
|
||||
// System.out.println("Invalid reprocess choice command: " + reprocessString);
|
||||
// }
|
||||
// }
|
||||
|
||||
// String reprocessString = GlobalArguments.getParam(ReprocessStoreChoice.paramName);
|
||||
// ReprocessStoreChoice reprocesschoice = null;
|
||||
// if (reprocessString != null) {
|
||||
// try {
|
||||
// reprocesschoice = ReprocessStoreChoice.valueOf(reprocessString);
|
||||
// }
|
||||
// catch (Exception e) {
|
||||
// System.out.println("Invalid reprocess choice command: " + reprocessString);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (saveSettings && getRunMode() == RUN_NORMAL) { // only true on a button press or network start.
|
||||
checkReprocessManager(saveSettings, startTime);
|
||||
}
|
||||
@ -1335,7 +1358,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the reprocess manager in a swing worker thread.
|
||||
* @param saveSettings
|
||||
@ -1344,17 +1367,17 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
private void checkReprocessManager(boolean saveSettings, long startTime) {
|
||||
ReprocessMon mon = new ReprocessMon(saveSettings, startTime);
|
||||
ReprocessManager reprocessManager = new ReprocessManager();
|
||||
// boolean goonthen = reprocessManager.checkOutputDataStatus();
|
||||
// if (!goonthen) {
|
||||
// System.out.println(
|
||||
// "Data processing will not start since you've chosen not to overwrite existing output data");
|
||||
// pamStop();
|
||||
// setPamStatus(PAM_IDLE);
|
||||
// return false;
|
||||
// }
|
||||
// boolean goonthen = reprocessManager.checkOutputDataStatus();
|
||||
// if (!goonthen) {
|
||||
// System.out.println(
|
||||
// "Data processing will not start since you've chosen not to overwrite existing output data");
|
||||
// pamStop();
|
||||
// setPamStatus(PAM_IDLE);
|
||||
// return false;
|
||||
// }
|
||||
reprocessManager.startCheckingThread(getMainFrame(), mon);
|
||||
}
|
||||
|
||||
|
||||
private class ReprocessMon implements ReprocessManagerMonitor {
|
||||
private boolean saveSettings;
|
||||
private long startTime;
|
||||
@ -1368,7 +1391,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
reprocessManagerDone(continueStart, continueStart, startTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void reprocessManagerDone(boolean goonthen, boolean saveSettings, long startTime) {
|
||||
if (!goonthen) {
|
||||
System.out.println(
|
||||
@ -1392,7 +1415,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
public boolean continueStart(boolean saveSettings, long startTime) {
|
||||
if (saveSettings) {
|
||||
startTime = PamCalendar.getSessionStartTime();
|
||||
// System.out.printf("Saving settings for start time %s\n", PamCalendar.formatDBDateTime(startTime));
|
||||
// System.out.printf("Saving settings for start time %s\n", PamCalendar.formatDBDateTime(startTime));
|
||||
saveSettings(PamCalendar.getSessionStartTime());
|
||||
}
|
||||
|
||||
@ -1464,10 +1487,10 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
|
||||
// start the status check timer, so that we know when all the threads have
|
||||
// actually stopped
|
||||
// statusCheckThread = new Thread(new StatusTimer());
|
||||
// statusCheckThread.start();
|
||||
// statusCheckThread = new Thread(new StatusTimer());
|
||||
// statusCheckThread.start();
|
||||
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
|
||||
|
||||
|
||||
long stopTime = PamCalendar.getTimeInMillis();
|
||||
|
||||
// tell all controlled units to stop
|
||||
@ -1561,13 +1584,13 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
private void finishStopping() {
|
||||
detectorEndThread = null;
|
||||
// this was never getting invoked for some reason.
|
||||
// SwingUtilities.invokeLater(new Runnable() {
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// SwingUtilities.invokeLater(new Runnable() {
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
pamStopped();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1579,7 +1602,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
* If it's running in multithreading mode, then at this point it is necessary to
|
||||
* make sure that all internal datablock buffers have had time to empty.
|
||||
*/
|
||||
// System.out.println("Arrived in PamStopped() in thread " + Thread.currentThread().toString());
|
||||
// System.out.println("Arrived in PamStopped() in thread " + Thread.currentThread().toString());
|
||||
|
||||
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
|
||||
|
||||
@ -1592,18 +1615,18 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
|
||||
// wait here until the status has changed to Pam_Idle, so that we know
|
||||
// that we've really finished processing all data
|
||||
// Debug.out.println("PamController waiting for all threaded observers to stop...");
|
||||
//
|
||||
// while (getPamStatus()!=PAM_IDLE) {
|
||||
// try {
|
||||
// Thread.sleep(10);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// Debug.out.println("PamController waiting for all threaded observers to stop...");
|
||||
//
|
||||
// while (getPamStatus()!=PAM_IDLE) {
|
||||
// try {
|
||||
// Thread.sleep(10);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
// send out the pamHasStopped message
|
||||
// Debug.out.println("PamController letting everyone know PAMGuard has stopped.");
|
||||
// Debug.out.println("PamController letting everyone know PAMGuard has stopped.");
|
||||
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
|
||||
pamControlledUnits.get(iU).pamHasStopped();
|
||||
}
|
||||
@ -1615,13 +1638,13 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
guiFrameManager.pamEnded();
|
||||
|
||||
// no good having this here since it get's called at the end of every file.
|
||||
// if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
|
||||
//// can exit here, since we've auto started, can auto exit.
|
||||
// if (canClose()) {
|
||||
// pamClose();
|
||||
// shutDownPamguard();
|
||||
// }
|
||||
// }
|
||||
// if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
|
||||
//// can exit here, since we've auto started, can auto exit.
|
||||
// if (canClose()) {
|
||||
// pamClose();
|
||||
// shutDownPamguard();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void batchProcessingComplete() {
|
||||
@ -1642,25 +1665,25 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
* @author mo55
|
||||
*
|
||||
*/
|
||||
// private class StatusTimer implements Runnable {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// boolean stillRunning = true;
|
||||
// while (stillRunning) {
|
||||
// try {
|
||||
// Thread.sleep(200);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// if (checkRunStatus() == true) {
|
||||
// setPamStatus(PAM_IDLE);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// System.out.println("Status timer completed, all processes have received last data");
|
||||
// }
|
||||
// }
|
||||
// private class StatusTimer implements Runnable {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// boolean stillRunning = true;
|
||||
// while (stillRunning) {
|
||||
// try {
|
||||
// Thread.sleep(200);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// if (checkRunStatus() == true) {
|
||||
// setPamStatus(PAM_IDLE);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// System.out.println("Status timer completed, all processes have received last data");
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Check the status of every threaded observer to see if it has emptied out it's
|
||||
@ -1670,39 +1693,39 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
* @return true if ANY process is still running
|
||||
*/
|
||||
private boolean checkRunStatus() {
|
||||
// boolean areWeFinished = true;
|
||||
// Debug.out.println("Checking run status...");
|
||||
// for (PamControlledUnit aUnit : pamControlledUnits) {
|
||||
// int numProcesses = aUnit.getNumPamProcesses();
|
||||
// for (int i=0; i<numProcesses; i++) {
|
||||
// PamProcess aProcess = aUnit.getPamProcess(i);
|
||||
// ArrayList<PamDataBlock> outputBlocks = aProcess.getOutputDataBlocks();
|
||||
// for (PamDataBlock aBlock : outputBlocks) {
|
||||
// int numObs = aBlock.countObservers();
|
||||
// for (int j=0; j<numObs; j++) {
|
||||
// PamObserver anObs = aBlock.getPamObserver(j);
|
||||
// if (ThreadedObserver.class.isAssignableFrom(anObs.getClass())) {
|
||||
// if (((ThreadedObserver) anObs).isEmptyRead() == false) {
|
||||
// Debug.out.println(" Thread " + anObs.getObserverName() + "-" + System.identityHashCode(anObs) +
|
||||
// " (" + Thread.currentThread().getName() +
|
||||
// "-" + Thread.currentThread().getId() +
|
||||
// ") is STILL processing");
|
||||
// areWeFinished = false;
|
||||
// break; // if we've found one still going, no need to check any further
|
||||
// }
|
||||
// else {
|
||||
// Debug.out.println(" Thread " + anObs.getObserverName() + "-" + System.identityHashCode(anObs) +
|
||||
// " (" + Thread.currentThread().getName() +
|
||||
// "-" + Thread.currentThread().getId() +
|
||||
// ") is finished processing");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Debug.out.println(" Are we finished? " + areWeFinished);
|
||||
// return areWeFinished;
|
||||
// boolean areWeFinished = true;
|
||||
// Debug.out.println("Checking run status...");
|
||||
// for (PamControlledUnit aUnit : pamControlledUnits) {
|
||||
// int numProcesses = aUnit.getNumPamProcesses();
|
||||
// for (int i=0; i<numProcesses; i++) {
|
||||
// PamProcess aProcess = aUnit.getPamProcess(i);
|
||||
// ArrayList<PamDataBlock> outputBlocks = aProcess.getOutputDataBlocks();
|
||||
// for (PamDataBlock aBlock : outputBlocks) {
|
||||
// int numObs = aBlock.countObservers();
|
||||
// for (int j=0; j<numObs; j++) {
|
||||
// PamObserver anObs = aBlock.getPamObserver(j);
|
||||
// if (ThreadedObserver.class.isAssignableFrom(anObs.getClass())) {
|
||||
// if (((ThreadedObserver) anObs).isEmptyRead() == false) {
|
||||
// Debug.out.println(" Thread " + anObs.getObserverName() + "-" + System.identityHashCode(anObs) +
|
||||
// " (" + Thread.currentThread().getName() +
|
||||
// "-" + Thread.currentThread().getId() +
|
||||
// ") is STILL processing");
|
||||
// areWeFinished = false;
|
||||
// break; // if we've found one still going, no need to check any further
|
||||
// }
|
||||
// else {
|
||||
// Debug.out.println(" Thread " + anObs.getObserverName() + "-" + System.identityHashCode(anObs) +
|
||||
// " (" + Thread.currentThread().getName() +
|
||||
// "-" + Thread.currentThread().getId() +
|
||||
// ") is finished processing");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Debug.out.println(" Are we finished? " + areWeFinished);
|
||||
// return areWeFinished;
|
||||
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
|
||||
|
||||
boolean running = false;
|
||||
@ -1715,7 +1738,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
sayStatusWarning("Waiting for " + aProcess.getProcessName());
|
||||
running = true;
|
||||
}
|
||||
// System.out.printf("Process %s is in state %d\n", aProcess.getProcessName(), lastNotification);
|
||||
// System.out.printf("Process %s is in state %d\n", aProcess.getProcessName(), lastNotification);
|
||||
}
|
||||
}
|
||||
return running;
|
||||
@ -1734,7 +1757,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
* via the database and binary storage modules.
|
||||
*/
|
||||
private void saveEndSettings(long timeNow) {
|
||||
// System.out.printf("Updating settings with end time %s\n", PamCalendar.formatDBDateTime(timeNow));
|
||||
// System.out.printf("Updating settings with end time %s\n", PamCalendar.formatDBDateTime(timeNow));
|
||||
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
|
||||
PamControlledUnit pcu;
|
||||
PamSettingsSource settingsSource;
|
||||
@ -1763,19 +1786,19 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
* @return path to the binary store.
|
||||
*/
|
||||
public String findBinaryStorePath() {
|
||||
// TODO get rid of the singleton binary store control and do from the Config.class
|
||||
// BinaryStore binaryControl = BinaryStore.findBinaryStoreControl();
|
||||
// if (binaryControl == null) {
|
||||
// return null;
|
||||
// }
|
||||
// String storeLoc = binaryControl.getBinaryStoreSettings().getStoreLocation();
|
||||
// if (storeLoc == null) {
|
||||
// return "";
|
||||
// }
|
||||
// if (storeLoc.endsWith(File.separator) == false) {
|
||||
// storeLoc += File.separator;
|
||||
// }
|
||||
// return storeLoc;
|
||||
// TODO get rid of the singleton binary store control and do from the Config.class
|
||||
// BinaryStore binaryControl = BinaryStore.findBinaryStoreControl();
|
||||
// if (binaryControl == null) {
|
||||
// return null;
|
||||
// }
|
||||
// String storeLoc = binaryControl.getBinaryStoreSettings().getStoreLocation();
|
||||
// if (storeLoc == null) {
|
||||
// return "";
|
||||
// }
|
||||
// if (storeLoc.endsWith(File.separator) == false) {
|
||||
// storeLoc += File.separator;
|
||||
// }
|
||||
// return storeLoc;
|
||||
return pamConfiguration.findBinaryStorePath();
|
||||
}
|
||||
|
||||
@ -1919,9 +1942,9 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// private ArrayList<PamDataBlock> makeDataBlockList(Class classType, boolean includSubClasses) {
|
||||
// return pamConfiguration.makeDataBlockList(classType, includSubClasses);
|
||||
// }
|
||||
// private ArrayList<PamDataBlock> makeDataBlockList(Class classType, boolean includSubClasses) {
|
||||
// return pamConfiguration.makeDataBlockList(classType, includSubClasses);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Find a block of a given type with the id number, or null if the number is out
|
||||
@ -2037,7 +2060,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
// System.out.printf("***** notify %d on thread %s is EventDispatch = %s\n", changeType, currentThread.getName(), isEvDT.toString());
|
||||
// }
|
||||
|
||||
// System.out.println("PamController: notify model changed: " +changeType );
|
||||
|
||||
if (changeType == CHANGED_MULTI_THREADING) {
|
||||
changedThreading();
|
||||
}
|
||||
@ -2239,7 +2262,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
|
||||
public void setPamStatus(int pamStatus) {
|
||||
this.pamStatus = pamStatus;
|
||||
// System.out.println("Set PAM Status: " + pamStatus);
|
||||
// System.out.println("Set PAM Status: " + pamStatus);
|
||||
/*
|
||||
* This only get's called once when set idle at viewer mode startup.
|
||||
*/
|
||||
@ -2342,7 +2365,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
statusWarning.setWarningMessage(warningMessage);
|
||||
statusWarning.setWarnignLevel(1);
|
||||
warningSystem.addWarning(statusWarning);
|
||||
// System.out.println(warningMessage);
|
||||
// System.out.println(warningMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2877,14 +2900,14 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
public void storageOptions(JFrame parentFrame) {
|
||||
StorageOptions.getInstance().showDialog(parentFrame);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show export options tp export data to other formats
|
||||
* @param parentFrame
|
||||
*/
|
||||
public void exportData(JFrame parentFrame) {
|
||||
ExportOptions.getInstance().showDialog(parentFrame);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2970,16 +2993,16 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
}
|
||||
}
|
||||
|
||||
// int pos = version.indexOf('.'); // get the index of the first decimal
|
||||
// if (pos==-1) { // if there is no decimal place (e.g. Java 13) then just use the full string
|
||||
// pos=version.length();
|
||||
// }
|
||||
// else {
|
||||
// pos = version.indexOf('.', pos+1); // get the position of the second decimal
|
||||
// if (pos==-1) { // if there is no second decimal place (e.g. Java 12.0) then just use the full string
|
||||
// pos=version.length();
|
||||
// }
|
||||
// }
|
||||
// int pos = version.indexOf('.'); // get the index of the first decimal
|
||||
// if (pos==-1) { // if there is no decimal place (e.g. Java 13) then just use the full string
|
||||
// pos=version.length();
|
||||
// }
|
||||
// else {
|
||||
// pos = version.indexOf('.', pos+1); // get the position of the second decimal
|
||||
// if (pos==-1) { // if there is no second decimal place (e.g. Java 12.0) then just use the full string
|
||||
// pos=version.length();
|
||||
// }
|
||||
// }
|
||||
double mainVersion = 0;
|
||||
try {
|
||||
mainVersion = Double.parseDouble(version.substring(0, iLen));
|
||||
|
@ -31,12 +31,12 @@ public class PamguardVersionInfo {
|
||||
* Version number, major version.minorversion.sub-release.
|
||||
* Note: can't go higher than sub-release 'f'
|
||||
*/
|
||||
static public final String version = "2.02.16";
|
||||
static public final String version = "2.02.16a";
|
||||
|
||||
/**
|
||||
* Release date
|
||||
*/
|
||||
static public final String date = "20 February 2025";
|
||||
static public final String date = "April 2025";
|
||||
|
||||
// /**
|
||||
// * Release type - Beta or Core
|
||||
|
@ -467,7 +467,7 @@ final public class PamModel implements PamSettings {
|
||||
mi.setToolTipText("Record observer monitoring effort");
|
||||
mi.setModulesMenuGroup(utilitiesGroup);
|
||||
// mi.setHidden(SMRUEnable.isEnable() == false);
|
||||
mi.setToolTipText("Enables an observer to enter their name and infomation about which displays are being monitored");
|
||||
mi.setToolTipText("Enables an observer to enter their name and information about which displays are being monitored");
|
||||
mi.setMaxNumber(1);
|
||||
|
||||
mi = PamModuleInfo.registerControlledUnit(BackupManager.class.getName(), BackupManager.defaultName);
|
||||
@ -708,7 +708,7 @@ final public class PamModel implements PamSettings {
|
||||
|
||||
mi = PamModuleInfo.registerControlledUnit("envelopeTracer.EnvelopeControl", "Envelope Tracing");
|
||||
mi.addDependency(new PamDependency(RawDataUnit.class, "Acquisition.AcquisitionControl"));
|
||||
mi.setToolTipText("");
|
||||
mi.setToolTipText("Traces the envelope of audio data and outputs it as a new waveform");
|
||||
mi.setModulesMenuGroup(processingGroup);
|
||||
mi.setModulesMenuGroup(processingGroup);
|
||||
mi.setHelpPoint("sound_processing/EnvelopeTrace/Docs/EnvelopeOverview.html");
|
||||
|
167
src/PamUtils/LittleEndianDataInputStream.java
Normal file
167
src/PamUtils/LittleEndianDataInputStream.java
Normal file
@ -0,0 +1,167 @@
|
||||
package PamUtils;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Copied from https://www.peterfranza.com/2008/09/26/little-endian-input-stream/
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class LittleEndianDataInputStream extends InputStream implements DataInput {
|
||||
|
||||
public LittleEndianDataInputStream(InputStream in) {
|
||||
this.in = in;
|
||||
this.d = new DataInputStream(in);
|
||||
w = new byte[8];
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
return d.available();
|
||||
}
|
||||
|
||||
|
||||
public final short readShort() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 2);
|
||||
return (short)(
|
||||
(w[1]&0xff) << 8 |
|
||||
(w[0]&0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Note, returns int even though it reads a short.
|
||||
*/
|
||||
public final int readUnsignedShort() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 2);
|
||||
return (
|
||||
(w[1]&0xff) << 8 |
|
||||
(w[0]&0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* like DataInputStream.readChar except little endian.
|
||||
*/
|
||||
public final char readChar() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 2);
|
||||
return (char) (
|
||||
(w[1]&0xff) << 8 |
|
||||
(w[0]&0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* like DataInputStream.readInt except little endian.
|
||||
*/
|
||||
public final int readInt() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 4);
|
||||
return
|
||||
(w[3]) << 24 |
|
||||
(w[2]&0xff) << 16 |
|
||||
(w[1]&0xff) << 8 |
|
||||
(w[0]&0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* like DataInputStream.readUnsignedInt except little endian.
|
||||
*/
|
||||
public final long readUnsignedInt() throws IOException
|
||||
{
|
||||
int v = readInt();
|
||||
return Integer.toUnsignedLong(v);
|
||||
// ByteArray.to
|
||||
// return
|
||||
// (w[3]) << 24 |
|
||||
// (w[2]&0xff) << 16 |
|
||||
// (w[1]&0xff) << 8 |
|
||||
// (w[0]&0xff);
|
||||
|
||||
}
|
||||
/**
|
||||
* like DataInputStream.readLong except little endian.
|
||||
*/
|
||||
public final long readLong() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 8);
|
||||
return
|
||||
(long)(w[7]) << 56 |
|
||||
(long)(w[6]&0xff) << 48 |
|
||||
(long)(w[5]&0xff) << 40 |
|
||||
(long)(w[4]&0xff) << 32 |
|
||||
(long)(w[3]&0xff) << 24 |
|
||||
(long)(w[2]&0xff) << 16 |
|
||||
(long)(w[1]&0xff) << 8 |
|
||||
(long)(w[0]&0xff);
|
||||
}
|
||||
|
||||
public final float readFloat() throws IOException {
|
||||
// still need to byteswap
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
public final double readDouble() throws IOException {
|
||||
// still need to byteswap
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
public final int read(byte b[], int off, int len) throws IOException {
|
||||
return in.read(b, off, len);
|
||||
}
|
||||
|
||||
public final void readFully(byte b[]) throws IOException {
|
||||
d.readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
public final void readFully(byte b[], int off, int len) throws IOException {
|
||||
d.readFully(b, off, len);
|
||||
}
|
||||
|
||||
public final int skipBytes(int n) throws IOException {
|
||||
return d.skipBytes(n);
|
||||
}
|
||||
|
||||
public final long skip(long n) throws IOException {
|
||||
return d.skipBytes((int) n);
|
||||
}
|
||||
|
||||
public final boolean readBoolean() throws IOException {
|
||||
return d.readBoolean();
|
||||
}
|
||||
|
||||
public final byte readByte() throws IOException {
|
||||
return d.readByte();
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
|
||||
public final int readUnsignedByte() throws IOException {
|
||||
return d.readUnsignedByte();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public final String readLine() throws IOException {
|
||||
return d.readLine();
|
||||
}
|
||||
|
||||
public final String readUTF() throws IOException {
|
||||
return d.readUTF();
|
||||
}
|
||||
|
||||
public final void close() throws IOException {
|
||||
d.close();
|
||||
}
|
||||
|
||||
private DataInputStream d; // to get at high level readFully methods of
|
||||
// DataInputStream
|
||||
private InputStream in; // to get at the low-level read methods of
|
||||
// InputStream
|
||||
private byte w[]; // work array for buffering input
|
||||
|
||||
}
|
@ -49,6 +49,7 @@ import javax.swing.border.EmptyBorder;
|
||||
|
||||
import PamController.PamController;
|
||||
import PamController.PamguardVersionInfo;
|
||||
import PamController.PamguardVersionInfo.ReleaseType;
|
||||
import PamUtils.PlatformInfo.OSType;
|
||||
import pamguard.Pamguard;
|
||||
|
||||
@ -163,11 +164,15 @@ public class Splash extends JWindow implements Runnable {
|
||||
else if (runMode == PamController.RUN_PAMVIEW) {
|
||||
modeText = "Viewer";
|
||||
}
|
||||
String typeText = " " + PamguardVersionInfo.getReleaseType().toString();
|
||||
if (PamguardVersionInfo.getReleaseType() == ReleaseType.CORE) {
|
||||
typeText = "";
|
||||
}
|
||||
if (modeText != null) {
|
||||
version = modeText + " " + PamguardVersionInfo.version + " " + PamguardVersionInfo.getReleaseType().toString();
|
||||
version = modeText + " " + PamguardVersionInfo.version + typeText;
|
||||
}
|
||||
else {
|
||||
version = "Version " + PamguardVersionInfo.version + " " + PamguardVersionInfo.getReleaseType().toString();
|
||||
version = "Version " + PamguardVersionInfo.version + typeText;
|
||||
}
|
||||
|
||||
// get image graphics handle.
|
||||
|
@ -641,15 +641,18 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
|
||||
|
||||
menuItem = new JMenuItem("Module Ordering ...");
|
||||
menuItem.addActionListener(new menuModuleOrder());
|
||||
menuItem.setToolTipText("Change the order of modules in the PAMGuard configuration");
|
||||
orderModulesEnabler.addMenuItem(menuItem);
|
||||
fileMenu.add(menuItem);
|
||||
|
||||
menuItem = new JMenuItem("Show Object List ...");
|
||||
menuItem.addActionListener(new menuShowObjectList());
|
||||
menuItem.setToolTipText("Show a list of data and detections currnetly held in memory for each module");
|
||||
fileMenu.add(menuItem);
|
||||
|
||||
menuItem = new JMenuItem("Show Data Model ...");
|
||||
menuItem.addActionListener(new menuShowObjectDiagram());
|
||||
menuItem.setToolTipText("Show a graphical representation of modules and their interconnections");
|
||||
fileMenu.add(menuItem);
|
||||
|
||||
if (!isViewer) {
|
||||
|
@ -620,6 +620,13 @@ abstract public class PamDialog extends JDialog {
|
||||
return showWarning(warningTitle, warningText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a warning text.
|
||||
* @param owner
|
||||
* @param warningTitle
|
||||
* @param warningText
|
||||
* @return
|
||||
*/
|
||||
public static boolean showWarning(Window owner, String warningTitle, String warningText) {
|
||||
JOptionPane.showMessageDialog(owner, warningText, warningTitle, JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package PamView.dialog;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Window;
|
||||
@ -16,20 +15,14 @@ import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import PamController.PamController;
|
||||
import PamDetection.LocalisationInfo;
|
||||
import PamUtils.PamUtils;
|
||||
import PamguardMVC.PamConstants;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import PamguardMVC.PamProcess;
|
||||
|
||||
/**
|
||||
* Standard panel for dialogs that shows a list of
|
||||
|
@ -143,7 +143,7 @@ public class ClickDetector extends PamProcess {
|
||||
|
||||
private PamDataBlock<TriggerLevelDataUnit> triggerDataBlock;
|
||||
|
||||
private PamRawDataBlock doubleFilteredData;
|
||||
// private PamRawDataBlock doubleFilteredData;
|
||||
|
||||
// protected PamDataBlock<ClickDetection> trackedClicks;
|
||||
private PamDataBlock trackedClicks;
|
||||
@ -730,12 +730,12 @@ public class ClickDetector extends PamProcess {
|
||||
// }
|
||||
|
||||
if ((newRawData.getChannelBitmap() & clickControl.clickParameters.getChannelBitmap()) == 0)
|
||||
return;
|
||||
return; // not a channel we're interested in
|
||||
//
|
||||
// if (obs == filteredDataBlock || obs == doubleFilteredData)
|
||||
// return;
|
||||
|
||||
clickControl.newRawData(obs, newData);
|
||||
clickControl.newRawData(obs, newData); // does nothing
|
||||
|
||||
// see if it's time to start a new file
|
||||
// only do this here if it's not multithread
|
||||
@ -1496,7 +1496,9 @@ public class ClickDetector extends PamProcess {
|
||||
int keepMillis = (int) (relSamplesToMilliseconds(requiredKeepSamples) * 2);
|
||||
// int keepSeconds = Math.max(1, (int)
|
||||
// relSamplesToMilliseconds(requiredKeepSamples)/1000);
|
||||
keepMillis = Math.max(1000, keepMillis);
|
||||
// add an extra second on 2025-04-01 to try to avoid null clicks.
|
||||
|
||||
keepMillis = Math.max(1000, keepMillis) + 1000;
|
||||
// filteredDataBlock.setNaturalLifetime(keepSeconds);
|
||||
finalDataSource = filteredDataBlock;
|
||||
finalDataSource.setNaturalLifetimeMillis(keepMillis);
|
||||
@ -1642,7 +1644,7 @@ public class ClickDetector extends PamProcess {
|
||||
/*
|
||||
* Waveform data ends up pointing either to the raw data, or the output of the
|
||||
* fist filter if there is one. new wavefformData is created every time (or
|
||||
* recycled from the data block) since we may beed to go back a while to find
|
||||
* recycled from the data block) since we may need to go back a while to find
|
||||
* data from a previous block
|
||||
*/
|
||||
double[][] waveformData = new double[nChannels][];
|
||||
|
@ -36,6 +36,11 @@ public abstract class GenericLinePlotInfo extends TDDataInfoFX {
|
||||
* TRhe managed symbol chooser.
|
||||
*/
|
||||
private TDSymbolChooserFX managedSymbolChooser;
|
||||
|
||||
/**
|
||||
* The radius if drawing a point instead of a line i.e. if there is only one data point.
|
||||
*/
|
||||
public static final double OVAL_RADIUS = 10;
|
||||
|
||||
/**
|
||||
* The last units
|
||||
@ -157,7 +162,9 @@ public abstract class GenericLinePlotInfo extends TDDataInfoFX {
|
||||
|
||||
if (lastUnits[chan][i]==null) {
|
||||
lastUnits[chan][i] = new TimePoint2D(tC, dataPixel, pamDataUnit.getTimeMilliseconds() );
|
||||
g.fillOval(tC, dataPixel, 10,10);
|
||||
|
||||
|
||||
g.fillOval(tC-OVAL_RADIUS/2, dataPixel-OVAL_RADIUS/2, OVAL_RADIUS,OVAL_RADIUS);
|
||||
// System.out.println("Fill oval:");
|
||||
return null;
|
||||
}
|
||||
|
@ -131,4 +131,11 @@ public class RavenControl extends PamControlledUnit implements PamSettings {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ravenParameters
|
||||
*/
|
||||
public RavenParameters getRavenParameters() {
|
||||
return ravenParameters;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ public class RavenParameters implements Serializable, Cloneable {
|
||||
|
||||
public String importFile;
|
||||
|
||||
public double timeOffsetSeconds = 0;
|
||||
|
||||
private ArrayList<RavenColumnInfo> extraColumns;
|
||||
|
||||
public ArrayList<RavenColumnInfo> getExtraColumns() {
|
||||
|
@ -95,7 +95,7 @@ public class RavenProcess extends PamProcess {
|
||||
* this as an option in future releases.
|
||||
* Offset of 2843100 needed for mn23_055a tag data.
|
||||
*/
|
||||
long offsetMillis = 0;//2843100;
|
||||
long offsetMillis = (long) (ravenControl.getRavenParameters().timeOffsetSeconds * 1000.);
|
||||
|
||||
RavenDataRow prevRow = null;
|
||||
for (RavenDataRow ravenRow : ravenData) {
|
||||
|
@ -10,6 +10,7 @@ import java.io.File;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.TitledBorder;
|
||||
@ -30,6 +31,7 @@ public class RavenImportDialog extends PamDialog {
|
||||
|
||||
private JButton chooseButton;
|
||||
|
||||
private JTextField timeOffset;
|
||||
|
||||
|
||||
private RavenImportDialog(Window parentFrame) {
|
||||
@ -40,10 +42,30 @@ public class RavenImportDialog extends PamDialog {
|
||||
ravenFile = new JTextField(80);
|
||||
ravenFile.setEditable(false);
|
||||
chooseButton = new JButton("Select ...");
|
||||
|
||||
c.gridwidth = 2;
|
||||
c.gridx = c.gridy = 0;
|
||||
mainPanel.add(ravenFile, c);
|
||||
|
||||
JPanel p2 = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints c2 = new PamGridBagContraints();
|
||||
c2.gridx = 1;
|
||||
c2.gridwidth = 1;
|
||||
p2.add(chooseButton, c2);
|
||||
|
||||
c2.gridx = 0;
|
||||
c2.gridy++;
|
||||
c2.gridwidth = 1;
|
||||
p2.add(new JLabel("Time offset (s) ", JLabel.RIGHT), c2);
|
||||
c2.gridx++;
|
||||
p2.add(timeOffset = new JTextField(7), c2);
|
||||
String tip = "Added to data as it's read from file";
|
||||
timeOffset.setToolTipText(tip);
|
||||
|
||||
c.gridwidth = 2;
|
||||
c.gridy++;
|
||||
mainPanel.add(new PamAlignmentPanel(chooseButton, BorderLayout.EAST), c);
|
||||
mainPanel.add(new PamAlignmentPanel(p2, BorderLayout.EAST), c);
|
||||
|
||||
|
||||
chooseButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@ -80,6 +102,7 @@ public class RavenImportDialog extends PamDialog {
|
||||
private void setParams(RavenParameters ravenParameters) {
|
||||
this.ravenParameters = ravenParameters;
|
||||
ravenFile.setText(ravenParameters.importFile);
|
||||
timeOffset.setText(String.format("%5.3f", ravenParameters.timeOffsetSeconds));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,6 +117,12 @@ public class RavenImportDialog extends PamDialog {
|
||||
return showWarning(str);
|
||||
}
|
||||
ravenParameters.importFile = fn;
|
||||
try {
|
||||
ravenParameters.timeOffsetSeconds = Double.valueOf(timeOffset.getText());
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return showWarning("Invalid time offset value. Must be a number");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,8 @@ public class DLPredictionPane extends PamBorderPane implements TDSettingsPane {
|
||||
predColHolder.setPadding(new Insets(5,0,0,0));
|
||||
|
||||
this.setParams();
|
||||
|
||||
mainPane.setPrefWidth(300);
|
||||
|
||||
// if (dlPredictionPlotInfoFX.getDlControl().getDLModel()!=null) {
|
||||
// layoutColourPanes( dlPredictionPlotInfoFX.getDlControl().getDLModel().getClassNames());
|
||||
|
@ -21,6 +21,10 @@ import us.hebi.matlab.mat.format.Mat5File;
|
||||
import us.hebi.matlab.mat.types.Matrix;
|
||||
import us.hebi.matlab.mat.types.Struct;
|
||||
|
||||
|
||||
/**
|
||||
* Model from Thomas webber which is a good way to test the click based stuff is working in PAMGUard.
|
||||
*/
|
||||
public class ClickDLTest {
|
||||
|
||||
|
||||
|
@ -6,6 +6,8 @@ import java.util.ArrayList;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
|
||||
import clickDetector.WindowsFile;
|
||||
import wavFiles.xwav.HarpHeader;
|
||||
import wavFiles.xwav.XWavException;
|
||||
|
||||
public class WavHeader {
|
||||
|
||||
@ -110,6 +112,18 @@ public class WavHeader {
|
||||
windowsWavFile.seek(fmtEnd);
|
||||
// break;
|
||||
}
|
||||
else if (testString.equals("harp")) {
|
||||
chunkSize = windowsWavFile.readWinInt();
|
||||
headChunk = new byte[chunkSize];
|
||||
windowsWavFile.read(headChunk);
|
||||
try {
|
||||
HarpHeader.readHarpHeader(headChunk);
|
||||
} catch (XWavException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// wavHeadChunks.add(new WavHeadChunk(testString, headChunk));
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* As an example, SCRIPPS HARP .x.wav files have a chunk
|
||||
|
112
src/wavFiles/xwav/HarpHeader.java
Normal file
112
src/wavFiles/xwav/HarpHeader.java
Normal file
@ -0,0 +1,112 @@
|
||||
package wavFiles.xwav;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
import PamUtils.LittleEndianDataInputStream;
|
||||
import PamUtils.PamCalendar;
|
||||
|
||||
public class HarpHeader {
|
||||
|
||||
private HarpHeader() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack harp data junk from a xwav file.
|
||||
* @param chunkData
|
||||
* @return
|
||||
*/
|
||||
public static HarpHeader readHarpHeader(byte[] chunkData) throws XWavException {
|
||||
/*
|
||||
* Based on matlab code found at https://github.com/MarineBioAcousticsRC/Wav2XWav/blob/main/wrxwavhdX.m
|
||||
*/
|
||||
LittleEndianDataInputStream dis = new LittleEndianDataInputStream(new ByteArrayInputStream(chunkData));
|
||||
// new LittleEnd
|
||||
try {
|
||||
int harpSize = chunkData.length;
|
||||
int xhdVersion = dis.readUnsignedByte();
|
||||
String firmwareVersion = readString(dis, 10);
|
||||
String insId = readString(dis, 4);
|
||||
String site = readString(dis, 4);
|
||||
String experiment = readString(dis, 8);// could be 8 in example
|
||||
int diskSequenceNumber = dis.readUnsignedByte();
|
||||
String diskSerialNumber = readString(dis, 8);
|
||||
int numRF = dis.readUnsignedShort();
|
||||
int longitude = dis.readInt(); // defo written as integers. guessing float*1e5.
|
||||
int latitude = dis.readInt();
|
||||
// float longitude = dis.readFloat();
|
||||
// float latitude = dis.readFloat();
|
||||
int depth = dis.readShort();
|
||||
// skip 8.
|
||||
dis.skip(8);
|
||||
/*
|
||||
* then read numRF chunks, each of which is 32 bytes. In this example, we
|
||||
* have harpSize = 29752, so expecting about (29752-50)/32
|
||||
*/
|
||||
long lastT = 0;
|
||||
for (int iRF = 0; iRF < numRF; iRF++) {
|
||||
// time is from datevec, so it's year, month ... second in the first six
|
||||
int[] dateVec = new int[7];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
dateVec[i] = dis.readUnsignedByte();
|
||||
}
|
||||
dateVec[6] = dis.readUnsignedShort(); // number of millis.
|
||||
long byteLoc = dis.readUnsignedInt();
|
||||
long byteLength = dis.readUnsignedInt();
|
||||
long writeLength = dis.readUnsignedInt();
|
||||
long sampleRate = dis.readUnsignedInt();
|
||||
int gain = dis.readUnsignedByte();
|
||||
dis.skip(7);
|
||||
long tMillis = dateVec2Millis(dateVec);
|
||||
// if (lastT != 0) {
|
||||
// System.out.printf("%s length %d = %3.3fs, step = %dms\n", PamCalendar.formatDBDateTime(tMillis, true), byteLength,
|
||||
// (double) byteLength / (double) sampleRate / 2., tMillis-lastT);
|
||||
// }
|
||||
// else {
|
||||
// System.out.printf("%s length %d = %3.3fs\n", PamCalendar.formatDBDateTime(tMillis, true), byteLength,
|
||||
// (double) byteLength / (double) sampleRate / 2.);
|
||||
// }
|
||||
lastT = tMillis;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new XWavException(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert datevec read from file to Java millis.
|
||||
* @param dateVec
|
||||
*/
|
||||
private static long dateVec2Millis(int[] dateVec) {
|
||||
// format is yy, mm, dd, hh, mm, ss, ms as int values.
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(PamCalendar.defaultTimeZone);
|
||||
c.clear();
|
||||
int yy = dateVec[0];
|
||||
if (yy < 90) {
|
||||
yy += 2000;
|
||||
}
|
||||
c.set(yy, dateVec[1]-1, dateVec[2], dateVec[3], dateVec[4], dateVec[5]);
|
||||
long millis = c.getTimeInMillis() + dateVec[6];
|
||||
return millis;
|
||||
}
|
||||
|
||||
private static String readString(LittleEndianDataInputStream dis, int bytes) throws XWavException {
|
||||
byte[] data;
|
||||
try {
|
||||
data = dis.readNBytes(bytes);
|
||||
String str = new String(data);
|
||||
return str;
|
||||
} catch (IOException e) {
|
||||
throw new XWavException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
34
src/wavFiles/xwav/XWavException.java
Normal file
34
src/wavFiles/xwav/XWavException.java
Normal file
@ -0,0 +1,34 @@
|
||||
package wavFiles.xwav;
|
||||
|
||||
public class XWavException extends Exception {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public XWavException() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public XWavException(String message) {
|
||||
super(message);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public XWavException(Throwable cause) {
|
||||
super(cause);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public XWavException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public XWavException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user