Variable sound output level (#39)

Mods to SoundPlayback module to allow additional parameters. Implemented
system for NI cards to allow changes to selected output voltage range
meaning output can be boosted to level higher than current default.
This commit is contained in:
Douglas Gillespie 2022-07-12 15:53:07 +01:00 committed by GitHub
parent b916209f4f
commit 9fdd30556b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 240 additions and 4 deletions

View File

@ -16,6 +16,7 @@ import com.synthbot.jasiohost.AsioSampleType;
import PamController.PamController; import PamController.PamController;
import PamDetection.RawDataUnit; import PamDetection.RawDataUnit;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import PamView.dialog.PamDialogPanel;
import PamguardMVC.PamConstants; import PamguardMVC.PamConstants;
import soundPlayback.FilePlayback; import soundPlayback.FilePlayback;
import soundPlayback.FilePlaybackDevice; import soundPlayback.FilePlaybackDevice;
@ -334,4 +335,10 @@ public class ASIOFilePlaybackSystem implements FilePlaybackDevice {
return null; return null;
} }
@Override
public PamDialogPanel getSettingsPanel() {
// TODO Auto-generated method stub
return null;
}
} }

View File

@ -1,10 +1,15 @@
package nidaqdev; package nidaqdev;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import PamController.PamControlledUnitSettings;
import PamController.PamSettingManager;
import PamController.PamSettings;
import PamDetection.RawDataUnit; import PamDetection.RawDataUnit;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import PamView.dialog.PamDialogPanel;
import soundPlayback.FilePlayback; import soundPlayback.FilePlayback;
import soundPlayback.FilePlaybackDevice; import soundPlayback.FilePlaybackDevice;
import soundPlayback.PlayDeviceState; import soundPlayback.PlayDeviceState;
@ -17,7 +22,7 @@ import soundPlayback.PlaybackParameters;
* @author Doug Gillespie * @author Doug Gillespie
* *
*/ */
public class NIFilePlayback implements FilePlaybackDevice { public class NIFilePlayback implements FilePlaybackDevice, PamSettings {
private volatile boolean prepared; private volatile boolean prepared;
@ -39,9 +44,14 @@ public class NIFilePlayback implements FilePlaybackDevice {
private NIDeviceInfo currentDeviceInfo; private NIDeviceInfo currentDeviceInfo;
private NIPlaybackSettingsPanel playSettingsPanel;
private NIFilePlaybackParams niFilePlaybackParams = new NIFilePlaybackParams();
public NIFilePlayback(FilePlayback filePlayback) { public NIFilePlayback(FilePlayback filePlayback) {
super(); super();
this.filePlayback = filePlayback; this.filePlayback = filePlayback;
PamSettingManager.getInstance().registerSettings(this);
niDaq = new Nidaq(); niDaq = new Nidaq();
getNIDevices(); getNIDevices();
} }
@ -131,7 +141,7 @@ public class NIFilePlayback implements FilePlaybackDevice {
} }
int playRate = (int) playbackParameters.getPlaybackRate(); int playRate = (int) playbackParameters.getPlaybackRate();
int ans = niDaq.javaPreparePlayback(bn, playRate, playRate, outchans); int ans = niDaq.javaPreparePlayback(bn, playRate, playRate, outchans, (float) niFilePlaybackParams.outputRange);
// System.out.println("NI Answer = " + ans); // System.out.println("NI Answer = " + ans);
prepared = (ans == 0); prepared = (ans == 0);
return prepared; return prepared;
@ -163,4 +173,59 @@ public class NIFilePlayback implements FilePlaybackDevice {
} }
} }
@Override
public PamDialogPanel getSettingsPanel() {
if (playSettingsPanel == null) {
playSettingsPanel = new NIPlaybackSettingsPanel(this);
}
return playSettingsPanel;
}
/**
* @return the niFilePlaybackParams
*/
public NIFilePlaybackParams getNiFilePlaybackParams() {
return niFilePlaybackParams;
}
/**
* @param niFilePlaybackParams the niFilePlaybackParams to set
*/
public void setNiFilePlaybackParams(NIFilePlaybackParams niFilePlaybackParams) {
this.niFilePlaybackParams = niFilePlaybackParams;
}
@Override
public String getUnitName() {
return "NIFilePalybackSettings";
}
@Override
public String getUnitType() {
return "NIFilePalybackSettings";
}
@Override
public Serializable getSettingsReference() {
return niFilePlaybackParams;
}
@Override
public long getSettingsVersion() {
return NIFilePlaybackParams.serialVersionUID;
}
@Override
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
niFilePlaybackParams = (NIFilePlaybackParams) pamControlledUnitSettings.getSettings();
return true;
}
/**
* @return the currentDeviceInfo
*/
public NIDeviceInfo getCurrentDeviceInfo() {
return currentDeviceInfo;
}
} }

View File

@ -0,0 +1,21 @@
package nidaqdev;
import java.io.Serializable;
public class NIFilePlaybackParams implements Serializable, Cloneable{
public static final long serialVersionUID = 1L;
public double outputRange = 2.0;
@Override
protected NIFilePlaybackParams clone() {
try {
return (NIFilePlaybackParams) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,83 @@
package nidaqdev;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import PamView.dialog.PamDialog;
import PamView.dialog.PamDialogPanel;
import PamView.dialog.PamGridBagContraints;
public class NIPlaybackSettingsPanel implements PamDialogPanel {
private NIFilePlayback niFilePlayback;
private JPanel mainPanel;
private JComboBox<String> outputLevel;
public NIPlaybackSettingsPanel(NIFilePlayback niFilePlayback) {
this.niFilePlayback = niFilePlayback;
mainPanel = new JPanel(new GridBagLayout());
mainPanel.setBorder(new TitledBorder("NI Play options"));
GridBagConstraints c = new PamGridBagContraints();
mainPanel.add(new JLabel("Output level ", JLabel.RIGHT), c);
c.gridx++;
mainPanel.add(outputLevel = new JComboBox<>(), c);
c.gridx++;
mainPanel.add(new JLabel(" V(0-p)"), c);
outputLevel.addItem("1.0");
outputLevel.addItem("10.0");
}
@Override
public JComponent getDialogComponent() {
return mainPanel;
}
@Override
public void setParams() {
NIDeviceInfo deviceInfo = niFilePlayback.getCurrentDeviceInfo();
NIFilePlaybackParams params = niFilePlayback.getNiFilePlaybackParams();
if (deviceInfo == null) {
return;
}
int nRange = deviceInfo.getNumAOVoltageRanges();
outputLevel.removeAllItems();
int selInd = -1;
for (int i = 0; i < nRange; i++) {
double aRange = deviceInfo.getAOVoltageRangeEnd(i);
outputLevel.addItem(String.format("%3.1f", aRange));
if (aRange == params.outputRange) {
selInd = i;
}
}
if (selInd >= 0) {
outputLevel.setSelectedIndex(selInd);
}
}
@Override
public boolean getParams() {
NIDeviceInfo deviceInfo = niFilePlayback.getCurrentDeviceInfo();
NIFilePlaybackParams params = niFilePlayback.getNiFilePlaybackParams();
if (deviceInfo == null) {
return false;
}
int nRange = deviceInfo.getNumAOVoltageRanges();
int selInd = outputLevel.getSelectedIndex();
if (selInd < 0 || selInd >= nRange) {
return PamDialog.showWarning(null, "Invalid parameter", "Invalid output range");
}
params.outputRange = deviceInfo.getAOVoltageRangeEnd(selInd);
return true;
}
}

View File

@ -253,8 +253,20 @@ public class Nidaq {
public int javaPreparePlayback(int boardNumber, int sampleRate, public int javaPreparePlayback(int boardNumber, int sampleRate,
int bufferSamples, int[] outputChannelList) { int bufferSamples, int[] outputChannelList) {
// if (loadLibraryOK) {
// return jniPreparePlayback(boardNumber, sampleRate, playVoltageRange, bufferSamples, outputChannelList);
// }
// else {
// return 0;
// }
return javaPreparePlayback(boardNumber, sampleRate, bufferSamples, outputChannelList, playVoltageRange);
}
public int javaPreparePlayback(int boardNumber, int sampleRate,
int bufferSamples, int[] outputChannelList, float outputLevel) {
if (loadLibraryOK) { if (loadLibraryOK) {
return jniPreparePlayback(boardNumber, sampleRate, playVoltageRange, bufferSamples, outputChannelList); outputLevel = Math.abs(outputLevel);
return jniPreparePlayback(boardNumber, sampleRate, outputLevel, bufferSamples, outputChannelList);
} }
else { else {
return 0; return 0;

View File

@ -1,6 +1,7 @@
package soundPlayback; package soundPlayback;
import PamDetection.RawDataUnit; import PamDetection.RawDataUnit;
import PamView.dialog.PamDialogPanel;
/** /**
* Interface to device types that can be used to play * Interface to device types that can be used to play
@ -67,4 +68,10 @@ public interface FilePlaybackDevice {
public String getDeviceName(); public String getDeviceName();
/**
* Get a settings panel for additional options. Can be null.
* @return settings panel or null for additional options.
*/
public PamDialogPanel getSettingsPanel();
} }

View File

@ -15,6 +15,7 @@ import Acquisition.SoundCardSystem;
import PamDetection.RawDataUnit; import PamDetection.RawDataUnit;
import PamUtils.PamCalendar; import PamUtils.PamCalendar;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import PamView.dialog.PamDialogPanel;
import warnings.PamWarning; import warnings.PamWarning;
import warnings.WarningSystem; import warnings.WarningSystem;
@ -89,4 +90,10 @@ public class SoundCardFilePlayback implements FilePlaybackDevice {
return soundCardPlaybackBase.getDeviceState(); return soundCardPlaybackBase.getDeviceState();
} }
@Override
public PamDialogPanel getSettingsPanel() {
// TODO Auto-generated method stub
return null;
}
} }

View File

@ -20,8 +20,11 @@ import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import PamView.dialog.GenericSwingDialog;
import PamView.dialog.PamDialog; import PamView.dialog.PamDialog;
import PamView.dialog.PamDialogPanel;
import PamView.dialog.PamGridBagContraints; import PamView.dialog.PamGridBagContraints;
import PamView.dialog.SettingsButton;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.PamRawDataBlock; import PamguardMVC.PamRawDataBlock;
import soundPlayback.FilePlayback; import soundPlayback.FilePlayback;
@ -48,6 +51,8 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
private FilePlayback filePlayback; private FilePlayback filePlayback;
private PlaybackParameters playbackParameters; private PlaybackParameters playbackParameters;
private SettingsButton deviceSettingsButton;
private JButton defButton; private JButton defButton;
@ -57,6 +62,8 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
private PamDataBlock dataSource; private PamDataBlock dataSource;
private FilePlaybackDevice selectedDeviceType;
/** /**
* Dialog component for sound playback when input is from a file. * Dialog component for sound playback when input is from a file.
* <p> * <p>
@ -91,10 +98,23 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
c.gridy++; c.gridy++;
PamDialog.addComponent(panel, deviceTypes, c); PamDialog.addComponent(panel, deviceTypes, c);
c.gridy++; c.gridy++;
c.gridwidth = 3;
PamDialog.addComponent(panel, new JLabel("Output device name ..."), c); PamDialog.addComponent(panel, new JLabel("Output device name ..."), c);
c.gridx += c.gridwidth;
c.gridwidth = 1;
PamDialog.addComponent(panel, deviceSettingsButton = new SettingsButton(), c);
c.gridx = 0;
c.gridwidth = 4;
c.gridy++; c.gridy++;
PamDialog.addComponent(panel, soundCards, c); PamDialog.addComponent(panel, soundCards, c);
deviceSettingsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deviceSettings();
}
});
c.gridy++; c.gridy++;
c.gridx = 0; c.gridx = 0;
c.gridwidth = 1; c.gridwidth = 1;
@ -153,6 +173,17 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
} }
protected void deviceSettings() {
if (selectedDeviceType == null) {
return;
}
PamDialogPanel devicePanel = selectedDeviceType.getSettingsPanel();
if (devicePanel == null) {
return;
}
GenericSwingDialog.showDialog(getParentDialog(), "More Settings", devicePanel);
}
private void playSpeedChange() { private void playSpeedChange() {
playbackSpeed.setText(playSpeedSlider.getRatioString()); playbackSpeed.setText(playSpeedSlider.getRatioString());
sayDecimateInfo(); sayDecimateInfo();
@ -280,6 +311,9 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
if (parentDialog != null) { if (parentDialog != null) {
parentDialog.pack(); parentDialog.pack();
} }
if (selectedDeviceType != null) {
deviceSettingsButton.setEnabled(selectedDeviceType.getSettingsPanel() != null);
}
} }
} }
@ -297,7 +331,7 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
public void fillDeviceSpecificList() { public void fillDeviceSpecificList() {
int deviceType = deviceTypes.getSelectedIndex(); int deviceType = deviceTypes.getSelectedIndex();
deviceType = Math.max(0, deviceType); deviceType = Math.max(0, deviceType);
FilePlaybackDevice selectedDeviceType = filePlayback.getFilePBDevices().get(deviceType); selectedDeviceType = filePlayback.getFilePBDevices().get(deviceType);
soundCards.removeAllItems(); soundCards.removeAllItems();
String[] devList = selectedDeviceType.getDeviceNames(); String[] devList = selectedDeviceType.getDeviceNames();
for (int i = 0; i < devList.length; i++) { for (int i = 0; i < devList.length; i++) {