From 6ee03579d04a4af064778be29906f3f223da4140 Mon Sep 17 00:00:00 2001 From: Jamie Mac Date: Tue, 9 Jul 2024 13:14:43 +0100 Subject: [PATCH] Add zero pad option for sud files. --- src/Acquisition/FolderInputSystem.java | 16 +++- .../pamAudio/PamAudioFileLoader.java | 1 + .../pamAudio/PamAudioFileManager.java | 2 + .../pamAudio/PamAudioSettingsPane.java | 13 +++ src/Acquisition/pamAudio/PamAudioSystem.java | 2 + src/Acquisition/sud/PamSudParams.java | 33 ++++++++ .../{pamAudio => sud}/SudAudioFile.java | 65 +++++++++++++-- .../{pamAudio => sud}/SudAudioFileReader.java | 23 +++++- src/Acquisition/sud/SudAudioSettingsPane.java | 79 +++++++++++++++++-- 9 files changed, 219 insertions(+), 15 deletions(-) create mode 100644 src/Acquisition/sud/PamSudParams.java rename src/Acquisition/{pamAudio => sud}/SudAudioFile.java (78%) rename src/Acquisition/{pamAudio => sud}/SudAudioFileReader.java (76%) diff --git a/src/Acquisition/FolderInputSystem.java b/src/Acquisition/FolderInputSystem.java index fab8e961..5357638a 100644 --- a/src/Acquisition/FolderInputSystem.java +++ b/src/Acquisition/FolderInputSystem.java @@ -256,11 +256,11 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D addComponent(p, skipSecondsField = new JTextField(4), constraints); constraints.gridx++; addComponent(p, new JLabel("seconds"), constraints); - constraints.anchor = GridBagConstraints.EAST; // } //panel to show bespoke settings for certain audio loaders. + constraints.anchor = GridBagConstraints.WEST; constraints.gridx = 0; constraints.gridy++; constraints.gridwidth = 3; @@ -618,6 +618,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D // System.out.println("ADD AUDIO PANEL: " +loader.getSettingsPane().getAudioLoaderPanel()); //gridbag layout addComponent(audioLoaderHolder, loader.getSettingsPane().getAudioLoaderPanel(), constraints); + loader.getSettingsPane().setParams(); constraints.gridy++; } } @@ -823,6 +824,17 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D return false; } } + + //get bespoke paramters from selected audio loaders. + ArrayList loaders = PamAudioFileManager.getInstance().getAudioFileLoaders(allFiles); + + + for (PamAudioFileLoader loader : loaders) { + if (loader.getSettingsPane()!=null) { + loader.getSettingsPane().getParams(); + } + } + return super.dialogGetParams(); } @@ -1005,6 +1017,8 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D String bs = String.format("%d,%d,%d,%s", nFiles,currentFile,generalStatus,currFile); return bs; } + + } diff --git a/src/Acquisition/pamAudio/PamAudioFileLoader.java b/src/Acquisition/pamAudio/PamAudioFileLoader.java index 077e1f6e..797ab56d 100644 --- a/src/Acquisition/pamAudio/PamAudioFileLoader.java +++ b/src/Acquisition/pamAudio/PamAudioFileLoader.java @@ -53,6 +53,7 @@ public interface PamAudioFileLoader { * @return settings pane for audio loader - can be null. */ public PamAudioSettingsPane getSettingsPane(); + } diff --git a/src/Acquisition/pamAudio/PamAudioFileManager.java b/src/Acquisition/pamAudio/PamAudioFileManager.java index 3805e738..cf57787e 100644 --- a/src/Acquisition/pamAudio/PamAudioFileManager.java +++ b/src/Acquisition/pamAudio/PamAudioFileManager.java @@ -9,6 +9,8 @@ import javax.sound.sampled.UnsupportedAudioFileException; import org.codehaus.plexus.util.FileUtils; +import Acquisition.sud.SudAudioFile; + /** * Central class for opening sound files. *

diff --git a/src/Acquisition/pamAudio/PamAudioSettingsPane.java b/src/Acquisition/pamAudio/PamAudioSettingsPane.java index 50e33f4d..0db5beab 100644 --- a/src/Acquisition/pamAudio/PamAudioSettingsPane.java +++ b/src/Acquisition/pamAudio/PamAudioSettingsPane.java @@ -3,6 +3,9 @@ package Acquisition.pamAudio; import PamView.panel.PamPanel; import javafx.scene.layout.Pane; +/** + * User controls to change bespoke settings for audio loaders. + */ public interface PamAudioSettingsPane { /** @@ -17,5 +20,15 @@ public interface PamAudioSettingsPane { */ public PamPanel getAudioLoaderPanel(); + /** + * Get the parameters. This called whenever the settings dialog or pane is closed. + */ + public void getParams(); + + /** + * Set parameters. This is called when the dialog or pane is opened. + */ + public void setParams(); + } diff --git a/src/Acquisition/pamAudio/PamAudioSystem.java b/src/Acquisition/pamAudio/PamAudioSystem.java index ae50726f..6c012e21 100644 --- a/src/Acquisition/pamAudio/PamAudioSystem.java +++ b/src/Acquisition/pamAudio/PamAudioSystem.java @@ -10,6 +10,8 @@ import javax.sound.sampled.UnsupportedAudioFileException; //import org.kc7bfi.jflac.sound.spi.FlacAudioFileReader; import org.jflac.sound.spi.FlacAudioFileReader; +import Acquisition.sud.SudAudioFileReader; + /** * Now replaced with PamAudioFileManager. * diff --git a/src/Acquisition/sud/PamSudParams.java b/src/Acquisition/sud/PamSudParams.java new file mode 100644 index 00000000..85ce3ea2 --- /dev/null +++ b/src/Acquisition/sud/PamSudParams.java @@ -0,0 +1,33 @@ +package Acquisition.sud; + +import java.io.Serializable; + + +/** + * Parameters for sud file extraction. + */ +public class PamSudParams implements Serializable, Cloneable { + + public static final long serialVersionUID = 1L; + + /** + * Zero padding fills gaps in sud files with zeros - these gaps are usually due + * to errors in the recording hardware.Without zero pad then time drift within a + * file can be difficult to predict, however zero padding means the sample + * numbers in other files e.g. csv sensor files will not align. + */ + public boolean zeroPad = true; + + @Override + public PamSudParams clone() { + try { + PamSudParams ap = (PamSudParams) super.clone(); + + return ap; + } + catch (CloneNotSupportedException Ex) { + Ex.printStackTrace(); + } + return null; + } +} diff --git a/src/Acquisition/pamAudio/SudAudioFile.java b/src/Acquisition/sud/SudAudioFile.java similarity index 78% rename from src/Acquisition/pamAudio/SudAudioFile.java rename to src/Acquisition/sud/SudAudioFile.java index efd86f67..840edec1 100644 --- a/src/Acquisition/pamAudio/SudAudioFile.java +++ b/src/Acquisition/sud/SudAudioFile.java @@ -1,7 +1,8 @@ -package Acquisition.pamAudio; +package Acquisition.sud; import java.io.File; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -12,8 +13,13 @@ import javax.swing.SwingUtilities; import org.pamguard.x3.sud.ChunkHeader; import org.pamguard.x3.sud.SudMapListener; -import Acquisition.sud.SudAudioSettingsPane; +import Acquisition.AcquisitionParameters; +import Acquisition.pamAudio.PamAudioSettingsPane; +import Acquisition.pamAudio.WavAudioFile; +import PamController.PamControlledUnitSettings; import PamController.PamController; +import PamController.PamSettingManager; +import PamController.PamSettings; import PamUtils.worker.PamWorkProgressMessage; import PamUtils.worker.PamWorkWrapper; import PamUtils.worker.PamWorker; @@ -31,21 +37,32 @@ import PamUtils.worker.PamWorker; * @author Jamie Macaulay * */ -public class SudAudioFile extends WavAudioFile { +public class SudAudioFile extends WavAudioFile implements PamSettings { private Object conditionSync = new Object(); private volatile PamWorker worker; + private volatile SudMapWorker sudMapWorker; /** * Settings pane to allow users to set some additional options. */ private SudAudioSettingsPane sudAudioSettingsPane; + + /** + * Parameters for the sud file. TODO Note: PamAudioManager is always a single + * instance referenced globally from PAMGuard. Having parameters is therefore + * slightly problematic because they will apply across SoundAcquisition modules. + * So in the case that someone is using two or more Sound Acquisition modules + * then selecting zero and non -zero pad would be impossible + */ + private PamSudParams sudParams = new PamSudParams(); public SudAudioFile() { super(); fileExtensions = new ArrayList(Arrays.asList(new String[] { ".sud" })); + PamSettingManager.getInstance().registerSettings(this); } @Override @@ -69,7 +86,7 @@ public class SudAudioFile extends WavAudioFile { if (new File(soundFile.getAbsolutePath() + "x").exists()) { // System.out.println("----NO NEED TO MAP SUD FILE-----" + soundFile); try { - return new SudAudioFileReader().getAudioInputStream(soundFile); + return new SudAudioFileReader(sudParams.zeroPad).getAudioInputStream(soundFile); } catch (UnsupportedAudioFileException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -187,7 +204,7 @@ public class SudAudioFile extends WavAudioFile { // System.out.println("START OPEN SUD FILE:"); this.sudMapListener = new SudMapProgress(pamWorker); - stream = new SudAudioFileReader().getAudioInputStream(soundFile, sudMapListener); + stream = new SudAudioFileReader(sudParams.zeroPad).getAudioInputStream(soundFile, sudMapListener); // System.out.println("END SUD FILE:"); @@ -231,4 +248,42 @@ public class SudAudioFile extends WavAudioFile { return sudAudioSettingsPane; } + @Override + public String getUnitName() { + return "PamAudioManager"; + } + + @Override + public String getUnitType() { + return "sud_files"; + } + + @Override + public Serializable getSettingsReference() { + return sudParams; + } + + @Override + public long getSettingsVersion() { + return PamSudParams.serialVersionUID; + } + + + @Override + public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) { + try { + sudParams = ((PamSudParams) pamControlledUnitSettings.getSettings()).clone(); + + return true; + } + catch (ClassCastException e) { + e.printStackTrace(); + } + return false; + } + + public PamSudParams getSudParams() { + return this.sudParams; + } + } \ No newline at end of file diff --git a/src/Acquisition/pamAudio/SudAudioFileReader.java b/src/Acquisition/sud/SudAudioFileReader.java similarity index 76% rename from src/Acquisition/pamAudio/SudAudioFileReader.java rename to src/Acquisition/sud/SudAudioFileReader.java index b38ea34e..f69467f6 100644 --- a/src/Acquisition/pamAudio/SudAudioFileReader.java +++ b/src/Acquisition/sud/SudAudioFileReader.java @@ -1,4 +1,4 @@ -package Acquisition.pamAudio; +package Acquisition.sud; import java.io.File; import java.io.IOException; @@ -25,15 +25,32 @@ public class SudAudioFileReader { */ SudParams sudParams; - + /** + * Constructor to create an Sud Audio reader with a + * default true to zeropad sud files. + * */ public SudAudioFileReader() { + this(true); + } + + + /** + * Constructor to create an Sud Audio reader. Allows the option of zero padding. + * Zero padding fills gaps in sud files with zeros - these gaps are usually due + * to errors in the recording hardware.Without zero pad then time drift within a + * file can be difficult to predict, however zero padding means the sample + * numbers in other files e.g. csv sensor files will not align. + * + * @param zeroPad - true to zero pad sud files. + */ + public SudAudioFileReader(boolean zeroPad) { 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; + sudParams.zeroPad = zeroPad; } /** diff --git a/src/Acquisition/sud/SudAudioSettingsPane.java b/src/Acquisition/sud/SudAudioSettingsPane.java index 5d3e1e87..71d91e3b 100644 --- a/src/Acquisition/sud/SudAudioSettingsPane.java +++ b/src/Acquisition/sud/SudAudioSettingsPane.java @@ -1,17 +1,25 @@ package Acquisition.sud; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +import javax.swing.JCheckBox; import javax.swing.JLabel; +import javax.swing.JPanel; import Acquisition.pamAudio.PamAudioSettingsPane; -import Acquisition.pamAudio.SudAudioFile; +import PamView.dialog.PamGridBagContraints; import PamView.panel.PamPanel; import javafx.scene.layout.Pane; +/** + * Some Swing and FX controls to allow a user to chnage sud parameters. + */ public class SudAudioSettingsPane implements PamAudioSettingsPane { - + private SudAudioFile sudAudioFile; - - private PamPanel sudAudioPanel; + + private SudSettingsPanel sudAudioPanel; public SudAudioSettingsPane(SudAudioFile sudAudioFile) { this.sudAudioFile=sudAudioFile; @@ -32,10 +40,69 @@ public class SudAudioSettingsPane implements PamAudioSettingsPane { } private void createSudAudioPanel() { - sudAudioPanel = new PamPanel(); + sudAudioPanel = new SudSettingsPanel(); + } + + public void setParams(PamSudParams sudParams) { + //System.out.println("Set SUD PARAMS: " + sudParams + " " + sudParams.zeroPad); + if (sudAudioPanel!=null) sudAudioPanel.setParams(sudParams);; + + } + + public PamSudParams getParams(PamSudParams sudParams) { + //System.out.println("Get SUD PARAMS: " + sudParams + " " + sudParams.zeroPad); + + if (sudAudioPanel!=null) return sudAudioPanel.getParams(sudParams);; + return null; + } + + + /** + * The sud settings panel. + */ + public class SudSettingsPanel extends PamPanel { - sudAudioPanel.add(new JLabel("Hello")); + private static final long serialVersionUID = 1L; + private JCheckBox zeroPadSud; + + public SudSettingsPanel() { + + this.setLayout(new GridBagLayout()); +// soundTrapDate.setPreferredSize(tzPanel.getPreferredSize()); + GridBagConstraints c = new PamGridBagContraints(); + c.gridy = 0; + c.gridx = 0; + c.gridwidth = 1; + + zeroPadSud = new JCheckBox("Zero pad sud files"); + zeroPadSud.setToolTipText("Zero pad sud files. Zero padding replaces sections of sud files \n" + + "with corrupt or no data with zeros. This can improve time drift. "); + + this.add(zeroPadSud,c); + } + + public void setParams(PamSudParams sudParams) { + this.zeroPadSud.setSelected(sudParams.zeroPad); + } + + + public PamSudParams getParams(PamSudParams sudParams) { + sudParams.zeroPad = zeroPadSud.isSelected(); + return sudParams; + } + + } + + + @Override + public void getParams() { + getParams(sudAudioFile.getSudParams()); + } + + @Override + public void setParams() { + setParams(sudAudioFile.getSudParams()); } }