Work on PAMGuard exporter

This commit is contained in:
Jamie Mac 2024-08-19 16:29:20 +01:00
parent 984a37235e
commit 9d4642b6a6
13 changed files with 474 additions and 193 deletions

View File

@ -1,10 +1,12 @@
package export.CSVExport; package export.CSVExport;
import java.awt.Component;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import export.PamDataUnitExporter; import export.PamDataUnitExporter;
import javafx.scene.layout.Pane;
/** /**
@ -50,4 +52,16 @@ public class CSVExportManager implements PamDataUnitExporter{
return false; return false;
} }
@Override
public Component getOptionsPanel() {
// TODO Auto-generated method stub
return null;
}
@Override
public Pane getOptionsPane() {
// TODO Auto-generated method stub
return null;
}
} }

View File

@ -7,7 +7,6 @@ import PamController.PamControlledUnitSettings;
import PamController.PamSettingManager; import PamController.PamSettingManager;
import PamController.PamSettings; import PamController.PamSettings;
import PamController.StorageParameters; import PamController.StorageParameters;
import export.layoutFX.ExportParams;
import export.swing.ExportProcessDialog; import export.swing.ExportProcessDialog;
/** /**
@ -20,10 +19,10 @@ public class ExportOptions implements PamSettings {
private static ExportOptions singleInstance; private static ExportOptions singleInstance;
/** // /**
* Parameters for the exporter. // * Parameters for the exporter.
*/ // */
private ExportParams storageParameters = new ExportParams(); // private ExportParams storageParameters = new ExportParams();
/** /**
* Swing dialog for exporting data. * Swing dialog for exporting data.
@ -57,7 +56,7 @@ public class ExportOptions implements PamSettings {
if (exportProcessDialog==null) { if (exportProcessDialog==null) {
exportProcessDialog= new ExportProcessDialog(exportManager); exportProcessDialog= new ExportProcessDialog(exportManager);
} }
this.exportProcessDialog.showOfflineDialog(parentFrame, this.storageParameters); this.exportProcessDialog.showOfflineDialog(parentFrame, exportManager.getExportParams());
// ExportParams newParams = StorageOptionsDialog.showDialog(parentFrame, storageParameters); // ExportParams newParams = StorageOptionsDialog.showDialog(parentFrame, storageParameters);
// if (newParams != null) { // if (newParams != null) {
@ -73,7 +72,7 @@ public class ExportOptions implements PamSettings {
@Override @Override
public Serializable getSettingsReference() { public Serializable getSettingsReference() {
return storageParameters; return exportManager.getExportParams();
} }
@Override @Override
@ -94,20 +93,21 @@ public class ExportOptions implements PamSettings {
@Override @Override
public boolean restoreSettings( public boolean restoreSettings(
PamControlledUnitSettings pamControlledUnitSettings) { PamControlledUnitSettings pamControlledUnitSettings) {
storageParameters = ((ExportParams) pamControlledUnitSettings.getSettings()).clone(); ExportParams storageParameters = ((ExportParams) pamControlledUnitSettings.getSettings()).clone();
exportManager.setExportParams(storageParameters);
return true; return true;
} }
public void setStorageParameters(ExportParams storageParameters) { public void setExportParameters(ExportParams storageParameters) {
this.storageParameters = storageParameters; exportManager.setExportParams(storageParameters);
} }
/** /**
* Get storage parameters settings. * Get storage parameters settings.
* @return the storage paramters settings * @return the storage paramters settings
*/ */
public ExportParams getStorageParameters() { public ExportParams getExportParameters() {
return storageParameters; return exportManager.getExportParams();
} }
} }

View File

@ -1,4 +1,4 @@
package export.layoutFX; package export;
import java.io.Serializable; import java.io.Serializable;

View File

@ -1,5 +1,6 @@
package export.MLExport; package export.MLExport;
import java.awt.Component;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -11,6 +12,7 @@ import java.util.zip.Deflater;
import PamUtils.PamArrayUtils; import PamUtils.PamArrayUtils;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import export.PamDataUnitExporter; import export.PamDataUnitExporter;
import javafx.scene.layout.Pane;
import us.hebi.matlab.mat.format.Mat5; import us.hebi.matlab.mat.format.Mat5;
import us.hebi.matlab.mat.format.Mat5File; import us.hebi.matlab.mat.format.Mat5File;
import us.hebi.matlab.mat.format.Mat5Writer; import us.hebi.matlab.mat.format.Mat5Writer;
@ -272,6 +274,18 @@ public class MLDetectionsManager implements PamDataUnitExporter {
return false; return false;
} }
@Override
public Component getOptionsPanel() {
// TODO Auto-generated method stub
return null;
}
@Override
public Pane getOptionsPane() {
// TODO Auto-generated method stub
return null;
}

View File

@ -1,10 +1,12 @@
package export; package export;
import java.awt.Component;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import javafx.scene.layout.Pane;
/** /**
* Manages the exporting of data units to a particular type of file e.g. CSV, MATLAB, R, WAV files * Manages the exporting of data units to a particular type of file e.g. CSV, MATLAB, R, WAV files
@ -56,6 +58,18 @@ public interface PamDataUnitExporter {
* @return true if we need a new file. * @return true if we need a new file.
*/ */
public boolean isNeedsNewFile(); public boolean isNeedsNewFile();
/**
* An optional panel that displays additional options for the user.
* @return additional options panel - can be null.
*/
public Component getOptionsPanel();
/**
* An optional JavaFX pane that displays additional options for the user.
* @return pane with additonal options - can be null.
*/
public Pane getOptionsPane();
} }

View File

@ -11,7 +11,6 @@ import PamguardMVC.PamDataUnit;
import export.CSVExport.CSVExportManager; import export.CSVExport.CSVExportManager;
import export.MLExport.MLDetectionsManager; import export.MLExport.MLDetectionsManager;
import export.RExport.RExportManager; import export.RExport.RExportManager;
import export.layoutFX.ExportParams;
import export.wavExport.WavFileExportManager; import export.wavExport.WavFileExportManager;
/** /**
@ -63,7 +62,7 @@ public class PamExporterManager {
pamExporters.add(new MLDetectionsManager()); pamExporters.add(new MLDetectionsManager());
pamExporters.add(new RExportManager(this)); pamExporters.add(new RExportManager(this));
pamExporters.add(new WavFileExportManager()); pamExporters.add(new WavFileExportManager());
pamExporters.add(new CSVExportManager()); // pamExporters.add(new CSVExportManager());
} }
/** /**
@ -73,11 +72,11 @@ public class PamExporterManager {
public boolean exportDataUnit(PamDataUnit<?, ?> dataUnit, boolean force) { public boolean exportDataUnit(PamDataUnit<?, ?> dataUnit, boolean force) {
boolean exportOK = true; boolean exportOK = true;
System.out.println("Add data unit " + dataUnit + " to: "+ currentFile); //System.out.println("Add data unit " + dataUnit + " to: "+ currentFile);
if (dataUnit==null) { if (dataUnit==null) {
if (force) { if (force) {
System.out.println("Write data 1!!" + dataUnitBuffer.size() ); //System.out.println("Write data 1!!" + dataUnitBuffer.size() );
//finish off saving any buffered data //finish off saving any buffered data
exportOK = pamExporters.get(exportParams.exportChoice).exportData(currentFile, dataUnitBuffer, true); exportOK = pamExporters.get(exportParams.exportChoice).exportData(currentFile, dataUnitBuffer, true);
dataUnitBuffer.clear(); dataUnitBuffer.clear();
@ -101,7 +100,7 @@ public class PamExporterManager {
dataUnitBuffer.add(dataUnit); dataUnitBuffer.add(dataUnit);
System.out.println("Write data unit " + dataUnitBuffer.size() + " to: "+ currentFile); //System.out.println("Write data unit " + dataUnitBuffer.size() + " to: "+ currentFile);
if (dataUnitBuffer.size()>=BUFFER_SIZE || force) { if (dataUnitBuffer.size()>=BUFFER_SIZE || force) {
// System.out.println("Write data 2!!" + dataUnitBuffer.size()); // System.out.println("Write data 2!!" + dataUnitBuffer.size());
@ -181,6 +180,14 @@ public class PamExporterManager {
} }
/**
* Get the currently selected exporter.
* @return the currently selected exporter.
*/
public PamDataUnitExporter getCurretnExporter() {
return this.pamExporters.get(this.exportParams.exportChoice);
}

View File

@ -1,5 +1,6 @@
package export.RExport; package export.RExport;
import java.awt.Component;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -20,6 +21,7 @@ import PamguardMVC.PamDataUnit;
import export.PamDataUnitExporter; import export.PamDataUnitExporter;
import export.PamExporterManager; import export.PamExporterManager;
import export.MLExport.MLDetectionsManager; import export.MLExport.MLDetectionsManager;
import javafx.scene.layout.Pane;
/** /**
* Handles exporting pam data units into an rdata. * Handles exporting pam data units into an rdata.
@ -273,5 +275,19 @@ public class RExportManager implements PamDataUnitExporter {
} }
@Override
public Component getOptionsPanel() {
// TODO Auto-generated method stub
return null;
}
@Override
public Pane getOptionsPane() {
// TODO Auto-generated method stub
return null;
}
} }

View File

@ -1,6 +1,7 @@
package export.layoutFX; package export.layoutFX;
import PamController.SettingsPane; import PamController.SettingsPane;
import export.ExportParams;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import pamViewFX.fxNodes.PamBorderPane; import pamViewFX.fxNodes.PamBorderPane;

View File

@ -1,5 +1,6 @@
package export.swing; package export.swing;
import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Frame; import java.awt.Frame;
@ -33,8 +34,8 @@ import PamView.dialog.PamDialog;
import PamView.dialog.PamGridBagContraints; import PamView.dialog.PamGridBagContraints;
import PamView.panel.PamPanel; import PamView.panel.PamPanel;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import export.ExportParams;
import export.PamExporterManager; import export.PamExporterManager;
import export.layoutFX.ExportParams;
import offlineProcessing.OLProcessDialog; import offlineProcessing.OLProcessDialog;
import offlineProcessing.OfflineTaskGroup; import offlineProcessing.OfflineTaskGroup;
import offlineProcessing.TaskMonitor; import offlineProcessing.TaskMonitor;
@ -145,6 +146,10 @@ public class ExportProcessDialog {
*/ */
private JToggleButton[] exportButtons; private JToggleButton[] exportButtons;
private PamPanel extraSettingsPanel;
private PamPanel mainPanel;
public ExportOLDialog(Window parentFrame, OfflineTaskGroup taskGroup, String title) { public ExportOLDialog(Window parentFrame, OfflineTaskGroup taskGroup, String title) {
super(parentFrame, taskGroup, title); super(parentFrame, taskGroup, title);
@ -155,19 +160,23 @@ public class ExportProcessDialog {
super.getDeleteOldDataBox().setVisible(false); super.getDeleteOldDataBox().setVisible(false);
//construc tthe panel. //construc tthe panel.
PamPanel mainPanel = new PamPanel(); mainPanel = new PamPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS)); mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
mainPanel.setBorder(new TitledBorder("Export Settings")); mainPanel.setBorder(new TitledBorder("Export Settings"));
buttonGroup = new ButtonGroup(); buttonGroup = new ButtonGroup();
extraSettingsPanel = new PamPanel();
PamPanel buttonPanel = new PamPanel(); PamPanel buttonPanel = new PamPanel();
ActionListener listener = actionEvent -> { ActionListener listener = actionEvent -> {
// System.out.println(actionEvent.getActionCommand() + " Selected"); // System.out.println(actionEvent.getActionCommand() + " Selected");
//TODO set the buttons to be disabled or enabled. //TODO set the buttons to be disabled or enabled.
enableTasks(getExportSelection()); enableTasks();
}; };
exportButtons = new JToggleButton[exportManager.getNumExporters()]; exportButtons = new JToggleButton[exportManager.getNumExporters()];
@ -189,6 +198,8 @@ public class ExportProcessDialog {
} }
PamPanel p = new PamPanel(new GridBagLayout()); PamPanel p = new PamPanel(new GridBagLayout());
GridBagConstraints c = new PamGridBagContraints(); GridBagConstraints c = new PamGridBagContraints();
c.gridwidth = 3; c.gridwidth = 3;
@ -238,11 +249,9 @@ public class ExportProcessDialog {
c.gridx ++; c.gridx ++;
addComponent(p, new JLabel("MB"), c); addComponent(p, new JLabel("MB"), c);
mainPanel.add(p); mainPanel.add(p);
mainPanel.add(buttonPanel); mainPanel.add(buttonPanel);
mainPanel.add(extraSettingsPanel);
//add the main panel at a different index. //add the main panel at a different index.
getMainPanel().add(mainPanel, 1); getMainPanel().add(mainPanel, 1);
@ -255,17 +264,26 @@ public class ExportProcessDialog {
* Enable which task are disables and enabled. * Enable which task are disables and enabled.
* @param exportSelection * @param exportSelection
*/ */
private void enableTasks(int exportSelection) { private void enableTasks() {
this.currentParams = getExportParams(); this.currentParams = getExportParams();
exportManager.setExportParams(currentParams); exportManager.setExportParams(currentParams);
// ExportTask task; // ExportTask task;
// for (int i=0; i<this.getTaskGroup().getNTasks(); i++) { // for (int i=0; i<this.getTaskGroup().getNTasks(); i++) {
// task = (ExportTask) this.getTaskGroup().getTask(i); // task = (ExportTask) this.getTaskGroup().getTask(i);
// } // }
enableControls(); enableControls();
//add additional controls if needed
extraSettingsPanel.removeAll();
if (exportManager.getCurretnExporter().getOptionsPanel()!=null) {
extraSettingsPanel.add(exportManager.getCurretnExporter().getOptionsPanel(), BorderLayout.CENTER);// add extra settings.
}
mainPanel.validate();
pack();
} }
private Ikon getIconFromString(String iconString) { private Ikon getIconFromString(String iconString) {
Ikon icon = null; Ikon icon = null;
@ -289,7 +307,7 @@ public class ExportProcessDialog {
} }
return icon; return icon;
} }
private int getExportSelection() { private int getExportSelection() {
int sel=-1; int sel=-1;
for (int i=0; i<exportButtons.length; i++) { for (int i=0; i<exportButtons.length; i++) {
@ -301,10 +319,10 @@ public class ExportProcessDialog {
return sel; return sel;
} }
public ExportParams getExportParams() { public ExportParams getExportParams() {
currentParams.folder = null; currentParams.folder = null;
if (exportTo.getText().length()>0) { if (exportTo.getText().length()>0) {
File file = new File(exportTo.getText()); File file = new File(exportTo.getText());
@ -316,15 +334,17 @@ public class ExportProcessDialog {
currentParams.folder = file.getAbsolutePath(); currentParams.folder = file.getAbsolutePath();
} }
} }
currentParams.exportChoice = getExportSelection(); currentParams.exportChoice = getExportSelection();
currentParams.maximumFileSize = (Double) spinner.getValue(); currentParams.maximumFileSize = (Double) spinner.getValue();
return currentParams; return currentParams;
} }
@Override @Override
public boolean getParams() { public boolean getParams() {
System.out.println("EXPORT: GET PARAMS:");
//make sure we update the current paramters before processing starts. //make sure we update the current paramters before processing starts.
this.currentParams = getExportParams(); this.currentParams = getExportParams();
exportManager.setExportParams(currentParams); exportManager.setExportParams(currentParams);
@ -339,27 +359,32 @@ public class ExportProcessDialog {
public void setParams(ExportParams params) { public void setParams(ExportParams params) {
System.out.println("EXPORT: SET PARAMS: " +params);
if (params ==null) currentParams = new ExportParams(); if (params ==null) currentParams = new ExportParams();
currentParams = params.clone(); currentParams = params.clone();
buttonGroup.clearSelection(); buttonGroup.clearSelection();
exportButtons[params.exportChoice].setSelected(true); exportButtons[params.exportChoice].setSelected(true);
System.out.println("EXPORT: SET PARAMS: " +currentParams.folder);
exportTo.setText(currentParams.folder); exportTo.setText(currentParams.folder);
spinner.setValue(currentParams.maximumFileSize); spinner.setValue(currentParams.maximumFileSize);
enableTasks();
} }
} }
class ExportTaskMonitor implements TaskMonitor { class ExportTaskMonitor implements TaskMonitor {
private int taskIndex; private int taskIndex;
private ExportTaskGroup exportTaskGroup; private ExportTaskGroup exportTaskGroup;
private boolean started = false; private boolean started = false;
public ExportTaskMonitor(int i, ExportTaskGroup exportTaskGroup) { public ExportTaskMonitor(int i, ExportTaskGroup exportTaskGroup) {
@ -367,7 +392,7 @@ public class ExportProcessDialog {
this.exportTaskGroup = exportTaskGroup; this.exportTaskGroup = exportTaskGroup;
} }
@Override @Override
public void setTaskStatus(TaskMonitorData taskMonitorData) { public void setTaskStatus(TaskMonitorData taskMonitorData) {
if (taskMonitorData.taskStatus== TaskStatus.COMPLETE && !started) { if (taskMonitorData.taskStatus== TaskStatus.COMPLETE && !started) {
@ -379,9 +404,6 @@ public class ExportProcessDialog {
} }
} }
} }
@ -390,17 +412,17 @@ public class ExportProcessDialog {
*/ */
class ExportTaskGroup extends OfflineTaskGroup { class ExportTaskGroup extends OfflineTaskGroup {
public ExportTaskGroup(String settingsName) { public ExportTaskGroup(String settingsName) {
super(null, settingsName); super(null, settingsName);
} }
@Override @Override
public String getUnitType() { public String getUnitType() {
return "Export Data"; return "Export Data";
} }
/** /**
* Runs tasks from a specific task number. * Runs tasks from a specific task number.
* @param i - the index * @param i - the index
@ -415,10 +437,10 @@ public class ExportProcessDialog {
} }
super.runTasks(); super.runTasks();
} }
/** /**
* Override the tasks o it runs through all tasks for each datablock. Usually * Override the tasks so it runs through all tasks for each datablock. Usually
* task groups deal with just one parent datablock but exporters export from * task groups deal with just one parent datablock but exporters export from
* different data blocks. The only way to deal with this is to let the task run * different data blocks. The only way to deal with this is to let the task run
* again and again through all tasks and letting tasks themselves check the * again and again through all tasks and letting tasks themselves check the
@ -431,7 +453,7 @@ public class ExportProcessDialog {
} }
} }

View File

@ -46,17 +46,18 @@ public class ExportTask extends OfflineTask<PamDataUnit<?,?>>{
@Override @Override
public boolean processDataUnit(PamDataUnit<?, ?> dataUnit) { public boolean processDataUnit(PamDataUnit<?, ?> dataUnit) {
// System.out.println("Huh? " + this.getDataBlock().getDataName() + " " + dataUnit + " " + dataUnit.getParentDataBlock().equals(this.getDataBlock())); //System.out.println("Huh? " + this.getDataBlock().getDataName() + " " + dataUnit + " " + dataUnit.getParentDataBlock().equals(this.getDataBlock()));
if (dataUnit.getParentDataBlock().equals(this.getDataBlock())) { if (dataUnit.getParentDataBlock().equals(this.getDataBlock())) {
//this is very important because the way the exporter works is that it iterates through multiple parent data blocks //this is very important because the way the exporter works is that it iterates through multiple parent data blocks
System.out.println(this.getDataBlock().getDataName() + " " + dataUnit + " " + dataSelector.scoreData(dataUnit)); //System.out.println(this.getDataBlock().getDataName() + " " + dataUnit + " " + dataSelector.scoreData(dataUnit));
if (dataSelector==null) { if (dataSelector==null) {
// System.out.println("Data selector null: " + this.getDataBlock().getDataName() + " " + dataUnit); //System.out.println("Data selector null: " + this.getDataBlock().getDataName() + " " + dataUnit);
exporter.exportDataUnit(dataUnit, false); exporter.exportDataUnit(dataUnit, false);
} }
else if (dataSelector.scoreData(dataUnit)>=0 || dataSelector.getParams().getCombinationFlag() == DataSelectParams.DATA_SELECT_DISABLE) { else if (dataSelector.scoreData(dataUnit)>0 && dataSelector.getParams().getCombinationFlag() != DataSelectParams.DATA_SELECT_DISABLE) {
// System.out.println("Data selector OK: " + this.getDataBlock().getDataName() + " " + dataUnit); //System.out.println("Data selector OK: " + this.getDataBlock().getDataName() + " " + dataUnit);
exporter.exportDataUnit(dataUnit, false); exporter.exportDataUnit(dataUnit, false);
} }
} }

View File

@ -0,0 +1,32 @@
package export.wavExport;
import java.io.Serializable;
/**
* Options for exporting wav files
*/
public class WavExportOptions implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
/**
* Save detections as zero padded.
*/
public static final int SAVEWAV_ZERO_PAD = 0;
/**
* Save detections as concatenated.
*/
public static final int SAVEWAV_CONCAT = 1;
/**
* Save detections as individual wav files.
*/
public static final int SAVEWAV_INDIVIDUAL = 2;
/**
* Flag to indicuate how to save files
*/
public int wavSaveChoice = SAVEWAV_CONCAT;
}

View File

@ -1,5 +1,6 @@
package export.wavExport; package export.wavExport;
import java.awt.Component;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -19,15 +20,24 @@ import PamguardMVC.PamObservable;
import PamguardMVC.PamObserver; import PamguardMVC.PamObserver;
import PamguardMVC.PamObserverAdapter; import PamguardMVC.PamObserverAdapter;
import PamguardMVC.PamRawDataBlock; import PamguardMVC.PamRawDataBlock;
import PamguardMVC.RawDataHolder;
import PamguardMVC.dataOffline.OfflineDataLoading; import PamguardMVC.dataOffline.OfflineDataLoading;
import dataMap.OfflineDataMapPoint; import dataMap.OfflineDataMapPoint;
import detectiongrouplocaliser.DetectionGroupSummary; import detectiongrouplocaliser.DetectionGroupSummary;
import export.PamDataUnitExporter; import export.PamDataUnitExporter;
import javafx.scene.layout.Pane;
import wavFiles.Wav16AudioFormat; import wavFiles.Wav16AudioFormat;
import wavFiles.WavFileWriter; import wavFiles.WavFileWriter;
/** /**
* Manages .wav file writing based on what type of data unit is selected and whether raw data is available. * Manages .wav file writing based on what type of data unit is selected and whether raw data is available.
* <p>
* There are two primary use cases;
* <br>
* 1) Order raw data from an overlay mark and save as a wav file
* <br>
* 2) Save a list of data units to wav files - either a single file with zero pads, a concatonated file or seperate files.
*
* @author Jamie Macaulay * @author Jamie Macaulay
* *
*/ */
@ -64,12 +74,15 @@ public class WavFileExportManager implements PamDataUnitExporter {
private ArrayList<WavDataUnitExport> wavDataUnitExports = new ArrayList<WavDataUnitExport>(); private ArrayList<WavDataUnitExport> wavDataUnitExports = new ArrayList<WavDataUnitExport>();
private WavSaveCallback saveCallback; private WavSaveCallback saveCallback;
private WavExportOptions wavFileoptions = new WavExportOptions();
private WavOptionsPanel wavOptionsPanel;
public WavFileExportManager() { public WavFileExportManager() {
wavDataUnitExports.add(new RawHolderWavExport()); wavDataUnitExports.add(new RawHolderWavExport());
defaultPath=FileSystemView.getFileSystemView().getDefaultDirectory().getPath(); defaultPath=FileSystemView.getFileSystemView().getDefaultDirectory().getPath();
defaultPath=defaultPath + File.separator + "Pamguard Manual Export"; defaultPath=defaultPath + File.separator + "Pamguard Manual Export";
@ -153,10 +166,18 @@ public class WavFileExportManager implements PamDataUnitExporter {
} }
/** /**
* Convert the mark/dataunits to a .wav file. * Convert the mark/dataunits to a .wav file. makes a decision as to what to
* @param foundDataUnits - found data units. * save
* @param selectedIndex - the currently selected data unit. *
* @param mark - overlay mark. * 1) Data units with no raw data in which case we want to export a wav clip
* from raw data <br> 2) Data units which all have raw data in which case we want to
* export data unit clips as a zero padded wav file (this counts for a single
* data unit too) <b> 3) Mixed data units in which case we want to export a wav clip
* from raw data.
*
* @param foundDataUnits - found data units.
* @param selectedIndex - the currently selected data unit.
* @param mark - overlay mark.
*/ */
public int dataUnits2Wav(DetectionGroupSummary foundDataUnits, int selectedIndex, OverlayMark mark) { public int dataUnits2Wav(DetectionGroupSummary foundDataUnits, int selectedIndex, OverlayMark mark) {
System.out.println("Data units 2 wav"); System.out.println("Data units 2 wav");
@ -219,6 +240,7 @@ public class WavFileExportManager implements PamDataUnitExporter {
/** /**
* Save a clip of wav data from a pre existing .wav or other audio file within in PG. * Save a clip of wav data from a pre existing .wav or other audio file within in PG.
*
* @param start - the start of the wav file. * @param start - the start of the wav file.
* @param end - the end of the wac file. * @param end - the end of the wac file.
*/ */
@ -237,6 +259,166 @@ public class WavFileExportManager implements PamDataUnitExporter {
return 0; return 0;
} }
/**
* Save wav data from a data unit instead of from the raw file store.
* @param foundDataUnits - the list of found data units.
* @return the number of data units that were saved.
*/
private int saveDataUnitWav(DetectionGroupSummary foundDataUnits) {
return saveDataUnitWav(foundDataUnits.getDataList());
}
/**
* Save data units which contain raw data to a wav file. Note that this assumed
* the data units all contain raw data and are in order.
*
* @param foundDataUnits - data units containing raw data.
* @return the number of data units saved - this should be the same as the size
* of the data unit list.
*/
private int saveDataUnitWav(List<PamDataUnit> foundDataUnits) {
int n=0;
WavFileWriter wavWrite = null;
for (PamDataUnit fnDataUnit: foundDataUnits){
String currentFile = createFileName(fnDataUnit.getTimeMilliseconds());
AudioFormat audioFormat = new Wav16AudioFormat(fnDataUnit.getParentDataBlock().getSampleRate(), PamUtils.getNumChannels(fnDataUnit.getChannelBitmap()));
System.out.println("Save detection wav." + foundDataUnits.size());
for (int i=0; i<wavDataUnitExports.size(); i++) {
if (wavDataUnitExports.get(i).getUnitClass().isAssignableFrom(fnDataUnit.getClass())) {
wavWrite= new WavFileWriter(currentFile, audioFormat);
System.out.println("Append wav." + foundDataUnits.size());
//save the wav file of detection
wavWrite.append(wavDataUnitExports.get(i).getWavClip(fnDataUnit));
n++;
wavWrite.close();
break;
}
}
}
//send a message that the wav file has saved
if (wavWrite!=null && saveCallback!=null) saveCallback.wavSaved(wavWrite.getFileName(), 0);
return n;
}
/**
* Save wav data from a data unit instead of from the raw file store.
* @param foundDataUnits - the list of found data units.
* @return
*/
private int getNWavDataUnits(DetectionGroupSummary foundDataUnits) {
int n=0;
for (PamDataUnit fnDataUnit: foundDataUnits.getDataList()){
//System.out.println("Save detection wav." + foundDataUnits.getNumDataUnits());
for (int i=0; i<wavDataUnitExports.size(); i++) {
if (wavDataUnitExports.get(i).getUnitClass().isAssignableFrom(fnDataUnit.getClass())) {
n++;
break;
}
}
}
return n;
}
/**
* Set a callback for saving .wav data.
* @param saveCallback - the callback
*/
public void setOnWavSaved(WavSaveCallback saveCallback) {
this.saveCallback=saveCallback;
}
@Override
public boolean hasCompatibleUnits(Class dataUnitType) {
// boolean implementsInterface = Arrays.stream(dataUnitType.getInterfaces()).anyMatch(i -> i == RawDataHolder.class);
if ( RawDataHolder.class.isAssignableFrom(dataUnitType)) return true;
return false;
}
@Override
public boolean exportData(File fileName,
List<PamDataUnit> dataUnits, boolean append) {
//should we zeropad?
saveDataUnitWav(dataUnits);
return true;
}
@Override
public String getFileExtension() {
return "wav";
}
@Override
public String getIconString() {
return "mdi2f-file-music";
}
@Override
public String getName() {
return "raw sound";
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public boolean isNeedsNewFile() {
return false;
}
@Override
public Component getOptionsPanel() {
if (this.wavOptionsPanel==null) {
this.wavOptionsPanel = new WavOptionsPanel();
}
return wavOptionsPanel;
}
@Override
public Pane getOptionsPane() {
// TODO Auto-generated method stub
return null;
}
/** /**
* Observes incoming raw data and saves to a wav file * Observes incoming raw data and saves to a wav file
* *
@ -346,134 +528,6 @@ public class WavFileExportManager implements PamDataUnitExporter {
} }
/**
* Save wav data from a data unit instead of from the raw file store.
* @param foundDataUnits - the list of found data units.
* @return
*/
private int saveDataUnitWav(DetectionGroupSummary foundDataUnits) {
//TODO - need to pad the detections...with zeros.
//System.out.println("Save data unit wav: " + foundDataUnits.getNumDataUnits());
int n=0;
WavFileWriter wavWrite = null;
for (PamDataUnit fnDataUnit: foundDataUnits.getDataList()){
String currentFile = createFileName(fnDataUnit.getTimeMilliseconds());
AudioFormat audioFormat = new Wav16AudioFormat(fnDataUnit.getParentDataBlock().getSampleRate(), PamUtils.getNumChannels(fnDataUnit.getChannelBitmap()));
System.out.println("Save detection wav." + foundDataUnits.getNumDataUnits());
for (int i=0; i<wavDataUnitExports.size(); i++) {
if (wavDataUnitExports.get(i).getUnitClass().isAssignableFrom(fnDataUnit.getClass())) {
wavWrite= new WavFileWriter(currentFile, audioFormat);
System.out.println("Append wav." + foundDataUnits.getNumDataUnits());
//save the wav file of detection
wavWrite.append(wavDataUnitExports.get(i).getWavClip(fnDataUnit));
n++;
wavWrite.close();
break;
}
}
}
if (wavWrite!=null && saveCallback!=null) saveCallback.wavSaved(wavWrite.getFileName(), 0);
return n;
}
/**
* Save wav data from a data unit instead of from the raw file store.
* @param foundDataUnits - the list of found data units.
* @return
*/
private int getNWavDataUnits(DetectionGroupSummary foundDataUnits) {
int n=0;
for (PamDataUnit fnDataUnit: foundDataUnits.getDataList()){
//System.out.println("Save detection wav." + foundDataUnits.getNumDataUnits());
for (int i=0; i<wavDataUnitExports.size(); i++) {
if (wavDataUnitExports.get(i).getUnitClass().isAssignableFrom(fnDataUnit.getClass())) {
n++;
break;
}
}
}
return n;
}
/**
* Set a callback for saving .wav data.
* @param saveCallback - the callback
*/
public void setOnWavSaved(WavSaveCallback saveCallback) {
this.saveCallback=saveCallback;
}
@Override
public boolean hasCompatibleUnits(Class dataUnitType) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean exportData(File fileName,
List<PamDataUnit> dataUnits, boolean append) {
// TODO Auto-generated method stub
return false;
}
@Override
public String getFileExtension() {
return "wav";
}
@Override
public String getIconString() {
// TODO Auto-generated method stub
return "mdi2f-file-music";
}
@Override
public String getName() {
return "raw sound";
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public boolean isNeedsNewFile() {
return false;
}
// hello(){ // hello(){
// //
// //

View File

@ -0,0 +1,106 @@
package export.wavExport;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import PamView.dialog.PamGridBagContraints;
import PamView.panel.PamPanel;
/**
*
*/
public class WavOptionsPanel extends PamPanel {
private static final long serialVersionUID = 1L;
private JRadioButton zeroPad;
private JRadioButton noZeroPad;
private JRadioButton indvidualWav;
public WavOptionsPanel() {
super();
GridBagConstraints c = new PamGridBagContraints();
c.gridwidth = 1;
c.gridx = 0;
c.gridy = 0;
this.setLayout((new GridBagLayout()));
addComponent(this, zeroPad = new JRadioButton("Concat"), c);
c.gridx++;
addComponent(this, noZeroPad = new JRadioButton("Zero pad"), c);
c.gridx++;
addComponent(this, indvidualWav = new JRadioButton("Individual"), c);
c.gridx++;
addComponent(this, new JLabel(" wav"), c);
// Initialization of object of "ButtonGroup" class.
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(zeroPad);
buttonGroup.add(noZeroPad);
buttonGroup.add(indvidualWav);
noZeroPad.setToolTipText(
"<html>"
+ "Concatonate detections within wav files. If selected, then the wav files are concatenated"
+ "<br>"
+ "and a seperate text file encodes the detection times - this saves a lot of storage space!"
+ "</html>");
zeroPad.setToolTipText(
"<html>"
+ "Zero pad wav files. If selected, then the wav files are zero padding between detections "
+ "<br>"
+ "so they appear at the right time - this can be very storage space intensive. "
+ "</html>");
indvidualWav.setToolTipText(
"<html>"
+ "Save each detection as an individual time stamped wav file"
+ "</html>");
}
public void setParams(WavExportOptions wavExportOptions) {
switch (wavExportOptions.wavSaveChoice) {
case WavExportOptions.SAVEWAV_CONCAT:
noZeroPad.setSelected(true);
break;
case WavExportOptions.SAVEWAV_ZERO_PAD:
zeroPad.setSelected(true);
break;
case WavExportOptions.SAVEWAV_INDIVIDUAL:
indvidualWav.setSelected(true);
break;
}
}
public WavExportOptions getParams(WavExportOptions wavExportOptions) {
if (zeroPad.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
if (noZeroPad.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
if (indvidualWav.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
return wavExportOptions;
}
}