SUD Processing

Extraction of SUD file clicks with SoundTrap Click Detector. Timing now
correct. Added some help pages.
This commit is contained in:
Douglas Gillespie 2022-11-12 19:21:57 +00:00
parent 068a8b1a27
commit d1af000040
21 changed files with 480 additions and 28 deletions

View File

@ -54,6 +54,7 @@ import asiojni.NewAsioSoundSystem;
import nidaqdev.NIDAQProcess;
import Acquisition.filedate.FileDate;
import Acquisition.filedate.StandardFileDate;
import Acquisition.filetypes.SoundFileTypes;
import Acquisition.layoutFX.AquisitionGUIFX;
import Acquisition.offlineFuncs.OfflineWavFileServer;
import Acquisition.rona.RonaOfflineFileServer;
@ -138,6 +139,8 @@ public class AcquisitionControl extends PamControlledUnit implements PamSettings
private SUDNotificationManager sudNotificationManager;
protected SoundFileTypes soundFileTypes;
/**
* Main control unit for audio data acquisition.
* <p>
@ -162,6 +165,8 @@ public class AcquisitionControl extends PamControlledUnit implements PamSettings
pamController = PamController.getInstance();
soundFileTypes = new SoundFileTypes(this);
registerDaqSystem(new SoundCardSystem(this));
if (PlatformInfo.calculateOS() == OSType.WINDOWS) {
registerDaqSystem(new ASIOSoundSystem(this));

View File

@ -16,6 +16,8 @@ import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.UnsupportedAudioFileException;
@ -53,6 +55,7 @@ import wavFiles.ByteConverter;
import Acquisition.filedate.FileDate;
import Acquisition.filedate.FileDateDialogStrip;
import Acquisition.filedate.FileDateObserver;
import Acquisition.filetypes.SoundFileType;
import Acquisition.pamAudio.PamAudioFileManager;
import Acquisition.pamAudio.PamAudioFileFilter;
import PamController.PamControlledUnitSettings;
@ -145,6 +148,11 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
protected FileDateDialogStrip fileDateStrip;
/**
* Sound file types present in the current selections.
*/
private List<SoundFileType> selectedFileTypes;
/**
* Text field for skipping initial few seconds of a file.
*/
@ -400,6 +408,9 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
if (newFile.length() == 0) return;
File file = new File(newFile);
setSelectedFileTypes(acquisitionControl.soundFileTypes.getUsedTypes(file));
if (file == null) return;
// try to work out the date of the file
@ -1222,4 +1233,27 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
getDialogPanel();
}
}
/**
* @return the selectedFileTypes
*/
public List<SoundFileType> getSelectedFileTypes() {
return selectedFileTypes;
}
/**
* Called when the file or file list selection is changes and finds a list of all
* sound file types included in the selection. this is only implemented for SUD files
* at the moment, the idea being to offer some additional functionality.
* @param selectedFileTypes the selectedFileTypes to set
*/
public void setSelectedFileTypes(List<SoundFileType> selectedFileTypes) {
this.selectedFileTypes = selectedFileTypes;
if (selectedFileTypes == null) {
return;
}
for (SoundFileType aType : selectedFileTypes) {
aType.selected(this);
}
}
}

View File

@ -10,6 +10,8 @@ import java.awt.event.ActionListener;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.swing.BoxLayout;
@ -495,6 +497,9 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings{
// fileListData.getFileCount(), System.currentTimeMillis() - wavListStart);
allFiles = fileListData.getListCopy();
List<WavFileType> asList = allFiles;
setSelectedFileTypes(acquisitionControl.soundFileTypes.getUsedTypes(allFiles));
setFileDateText();
// also open up the first file and get the sample rate and number of channels from it
// and set these

View File

@ -0,0 +1,29 @@
package Acquisition.filetypes;
import Acquisition.FileInputSystem;
import PamView.dialog.warn.WarnOnce;
public class SUDFileType extends SoundFileType {
private boolean isShown = false;
private String sudInfoText = "<html>There are SoundTrap SUD files in your selection. PAMGuard can now process data from these " +
"directly with no need to unpack them into WAV files. " +
"<p>If the SoundTrap was running with the click detector, then you should add a SoundTrap Click Detector module" +
" and detected clicks will automatically be extracted to binary files while processing the wav data." +
"<p>See the Click Detector help for further details";
public SUDFileType() {
super(".sud");
}
@Override
public void selected(FileInputSystem fileInputSystem) {
if (isShown) {
return;
}
WarnOnce.showWarning("SoundTrap SUD Files", sudInfoText, WarnOnce.OK_OPTION);
isShown = true;
}
}

View File

@ -0,0 +1,65 @@
package Acquisition.filetypes;
import java.io.File;
import java.util.List;
import Acquisition.FileInputSystem;
import Acquisition.pamAudio.PamAudioFileFilter;
import PamUtils.worker.filelist.WavFileType;
/**
* Some functions for the File and Folder input systems to give a bit of
* extra functionality / help for different file types. Primarily introduced
* to give a couple of extras for sud files.
* @author dg50
*
*/
public abstract class SoundFileType {
private String fileType;
private PamAudioFileFilter fileFilter = new PamAudioFileFilter();
public SoundFileType(String fileType) {
this.fileType = fileType.toLowerCase();
}
/**
* Work out if any files of this type are included in the current selection.
* @param fileOrFolder this for a single file.
* @param includeSubfolders used with folders.
* @return true if any exist.
*/
public boolean isFileType(File oneFile) {
if (oneFile == null) {
return false;
}
if (oneFile.isFile()) {
return oneFile.getName().toLowerCase().endsWith(fileType);
}
return false;
}
/**
* Work out if any files of this type are included in the current selection.
* @param fileOrFolder this for a single file.
* @param includeSubfolders used with folders.
* @return true if any exist.
*/
public boolean hasFileType(List<WavFileType> files) {
if (files == null) {
return false;
}
for (File aFile : files) {
if (isFileType(aFile)) {
return true;
}
}
return false;
}
public abstract void selected(FileInputSystem fileInputSystem);
}

View File

@ -0,0 +1,74 @@
package Acquisition.filetypes;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import Acquisition.AcquisitionControl;
import PamUtils.worker.filelist.WavFileType;
/**
* List of SoundFileType objects.
* @author dg50
*
*/
public class SoundFileTypes {
private AcquisitionControl acquisitionControl;
private ArrayList<SoundFileType> availableTypes = new ArrayList<>();
public SoundFileTypes(AcquisitionControl acquisitionControl) {
this.acquisitionControl = acquisitionControl;
availableTypes.add(new SUDFileType());
}
/**
* Get a list of used file types. Reaslistically this
* can only return one value.
* @param aFile
* @return
*/
public SoundFileType getFileType(File aFile) {
ArrayList<SoundFileType> usedTypes = new ArrayList<>();
for (SoundFileType aType : availableTypes) {
if (aType.isFileType(aFile)) {
return aType;
}
}
return null;
}
/**
* Get a list of used file types. Reaslistically this
* can only return one value but possibly it's useful to have it in the same
* format as the multiple file version. .
* @param aFile
* @return
*/
public List<SoundFileType> getUsedTypes(File aFile) {
ArrayList<SoundFileType> usedTypes = new ArrayList<>();
for (SoundFileType aType : availableTypes) {
if (aType.isFileType(aFile)) {
usedTypes.add(aType);
}
}
return usedTypes;
}
/**
* Get a list of used file types for the folder Input System.
* @param aFile
* @return
*/
public List<SoundFileType> getUsedTypes(List<WavFileType> aFile) {
ArrayList<SoundFileType> usedTypes = new ArrayList<>();
for (SoundFileType aType : availableTypes) {
if (aType.hasFileType(aFile)) {
usedTypes.add(aType);
}
}
return usedTypes;
}
}

View File

@ -17,7 +17,7 @@ public class PamAudioFileFilter extends PamFileFilter {
// addFileType(".AIFF");
// addFileType(".FLAC");
addFileType(".flac");
// addFileType(".sud");
addFileType(".sud");
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,2 +1,2 @@
JavaSearch 1.0
TMAP bs=2048 rt=1 fl=-1 id1=6679 id2=1
TMAP bs=2048 rt=1 fl=-1 id1=6697 id2=1

Binary file not shown.

View File

@ -574,6 +574,8 @@
<mapID target="utilities.SIDEModule.docs.SIDE_Overview_seq" url="utilities/SIDEModule/docs/SIDE_Overview.html#seq"/>
<mapID target="detectors.clickDetectorHelp.docs.SoundTrapClickDetector" url="detectors/clickDetectorHelp/docs/SoundTrapClickDetector.html"/>
<mapID target="utilities.spectrogramannotations.docs.using" url="utilities/spectrogramannotations/docs/using.html"/>
<mapID target="visual_methods.loggerFormsHelp.docs.NMEAINT" url="visual_methods/loggerFormsHelp/docs/NMEAINT.html"/>
@ -802,6 +804,8 @@
<mapID target="visual_methods.loggerFormsHelp.docs.NMEACHAR" url="visual_methods/loggerFormsHelp/docs/NMEACHAR.html"/>
<mapID target="sound_processing.AcquisitionHelp.docs.sudfiles" url="sound_processing/AcquisitionHelp/docs/sudfiles.html"/>
<mapID target="sound_processing.LTSA.Docs.LTSADisplays" url="sound_processing/LTSA/Docs/LTSADisplays.html"/>
<mapID target="localisation.difar.difarLocalisation.docs.difar_PostProcessingTutorial__Toc396467156" url="localisation/difar/difarLocalisation/docs/difar_PostProcessingTutorial.html#_Toc396467156"/>

View File

@ -16,6 +16,11 @@
@ -35,6 +40,11 @@
@ -54,6 +64,11 @@
@ -75,6 +90,11 @@ top
@ -94,6 +114,11 @@ top
@ -113,6 +138,11 @@ top
@ -132,6 +162,11 @@ top
@ -153,6 +188,11 @@ TOC
@ -174,6 +214,11 @@ TOC
@ -195,6 +240,11 @@ javax.help.TOCView
@ -216,6 +266,11 @@ PAMGUARDTOC.xml
@ -235,6 +290,11 @@ PAMGUARDTOC.xml
@ -254,6 +314,11 @@ PAMGUARDTOC.xml
@ -275,6 +340,11 @@ Index
@ -296,6 +366,11 @@ Index
@ -317,6 +392,11 @@ javax.help.IndexView
@ -338,6 +418,11 @@ PAMGUARDIndex.xml
@ -357,6 +442,11 @@ PAMGUARDIndex.xml
@ -376,6 +466,11 @@ PAMGUARDIndex.xml
@ -397,6 +492,11 @@ Search
@ -418,6 +518,11 @@ Search
@ -439,6 +544,11 @@ javax.help.SearchView
@ -460,6 +570,11 @@ JavaHelpSearch
@ -479,6 +594,11 @@ JavaHelpSearch

View File

@ -2,6 +2,8 @@
<!DOCTYPE index PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 1.0//EN" "http://java.sun.com/products/javahelp/index_2_0.dtd"><!--generated by JHelpDev Version: 0.63, 14 May 2008, see jhelpdev.sourceforge.net-->
<index version="1.0">
<indexitem text="SoundTrap " target="detectors.clickDetectorHelp.docs.SoundTrapClickDetector"/>
<indexitem text="3D Localisation " target="detectors.Pam3DHelp.docs.guiOverview"/>
<indexitem text="Adding or Editing a Hydrophone " target="utilities.hydrophoneArrayManagerHelp.docs.Array_NewHydrophone"/>

View File

@ -278,8 +278,10 @@
<tocitem text="Asio Sound Cards " target="sound_processing.AcquisitionHelp.docs.AcquisitionAsioSoundCard" image="topic"/>
<tocitem text="Audio Files " target="sound_processing.AcquisitionHelp.docs.AcquisitionFile" image="topic"/>
<tocitem text="Audio Files " target="sound_processing.AcquisitionHelp.docs.AcquisitionFile" image="topic">
<tocitem text="SUD Files " target="sound_processing.AcquisitionHelp.docs.sudfiles" image="topic"/>
</tocitem>
<tocitem text="Audio File Folders " target="sound_processing.AcquisitionHelp.docs.AcquisitionFileFolder" image="topic"/>
<tocitem text="File Dates " target="sound_processing.AcquisitionHelp.docs.FileTimeZone" image="topic"/>
@ -426,6 +428,8 @@
<tocitem text="Create Binary Files Offline " target="utilities.BinaryStore.docs.CreateBinariesOffline" image="topic"/>
</tocitem>
<tocitem text="SoundTrap Click Detector " target="detectors.clickDetectorHelp.docs.SoundTrapClickDetector" image="topic"/>
</tocitem>
<tocitem text="Whistle and Moan Detector ">
<tocitem text="Overview " target="detectors.whistleMoanHelp.docs.whistleMoan_Overview" image="topic"/>

View File

@ -0,0 +1,80 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<link href="../../../pamHelpStylesheet.css" type="text/css" rel="STYLESHEET"><title>Click Classification</title></head>
<body><h1>
SoundTrap Click Detector
</h1><h2>SoundTrap Click Detector</h2>
<br>
<h3>Overview</h3>
<p>If you are using a SountTrap recording device with built in click detection from
<a href="https://www.oceaninstruments.co.nz/">Ocean Instruments</a>,
you may need to use a modified version of the <a href="ClickDetector_clickDetector.html">Click Detector</a>.
</p>
<p>The SoundTrap click detector allows you to detect and store clicks at high frequencies (say 384kHz), suitable for odontocete echolocation clicks, and
at the same time, record audio data files at a lower frequency (e.g. 96 or 48kHz). This optimises disk space usage and makes long deployments
of several months possible with moderate data storage. </p>
<p>Having two sample rates present within a single PAMGuard configuration is possible, using
<a href="../../../sound_processing/decimatorHelp/docs/decimator_decimator.html">Decimator</</a> modules, however such configurations become particularly
complicated to configure when the sample rate of the recorded files is lower than the sample rate of the click detector.</p>
<p>We therefore recommend that you use a modified version of the <a href="ClickDetector_clickDetector.html">Click Detector</a>which manages it's own sample rate and
channel information based on information extracted from the SoundTrap data.</p>
<p>Note that the SoundTrap click detector should only be used for clicks automatically detected by the SoundTrap. If you want to detect clicks from the
SoundTrap recordings, then use a normal <a href="ClickDetector_clickDetector.html">Click Detector</a> in the normal way.</p>
<h3>Creating an instance of the SoundTrap Click Detector</h3>
<p>
From the <strong><em>File>Add modules>Detectors</em></strong> menu, or
from the pop-up menu on the data model display, select <i>'SoundTrap Click
Detector'</i> near the bottom of the list. Enter a descriptive name for the new detector and press Ok.
</p>
<h3>Importing SoundTrap Data</h3>
<p>SoundTrap data are stored in proprietary files called <a href="../../../sound_processing/AcquisitionHelp/docs/sudfiles.html">SUD files</a>.</p>
<p> There are two ways in which you can get data from <a href="../../../sound_processing/AcquisitionHelp/docs/sudfiles.html">SUD files</a> into
the SoundTrap Click Detector. </p>
<h4>The Old Way</h4>
<p>The 'standard' way of using SoundTrap data was to inflate all of the data from the compressed SUD files. For details of this process, see the
SoundTrap user manuals and the SoundTrap Host software.</p>
<p>Normally, several inflated files are generated from each sud file:</p>
<ol>
<li>A wav file: Audio data in standard wav file format</li>
<li>An XML file: Metadata on the SoundTrap configuration, file start times in various formats, etc.</li>
<li>If the click detector was running BCL and DWV files, which contain the times of clicks and click waveforms respectively.</li>
</ol>
<p>To convert the SUD files to the binary storage format used by PAMGuard, working in the
<a href="../../../overview/PamMasterHelp/docs/viewerMode.html">PAMGuard Viewer</a>, create a Binary Store, a
SoundTrap Click Detector and also create a 'SoundTrap Detector Import' module. Then use the import module to import the BCL and DWV
data into PAMGuard. Once imported you can run <a href="ClickDetector_clickClassification.html">Click Classifiers</a>
and use other Click Detector offline functions to mark events, etc. </p>
<p>If you want to run additional analysis on the WAV file data (for example to make noise measurements or to detect whistles),
create a different PAMGuard configuration to process those data.<p>
<h4>The (better) New Way</h4>
<p>Current versions of PAMGuard can read SUD files directly, without first unpacking them into WAV, XML, BCL and DWV files. This not
only reduces the amount of disk space you need by about x4, but also saves a lot of time.</p>
<p>Better still, you can now set up PAMGuard in normal mode to simultaneously process the audio data in the sud file with one set of
detectors, and simultaneously extract the click detector data into appropriate files for a SoundTrap Click Detector. </p>
<p>Start PAMGuard in <a href="../../../overview/PamMasterHelp/docs/normalMode.html">Normal Mode</a> and add a
<a href="../../../sound_processing/AcquisitionHelp/docs/AcquisitionOverview.html">Sound Acquisition</a> module.
Add a SoundTrap Click Detector, a <a href="../../../utilities/BinaryStore/docs/binarystore_overview.html">Binary Store</a> store and a
<a href="../../../utilities/generalDatabaseHelp/docs/database_database.html">Database</a>
module (optional). In the <a href="../../../sound_processing/AcquisitionHelp/docs/AcquisitionConfiguration.html">Sound Acquisition dialog</a>
select a single SUD file or a folder of SUD files. At this point, the SoundTrap
Click Detector will be automatically configured with the correct sample rate (which won't be the sample rate displayed in the Sound Acquisition
module). </p>
<p>Configure any <a href="ClickDetector_clickClassification.html">Click Classifiers</a> you want to be run on the SoundTrap click data as it is imported.</p>
<p>You can then add any other detectors and measurement processes you want to run on the SoundTrap audio data, this may include
instances of the normal Click Detector module if you want to detect clicks in the lower frequency audio data.</p>
<p>Process the data in the normal way and clicks will automatically be generated within the SoundTrap click detector</p>
<p>Further process you data using the <a href="../../../overview/PamMasterHelp/docs/viewerMode.html">PAMGuard Viewer</a> in the normal way.</p>
<br>
<br>
<br>
</body></html>

View File

@ -7,7 +7,9 @@
<h1>Audio Files</h1>
<p>As well as analysing data from sound cards in real time, PAMGUARD can be used to analyse archived data
from audio filed in WAV or AIF format.</p>
from audio filed in <a href="https://en.wikipedia.org/wiki/WAV">WAV</a>,
<a href="https://en.wikipedia.org/wiki/Audio_Interchange_File_Format">AIF</a>, <a href="https://en.wikipedia.org/wiki/FLAC">FLAC</a>,
or <a href="sudfiles.html">SUD</a> file format.</p>
<br>
<h2>Setting up an Audio File</h2>

View File

@ -0,0 +1,27 @@
<html>
<head>
<LINK href="../../../pamHelpStylesheet.css" type=text/css rel=STYLESHEET>
<title>SUD Files</title>
</head>
<body>
<h1>SoundTrap data files</h1>
<h3>SUD Files</h3>
<p>
SoundTrap recorders from
<a href="https://www.oceaninstruments.co.nz/">Ocean Instruments</a>
store data in proprietary files called SUD files. See SoundTrap documentation for information on how to
extract SUD files from SoundTrap recorders. </p>
<p>Earlier versions of PAMGuard required you to 'inflate' the SUD files into standard wav audio files using
the <a href="https://www.oceaninstruments.co.nz/downloads/">SoundTrap Host software</a> before they could be processed.</p>
<p>The current version of PAMGuard no longer requires this since it can read data directly from the SUD files.</p>
<p>Inflating SUD files to WAV files generally required between 3 and 5 times as much disk space and could also take
a fair amount of time, so not inflating will save both!</p>
<h3>SoundTrap Click Detector</h3>
<p>If you are using the SoundTrap build in click detector (see SoundTrap manuals) then the SUD files will also contain
detected clicks.</p> <p>See the help page for the <a href="../../../detectors/clickDetectorHelp/docs/SoundTrapClickDetector.html">SoundTrap Click Detector</a>
for information on how to get these clicks from the SUD files into PAMGuard. </p>
<br><br><br>
</body>
</html>

View File

@ -216,6 +216,7 @@ public class SudFileDWVHandler implements SUDNotificationHandler {
// channelGroupDetector = clickDetector.getChannelGroupDetector(0);
ClickDetection click = new ClickDetection(1, elapsedSamples, nSamples, clickDetector, channelGroupDetector, 1);
click.setTimeMilliseconds(millis);
click.setWaveData(wavData);
// if (groupDetector != null) {