mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-22 07:02:29 +00:00
Change synchronization on RawDataTransforms soit uses the owner data (#26)
holder, not itself for synchronization. Otherwise you get thread locks.
This commit is contained in:
parent
d49d204a8a
commit
f1d0268ec5
@ -99,11 +99,35 @@ public class RawDataTransforms {
|
|||||||
*/
|
*/
|
||||||
private int shortestFFTLength;
|
private int shortestFFTLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object for synchronization. Get thread lock if this isn't the same as
|
||||||
|
* the object holding the data.
|
||||||
|
*/
|
||||||
|
private Object synchObject;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raw Data Transforms for a RawDataHolder using the rawDataHolder as the synchronization
|
||||||
|
* object.
|
||||||
|
* @param rawDataHolder RawDataHolder object (e.g. a click)
|
||||||
|
*/
|
||||||
public RawDataTransforms(@SuppressWarnings("rawtypes") PamDataUnit rawDataHolder) {
|
public RawDataTransforms(@SuppressWarnings("rawtypes") PamDataUnit rawDataHolder) {
|
||||||
|
this(rawDataHolder, rawDataHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raw Data Transforms for a RawDataHolder.
|
||||||
|
* @param rawDataHolder RawDataHolder object (e.g. a click)
|
||||||
|
* @param synchObject synchronization object, which is most likely the RawDataHolder object.
|
||||||
|
*/
|
||||||
|
public RawDataTransforms(@SuppressWarnings("rawtypes") PamDataUnit rawDataHolder, Object synchObject) {
|
||||||
this.rawData=(RawDataHolder) rawDataHolder;
|
this.rawData=(RawDataHolder) rawDataHolder;
|
||||||
this.dataUnit = rawDataHolder;
|
this.dataUnit = rawDataHolder;
|
||||||
|
this.synchObject = synchObject;
|
||||||
|
if (this.synchObject == null) {
|
||||||
|
this.synchObject = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -143,23 +167,25 @@ public class RawDataTransforms {
|
|||||||
* @param fftLength
|
* @param fftLength
|
||||||
* @return Power spectrum
|
* @return Power spectrum
|
||||||
*/
|
*/
|
||||||
public synchronized double[] getPowerSpectrum(int channel, int minBin, int maxBin, int fftLength) {
|
public double[] getPowerSpectrum(int channel, int minBin, int maxBin, int fftLength) {
|
||||||
if (minBin==0 && maxBin>=this.getWaveData(0).length-1) {
|
synchronized (synchObject) {
|
||||||
return getPowerSpectrum(channel, fftLength);
|
if (minBin==0 && maxBin>=this.getWaveData(0).length-1) {
|
||||||
}
|
return getPowerSpectrum(channel, fftLength);
|
||||||
if (fftLength == 0) {
|
}
|
||||||
fftLength = getCurrentSpectrumLength();
|
if (fftLength == 0) {
|
||||||
|
fftLength = getCurrentSpectrumLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
double[] waveformTrim = new double[maxBin-minBin];
|
||||||
|
|
||||||
|
// System.out.println("minBin: " + minBin + " maxBin: " + maxBin + " raw waveform: " + this.getWaveData(channel).length);
|
||||||
|
|
||||||
|
System.arraycopy(this.getWaveData(channel), minBin, waveformTrim, 0, Math.min(this.getWaveData(channel).length-minBin-1, waveformTrim.length));
|
||||||
|
|
||||||
|
ComplexArray cData = getComplexSpectrumHann(waveformTrim, fftLength);
|
||||||
|
|
||||||
|
return cData.magsq();
|
||||||
}
|
}
|
||||||
|
|
||||||
double[] waveformTrim = new double[maxBin-minBin];
|
|
||||||
|
|
||||||
// System.out.println("minBin: " + minBin + " maxBin: " + maxBin + " raw waveform: " + this.getWaveData(channel).length);
|
|
||||||
|
|
||||||
System.arraycopy(this.getWaveData(channel), minBin, waveformTrim, 0, Math.min(this.getWaveData(channel).length-minBin-1, waveformTrim.length));
|
|
||||||
|
|
||||||
ComplexArray cData = getComplexSpectrumHann(waveformTrim, fftLength);
|
|
||||||
|
|
||||||
return cData.magsq();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,29 +196,31 @@ public class RawDataTransforms {
|
|||||||
* @param fftLength
|
* @param fftLength
|
||||||
* @return Power spectrum
|
* @return Power spectrum
|
||||||
*/
|
*/
|
||||||
public synchronized double[] getPowerSpectrum(int channel, int fftLength) {
|
public double[] getPowerSpectrum(int channel, int fftLength) {
|
||||||
if (powerSpectra == null) {
|
synchronized (synchObject) {
|
||||||
powerSpectra = new double[PamUtils.getNumChannels(dataUnit.getChannelBitmap())][];
|
if (powerSpectra == null) {
|
||||||
}
|
powerSpectra = new double[PamUtils.getNumChannels(dataUnit.getChannelBitmap())][];
|
||||||
if (fftLength == 0) {
|
|
||||||
fftLength = getCurrentSpectrumLength();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (powerSpectra[channel] == null
|
|
||||||
|| powerSpectra[channel].length != fftLength / 2) {
|
|
||||||
ComplexArray cData = getComplexSpectrumHann(channel, fftLength);
|
|
||||||
currentSpecLen = fftLength;
|
|
||||||
powerSpectra[channel] = cData.magsq();
|
|
||||||
if (powerSpectra==null){
|
|
||||||
System.err.println("DLDetection: could not calculate power spectra");
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (powerSpectra[channel].length != fftLength/2) {
|
if (fftLength == 0) {
|
||||||
powerSpectra[channel] = Arrays.copyOf(powerSpectra[channel], fftLength/2);
|
fftLength = getCurrentSpectrumLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (powerSpectra[channel] == null
|
||||||
|
|| powerSpectra[channel].length != fftLength / 2) {
|
||||||
|
ComplexArray cData = getComplexSpectrumHann(channel, fftLength);
|
||||||
|
currentSpecLen = fftLength;
|
||||||
|
powerSpectra[channel] = cData.magsq();
|
||||||
|
if (powerSpectra==null){
|
||||||
|
System.err.println("DLDetection: could not calculate power spectra");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (powerSpectra[channel].length != fftLength/2) {
|
||||||
|
powerSpectra[channel] = Arrays.copyOf(powerSpectra[channel], fftLength/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return powerSpectra[channel];
|
||||||
}
|
}
|
||||||
return powerSpectra[channel];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -202,25 +230,27 @@ public class RawDataTransforms {
|
|||||||
* @param fftLength
|
* @param fftLength
|
||||||
* @return Sum of power spectra
|
* @return Sum of power spectra
|
||||||
*/
|
*/
|
||||||
public synchronized double[] getTotalPowerSpectrum(int fftLength) {
|
public double[] getTotalPowerSpectrum(int fftLength) {
|
||||||
if (fftLength == 0) {
|
synchronized (synchObject) {
|
||||||
fftLength = getCurrentSpectrumLength();
|
if (fftLength == 0) {
|
||||||
}
|
fftLength = getCurrentSpectrumLength();
|
||||||
if (fftLength == 0) {
|
}
|
||||||
fftLength = PamUtils.getMinFftLength(getSampleDuration());
|
if (fftLength == 0) {
|
||||||
}
|
fftLength = PamUtils.getMinFftLength(getSampleDuration());
|
||||||
double[] ps;
|
}
|
||||||
if (totalPowerSpectrum == null
|
double[] ps;
|
||||||
|| totalPowerSpectrum.length != fftLength / 2) {
|
if (totalPowerSpectrum == null
|
||||||
totalPowerSpectrum = new double[fftLength / 2];
|
|| totalPowerSpectrum.length != fftLength / 2) {
|
||||||
for (int c = 0; c < PamUtils.getNumChannels(this.dataUnit.getChannelBitmap()); c++) {
|
totalPowerSpectrum = new double[fftLength / 2];
|
||||||
ps = getPowerSpectrum(c, fftLength);
|
for (int c = 0; c < PamUtils.getNumChannels(this.dataUnit.getChannelBitmap()); c++) {
|
||||||
for (int i = 0; i < fftLength / 2; i++) {
|
ps = getPowerSpectrum(c, fftLength);
|
||||||
totalPowerSpectrum[i] += ps[i];
|
for (int i = 0; i < fftLength / 2; i++) {
|
||||||
|
totalPowerSpectrum[i] += ps[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return totalPowerSpectrum;
|
||||||
}
|
}
|
||||||
return totalPowerSpectrum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -235,15 +265,17 @@ public class RawDataTransforms {
|
|||||||
* @param fftLength - the FFT length to use.
|
* @param fftLength - the FFT length to use.
|
||||||
* @return the complex spectrum - the comnplex spectrum of the wave data from the specified channel.
|
* @return the complex spectrum - the comnplex spectrum of the wave data from the specified channel.
|
||||||
*/
|
*/
|
||||||
public synchronized ComplexArray getComplexSpectrumHann(int channel, int fftLength) {
|
public ComplexArray getComplexSpectrumHann(int channel, int fftLength) {
|
||||||
complexSpectrum = new ComplexArray[PamUtils.getNumChannels(dataUnit.getChannelBitmap())];
|
synchronized (synchObject) {
|
||||||
if (complexSpectrum[channel] == null
|
complexSpectrum = new ComplexArray[PamUtils.getNumChannels(dataUnit.getChannelBitmap())];
|
||||||
|| complexSpectrum.length != fftLength / 2) {
|
if (complexSpectrum[channel] == null
|
||||||
|
|| complexSpectrum.length != fftLength / 2) {
|
||||||
|
|
||||||
complexSpectrum[channel] = getComplexSpectrumHann(rawData.getWaveData()[channel], fftLength);
|
complexSpectrum[channel] = getComplexSpectrumHann(rawData.getWaveData()[channel], fftLength);
|
||||||
currentSpecLen = fftLength;
|
currentSpecLen = fftLength;
|
||||||
|
}
|
||||||
|
return complexSpectrum[channel];
|
||||||
}
|
}
|
||||||
return complexSpectrum[channel];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -282,10 +314,12 @@ public class RawDataTransforms {
|
|||||||
* @return the spectrogram length.
|
* @return the spectrogram length.
|
||||||
*/
|
*/
|
||||||
private int getCurrentSpectrumLength() {
|
private int getCurrentSpectrumLength() {
|
||||||
if (currentSpecLen<=0) {
|
synchronized (synchObject) {
|
||||||
currentSpecLen = PamUtils.getMinFftLength(dataUnit.getSampleDuration());
|
if (currentSpecLen<=0) {
|
||||||
|
currentSpecLen = PamUtils.getMinFftLength(dataUnit.getSampleDuration());
|
||||||
|
}
|
||||||
|
return currentSpecLen;
|
||||||
}
|
}
|
||||||
return currentSpecLen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -371,29 +405,31 @@ public class RawDataTransforms {
|
|||||||
* @param fftLength
|
* @param fftLength
|
||||||
* @return the complex spectrum
|
* @return the complex spectrum
|
||||||
*/
|
*/
|
||||||
public synchronized ComplexArray getComplexSpectrum(int channel, int fftLength) {
|
public ComplexArray getComplexSpectrum(int channel, int fftLength) {
|
||||||
double[] paddedRawData;
|
synchronized (synchObject) {
|
||||||
double[] rawData;
|
double[] paddedRawData;
|
||||||
int i, mn;
|
double[] rawData;
|
||||||
|
int i, mn;
|
||||||
|
|
||||||
if (complexSpectrum == null) {
|
if (complexSpectrum == null) {
|
||||||
complexSpectrum = new ComplexArray[getNChan()];
|
complexSpectrum = new ComplexArray[getNChan()];
|
||||||
}
|
|
||||||
if (complexSpectrum[channel] == null
|
|
||||||
|| complexSpectrum.length != fftLength / 2) {
|
|
||||||
paddedRawData = new double[fftLength];
|
|
||||||
rawData = getWaveData(channel);
|
|
||||||
//double[] rotData = getRotationCorrection(channel);
|
|
||||||
mn = Math.min(fftLength, getSampleDuration().intValue());
|
|
||||||
for (i = 0; i < mn; i++) {
|
|
||||||
paddedRawData[i] = rawData[i];//-rotData[i];
|
|
||||||
}
|
}
|
||||||
for (i = mn; i < fftLength; i++) {
|
if (complexSpectrum[channel] == null
|
||||||
paddedRawData[i] = 0;
|
|| complexSpectrum.length != fftLength / 2) {
|
||||||
|
paddedRawData = new double[fftLength];
|
||||||
|
rawData = getWaveData(channel);
|
||||||
|
//double[] rotData = getRotationCorrection(channel);
|
||||||
|
mn = Math.min(fftLength, getSampleDuration().intValue());
|
||||||
|
for (i = 0; i < mn; i++) {
|
||||||
|
paddedRawData[i] = rawData[i];//-rotData[i];
|
||||||
|
}
|
||||||
|
for (i = mn; i < fftLength; i++) {
|
||||||
|
paddedRawData[i] = 0;
|
||||||
|
}
|
||||||
|
complexSpectrum[channel] = fastFFT.rfft(paddedRawData, fftLength);
|
||||||
}
|
}
|
||||||
complexSpectrum[channel] = fastFFT.rfft(paddedRawData, fftLength);
|
return complexSpectrum[channel];
|
||||||
}
|
}
|
||||||
return complexSpectrum[channel];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -402,14 +438,16 @@ public class RawDataTransforms {
|
|||||||
* @param iChan channel index
|
* @param iChan channel index
|
||||||
* @return analytic waveform
|
* @return analytic waveform
|
||||||
*/
|
*/
|
||||||
public synchronized double[] getAnalyticWaveform(int iChan) {
|
public double[] getAnalyticWaveform(int iChan) {
|
||||||
if (analyticWaveform == null) {
|
synchronized (synchObject) {
|
||||||
analyticWaveform = new double[getNChan()][];
|
if (analyticWaveform == null) {
|
||||||
|
analyticWaveform = new double[getNChan()][];
|
||||||
|
}
|
||||||
|
// if (analyticWaveform[iChan] == null) {
|
||||||
|
analyticWaveform[iChan] = hilbert.getHilbert(getWaveData(iChan));
|
||||||
|
// }
|
||||||
|
return analyticWaveform[iChan];
|
||||||
}
|
}
|
||||||
// if (analyticWaveform[iChan] == null) {
|
|
||||||
analyticWaveform[iChan] = hilbert.getHilbert(getWaveData(iChan));
|
|
||||||
// }
|
|
||||||
return analyticWaveform[iChan];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -421,12 +459,14 @@ public class RawDataTransforms {
|
|||||||
* @param fftFilterParams fft filter parameters.
|
* @param fftFilterParams fft filter parameters.
|
||||||
* @return analystic waveform.
|
* @return analystic waveform.
|
||||||
*/
|
*/
|
||||||
public synchronized double[] getAnalyticWaveform(int iChan, boolean filtered, FFTFilterParams fftFilterParams) {
|
public double[] getAnalyticWaveform(int iChan, boolean filtered, FFTFilterParams fftFilterParams) {
|
||||||
if (filtered == false || fftFilterParams == null) {
|
synchronized (synchObject) {
|
||||||
return getAnalyticWaveform(iChan);
|
if (filtered == false || fftFilterParams == null) {
|
||||||
}
|
return getAnalyticWaveform(iChan);
|
||||||
else {
|
}
|
||||||
return getFilteredAnalyticWaveform(fftFilterParams, iChan);
|
else {
|
||||||
|
return getFilteredAnalyticWaveform(fftFilterParams, iChan);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,7 +477,8 @@ public class RawDataTransforms {
|
|||||||
* @param iChan channel number
|
* @param iChan channel number
|
||||||
* @return envelope of the filtered data.
|
* @return envelope of the filtered data.
|
||||||
*/
|
*/
|
||||||
public synchronized double[] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams, int iChan) {
|
public double[] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams, int iChan) {
|
||||||
|
synchronized (synchObject) {
|
||||||
if (analyticWaveform == null) {
|
if (analyticWaveform == null) {
|
||||||
analyticWaveform = new double[getNChan()][];
|
analyticWaveform = new double[getNChan()][];
|
||||||
}
|
}
|
||||||
@ -446,6 +487,7 @@ public class RawDataTransforms {
|
|||||||
getHilbert(getFilteredWaveData(fftFilterParams, iChan));
|
getHilbert(getFilteredWaveData(fftFilterParams, iChan));
|
||||||
// }
|
// }
|
||||||
return analyticWaveform[iChan];
|
return analyticWaveform[iChan];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -455,19 +497,21 @@ public class RawDataTransforms {
|
|||||||
* @return analystic waveforms
|
* @return analystic waveforms
|
||||||
*/
|
*/
|
||||||
public double[][] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams) {
|
public double[][] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams) {
|
||||||
if (analyticWaveform == null) {
|
synchronized (synchObject) { // new
|
||||||
analyticWaveform = new double[getNChan()][];
|
if (analyticWaveform == null) {
|
||||||
}
|
analyticWaveform = new double[getNChan()][];
|
||||||
for (int iChan = 0; iChan < getNChan(); iChan++) {
|
|
||||||
if (fftFilterParams != null) {
|
|
||||||
analyticWaveform[iChan] = hilbert.
|
|
||||||
getHilbert(getFilteredWaveData(fftFilterParams, iChan));
|
|
||||||
}
|
}
|
||||||
else {
|
for (int iChan = 0; iChan < getNChan(); iChan++) {
|
||||||
analyticWaveform[iChan] = getAnalyticWaveform(iChan);
|
if (fftFilterParams != null) {
|
||||||
|
analyticWaveform[iChan] = hilbert.
|
||||||
|
getHilbert(getFilteredWaveData(fftFilterParams, iChan));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
analyticWaveform[iChan] = getAnalyticWaveform(iChan);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return analyticWaveform;
|
||||||
}
|
}
|
||||||
return analyticWaveform;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -478,7 +522,7 @@ public class RawDataTransforms {
|
|||||||
* @param channelIndex channel index
|
* @param channelIndex channel index
|
||||||
* @return filtered waveform data
|
* @return filtered waveform data
|
||||||
*/
|
*/
|
||||||
public synchronized double[] getFilteredWaveData(FFTFilterParams filterParams, int channelIndex) {
|
public double[] getFilteredWaveData(FFTFilterParams filterParams, int channelIndex) {
|
||||||
filteredWaveData = getFilteredWaveData(filterParams);
|
filteredWaveData = getFilteredWaveData(filterParams);
|
||||||
return filteredWaveData[channelIndex];
|
return filteredWaveData[channelIndex];
|
||||||
}
|
}
|
||||||
@ -489,12 +533,14 @@ public class RawDataTransforms {
|
|||||||
* @param filterParams filter parameters
|
* @param filterParams filter parameters
|
||||||
* @return array of filtered data
|
* @return array of filtered data
|
||||||
*/
|
*/
|
||||||
public synchronized double[][] getFilteredWaveData(FFTFilterParams filterParams) {
|
public double[][] getFilteredWaveData(FFTFilterParams filterParams) {
|
||||||
|
synchronized (synchObject) {
|
||||||
//System.out.println("Make filterred wave data!: " + (filterParams != oldFFTFilterParams));
|
//System.out.println("Make filterred wave data!: " + (filterParams != oldFFTFilterParams));
|
||||||
if (filteredWaveData == null || filterParams != oldFFTFilterParams) {
|
if (filteredWaveData == null || filterParams != oldFFTFilterParams) {
|
||||||
filteredWaveData = makeFilteredWaveData(filterParams);
|
filteredWaveData = makeFilteredWaveData(filterParams);
|
||||||
}
|
}
|
||||||
return filteredWaveData;
|
return filteredWaveData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -538,13 +584,15 @@ public class RawDataTransforms {
|
|||||||
* @return FFT filter object.
|
* @return FFT filter object.
|
||||||
*/
|
*/
|
||||||
public FFTFilter getFFTFilter(FFTFilterParams fftFilterParams) {
|
public FFTFilter getFFTFilter(FFTFilterParams fftFilterParams) {
|
||||||
if (fftFilter == null) {
|
synchronized (synchObject) {
|
||||||
fftFilter = new FFTFilter(fftFilterParams, this.dataUnit.getParentDataBlock().getSampleRate());
|
if (fftFilter == null) {
|
||||||
|
fftFilter = new FFTFilter(fftFilterParams, this.dataUnit.getParentDataBlock().getSampleRate());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fftFilter.setParams(fftFilterParams, this.dataUnit.getParentDataBlock().getSampleRate());
|
||||||
|
}
|
||||||
|
return fftFilter;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
fftFilter.setParams(fftFilterParams, this.dataUnit.getParentDataBlock().getSampleRate());
|
|
||||||
}
|
|
||||||
return fftFilter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -589,7 +637,9 @@ public class RawDataTransforms {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private int getNChan() {
|
private int getNChan() {
|
||||||
return this.rawData.getWaveData().length;
|
synchronized (synchObject) { // new
|
||||||
|
return this.rawData.getWaveData().length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -622,9 +672,11 @@ public class RawDataTransforms {
|
|||||||
* Free eup some memory by deleting the filtered wave data, power spectra and analytic waveform.
|
* Free eup some memory by deleting the filtered wave data, power spectra and analytic waveform.
|
||||||
*/
|
*/
|
||||||
public void freeMemory() {
|
public void freeMemory() {
|
||||||
filteredWaveData = null;
|
synchronized (synchObject) {
|
||||||
powerSpectra = null;
|
filteredWaveData = null;
|
||||||
analyticWaveform = null;
|
powerSpectra = null;
|
||||||
|
analyticWaveform = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user