Updated X3 library to 2.2.6

This commit is contained in:
Douglas Gillespie 2023-11-15 13:08:02 +00:00
parent a4f484c76c
commit acc806d375
9 changed files with 258 additions and 68 deletions

View File

@ -8,6 +8,7 @@
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>

View File

@ -4,7 +4,7 @@
<groupId>org.pamguard</groupId>
<artifactId>Pamguard</artifactId>
<name>Pamguard Java12+</name>
<version>2.02.09b</version>
<version>2.02.09c</version>
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
<url>www.pamguard.org</url>
<organization>

View File

@ -786,7 +786,7 @@ C:\Users\*yourusername*\.m2\repository\pamguard\org\x3\2.2.2-->
<dependency>
<groupId>pamguard.org</groupId>
<artifactId>x3</artifactId>
<version>2.2.3</version>
<version>2.2.6</version>
</dependency>

View File

@ -0,0 +1,4 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Wed Nov 15 12:43:42 GMT 2023
x3-2.2.6.jar>=
x3-2.2.6.pom>=

Binary file not shown.

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>pamguard.org</groupId>
<artifactId>x3</artifactId>
<version>2.2.6</version>
<description>POM was created from install:install-file</description>
</project>

View File

@ -7,57 +7,214 @@ import java.util.Arrays;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.SwingUtilities;
import org.pamguard.x3.sud.ChunkHeader;
import org.pamguard.x3.sud.SudMapListener;
import PamController.PamController;
import PamUtils.worker.PamWorkProgressMessage;
import PamUtils.worker.PamWorkWrapper;
import PamUtils.worker.PamWorker;
/**
* Opens a .sud audio file.
* <p>
* Sud files contain X3 compressed audio data. The sud
* file reader opens files, creating a map of the file and saving
* the map as a.sudx file so it can be read more rapidly when the file
* is next accessed.
* Sud files contain X3 compressed audio data. The sud file reader opens files,
* creating a map of the file and saving the map as a.sudx file so it can be
* read more rapidly when the file is next accessed.
* <p>
* The SudioAudioInput stream fully implements AudioInputStream and so
* sud files can be accessed using much of the same code as .wav files.
*
* The SudioAudioInput stream fully implements AudioInputStream and so sud files
* can be accessed using much of the same code as .wav files.
*
* @author Jamie Macaulay
*
*/
public class SudAudioFile extends WavAudioFile {
private Object conditionSync = new Object();
private volatile PamWorker<AudioInputStream> worker;
private volatile SudMapWorker sudMapWorker;
public SudAudioFile() {
super();
fileExtensions = new ArrayList<String>(Arrays.asList(new String[]{".sud"}));
super();
fileExtensions = new ArrayList<String>(Arrays.asList(new String[] { ".sud" }));
}
@Override
public String getName() {
return "SUD";
}
@Override
public AudioInputStream getAudioStream(File soundFile) {
if (soundFile.exists() == false) {
System.err.println("The sud file does not exist: " + soundFile);
return null;
}
if (soundFile != null) {
try {
return new SudAudioFileReader().getAudioInputStream(soundFile);
}
// don't do anything and it will try the built in Audiosystem
catch (UnsupportedAudioFileException e) {
System.err.println("UnsupportedAudioFileException: Could not open sud file: not a supported file " + soundFile.getName());
System.err.println(e.getMessage());
// e.printStackTrace();
} catch (IOException e) {
System.err.println("Could not open sud file: IO Exception: " + soundFile.getName());
e.printStackTrace();
synchronized (conditionSync) {
// System.out.println("Get SUD getAudioStream : " + soundFile.getName());
if (soundFile.exists() == false) {
System.err.println("The sud file does not exist: " + soundFile);
return null;
}
if (soundFile != null) {
if (new File(soundFile.getAbsolutePath() + "x").exists()) {
// System.out.println("----NO NEED TO MAP SUD FILE-----" + soundFile);
try {
return new SudAudioFileReader().getAudioInputStream(soundFile);
} catch (UnsupportedAudioFileException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
// System.out.println("----MAP SUD FILE ON OTHER THREAD-----" + soundFile);
/**
* We need to map the sud file. But we don't want this o just freeze the current
* GUI thread. Therefore add a listener to the mapping process and show a
* blocking dialog to indicate that something is happening. The mapping is put
* on a separate thread and blocks stuff from happening until the mapping
* process has completed.
*/
if (sudMapWorker == null || !sudMapWorker.getSudFile().equals(soundFile)) {
sudMapWorker = new SudMapWorker(soundFile);
worker = new PamWorker<AudioInputStream>(sudMapWorker,
PamController.getInstance().getMainFrame(), 1,
"Mapping sud file: " + soundFile.getName());
// System.out.println("Sud Audio Stream STARTED: " + soundFile.getName());
SwingUtilities.invokeLater(() -> {
worker.start();
});
// this should block AWT thread but won't block if called on another thread..
}
// this is only ever called if this function is called on another thread other
// than the event dispatch thread.
while (sudMapWorker == null || !sudMapWorker.isDone()) {
// do nothing
// System.out.println("Waiting for the SUD file map: " + soundFile.getName() + " worker: " + worker);
try {
// Thread.sleep(100);
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
AudioInputStream stream = sudMapWorker.getSudAudioStream();
// sudMapWorker= null;
// worker = null;
// System.out.println("----RETURN SUD FILE ON OTHER THREAD-----" + stream);
return stream;
}
}
}
return null;
}
}
public class SudMapProgress implements SudMapListener {
PamWorker<AudioInputStream> sudMapWorker;
public SudMapProgress(PamWorker<AudioInputStream> sudMapWorker) {
this.sudMapWorker = sudMapWorker;
}
@Override
public void chunkProcessed(ChunkHeader chunkHeader, int count) {
// System.out.println("Sud Map Progress: " + count);
if (count % 500 == 0) {
// don't update too often or everything just freezes
sudMapWorker.update(new PamWorkProgressMessage(-1, ("Mapped " + count + " sud file chunks")));
}
if (count == -1) {
sudMapWorker.update(new PamWorkProgressMessage(-1, ("Mapping sud file finished")));
}
}
}
/**
* Opens an sud file on a different thread and adds a listener for a mapping.
* This allows a callback to show map progress.
*
* @author Jamie Macaulay
*
*/
public class SudMapWorker implements PamWorkWrapper<AudioInputStream> {
private File soundFile;
private SudMapProgress sudMapListener;
private volatile boolean done = false;
private AudioInputStream result;
public SudMapWorker(File soundFile) {
this.soundFile = soundFile;
}
public File getSudFile() {
return soundFile;
}
public AudioInputStream getSudAudioStream() {
return result;
}
@Override
public AudioInputStream runBackgroundTask(PamWorker<AudioInputStream> pamWorker) {
AudioInputStream stream;
try {
// System.out.println("START OPEN SUD FILE:");
this.sudMapListener = new SudMapProgress(pamWorker);
stream = new SudAudioFileReader().getAudioInputStream(soundFile, sudMapListener);
// System.out.println("END SUD FILE:");
// for some reason - task finished may not be called on other
// thread so put this here.
this.result = stream;
this.done = true;
return stream;
} catch (UnsupportedAudioFileException e) {
System.err.println("UnsupportedAudioFileException: Could not open sud file: not a supported file "
+ soundFile.getName());
System.err.println(e.getMessage());
// e.printStackTrace();
} catch (IOException e) {
System.err.println("Could not open sud file: IO Exception: " + soundFile.getName());
e.printStackTrace();
}
return null;
}
@Override
public void taskFinished(AudioInputStream result) {
// System.out.println("TASK FINSIHED:");
this.result = result;
this.done = true;
}
public boolean isDone() {
return done;
}
}
}

View File

@ -27,13 +27,14 @@ public class SudAudioFileReader {
public SudAudioFileReader() {
sudParams = new SudParams();
//set up the sud params for default. i.e. just read files and
//don't save any decompressed or meta data.
sudParams.saveWav = false;
sudParams.saveMeta = false;
sudParams.zeroPad = true;
}
sudParams = new SudParams();
//set up the sud params for default. i.e. just read files and
//don't save any decompressed or meta data.
// sudParams.saveWav = false;
// sudParams.saveMeta = false;
sudParams.setFileSave(false, false, false, false);
sudParams.zeroPad = true;
}
/**
* Get the audio input streamn.
@ -51,5 +52,25 @@ public class SudAudioFileReader {
}
return sudAudioInputStream;
}
/**
* Get the audio input stream for a sud file.
* @param file - the .sud file to open.
* @param mapListener- a listener for the sud file maps - can be null.
* @return the sud AudioStream.
* @throws UnsupportedAudioFileException
* @throws IOException
*/
public AudioInputStream getAudioInputStream(File file, SudMapListener mapListener) throws UnsupportedAudioFileException, IOException {
// System.out.println("Get SUD getAudioInputStream");
try {
sudAudioInputStream = SudAudioInputStream.openInputStream(file, sudParams, mapListener, false);
} catch (Exception e) {
String msg = String.format("Corrupt sud file %s: %s", file.getName(), e.getMessage());
throw new UnsupportedAudioFileException(msg);
}
return sudAudioInputStream;
}
}

View File

@ -1,18 +1,12 @@
package Acquisition.sud;
import java.io.File;
import org.pamguard.x3.sud.ChunkHeader;
import org.pamguard.x3.sud.SudAudioInputStream;
import org.pamguard.x3.sud.SudFileMap;
import org.pamguard.x3.sud.SudParams;
import PamUtils.PamCalendar;
public class SUDFileTime {
private static long sudTime;
private static String lastFilePath = "";
/**
* Temp measure to get the time from the first available sud record.
@ -20,6 +14,7 @@ public class SUDFileTime {
* @return
*/
public static long getSUDFileTime(File file) {
//System.out.println("Get sud file time: " + file.getName());
if (file == null || file.exists() == false) {
return Long.MIN_VALUE;
}
@ -36,22 +31,26 @@ public class SUDFileTime {
*/
// long t1 = System.currentTimeMillis();
sudTime = Long.MIN_VALUE;
SudParams sudParams = new SudParams();
sudParams.saveMeta = false;
sudParams.saveWav = false;
// SudParams sudParams = new SudParams();
// sudParams.saveMeta = false;
// sudParams.saveWav = false;
try {
SudAudioInputStream sudAudioInputStream = SudAudioInputStream.openInputStream(file, sudParams, false);
if (sudAudioInputStream == null) {
return Long.MIN_VALUE;
}
SudFileMap sudMap = sudAudioInputStream.getSudMap();
if (sudMap == null) {
return Long.MIN_VALUE;
}
long t = sudMap.getFirstChunkTimeMillis();
//
// SudAudioInputStream sudAudioInputStream = SudAudioInputStream.openInputStream(file, sudParams, false);
// if (sudAudioInputStream == null) {
// return Long.MIN_VALUE;
// }
// SudFileMap sudMap = sudAudioInputStream.getSudMap();
// if (sudMap == null) {
// return Long.MIN_VALUE;
// }
// long t = sudMap.getFirstChunkTimeMillis();
long t = SudAudioInputStream.quickFileTime(file);
t=t/1000; //turn to milliseconds.
if (t != 0) {
sudTime = t;
}
// sudAudioInputStream.addSudFileListener((chunkID, sudChunk)->{
// ChunkHeader chunkHead = sudChunk.chunkHeader;
// if (chunkHead == null || sudTime != Long.MIN_VALUE) {
@ -70,17 +69,16 @@ public class SUDFileTime {
// sudAudioInputStream.read();
// }
//
sudAudioInputStream.close();
// sudAudioInputStream.close();
// long t2 = System.currentTimeMillis();
// System.out.printf("SUD file time %s extracted in %d milliseconds\n", PamCalendar.formatDBDateTime(sudTime), t2-t1);
} catch (Exception e) {
System.err.println("Error getting time from SUD file: " + e.getMessage());
System.err.println("Error getting time from SUD file: " + file + " " + e.getMessage());
e.printStackTrace();
}
return sudTime;
}
}
}