Skip to content

Commit

Permalink
Update SonogramTests.cs
Browse files Browse the repository at this point in the history
Issue # 238 Write new test for generating spectrogram image with plots and events annotated. Make other tests more efficient
  • Loading branch information
towsey committed Sep 2, 2019
1 parent 1228b46 commit 1228ff3
Showing 1 changed file with 84 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@

namespace Acoustics.Test.AudioAnalysisTools.StandardSpectrograms
{
using System;
using System.Collections.Generic;
using System.IO;
using Acoustics.Shared;
using DSP;
using Acoustics.Test.AudioAnalysisTools.DSP;
using Acoustics.Test.TestHelpers;
using global::AudioAnalysisTools;
using global::AudioAnalysisTools.DSP;
using global::AudioAnalysisTools.StandardSpectrograms;
using global::AudioAnalysisTools.WavTools;
using global::TowseyLibrary;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestHelpers;

/// <summary>
/// Test methods for the various standard Sonograms or Spectrograms
Expand All @@ -28,6 +31,9 @@ public class SonogramTests
{
private const double AllowedDelta = 0.000001;
private DirectoryInfo outputDirectory;
private AudioRecording recording;
private FrequencyScale freqScale;
private SonogramConfig sonoConfig;

/*
// You can use the following additional attributes as you write your tests:
Expand All @@ -53,12 +59,30 @@ public class SonogramTests
public void Setup()
{
this.outputDirectory = PathHelper.GetTempDir();
this.recording = new AudioRecording(PathHelper.ResolveAsset("Recordings", "BAC2_20071008-085040.wav"));

// specified linear scale
this.freqScale = new FrequencyScale(nyquist: 11025, frameSize: 1024, hertzGridInterval: 1000);

// set up the config for each spectrogram
this.sonoConfig = new SonogramConfig
{
WindowSize = this.freqScale.FinalBinCount * 2,
WindowOverlap = 0.2,
SourceFName = this.recording.BaseName,
NoiseReductionType = NoiseReductionType.None,
NoiseReductionParameter = 0.0,
};
}

[TestCleanup]
public void Cleanup()
{
PathHelper.DeleteTempDir(this.outputDirectory);
this.recording.Dispose();

//this.freqScale.();
//this.sonoConfig.Dispose();
}

/// <summary>
Expand Down Expand Up @@ -88,23 +112,9 @@ public void TestAverageOfDecibelValues()
[TestMethod]
public void TestAmplitudeSonogram()
{
var recording = new AudioRecording(PathHelper.ResolveAsset("Recordings", "BAC2_20071008-085040.wav"));

// specfied linear scale
var freqScale = new FrequencyScale(nyquist: 11025, frameSize: 1024, hertzGridInterval: 1000);

var sonoConfig = new SonogramConfig
{
WindowSize = freqScale.FinalBinCount * 2,
WindowOverlap = 0.2,
SourceFName = recording.BaseName,
NoiseReductionType = NoiseReductionType.None,
NoiseReductionParameter = 0.0,
};

// DO EQUALITY TEST on the AMPLITUDE SONGOGRAM DATA
// Do not bother with the image because this is only an amplitude spectrogram.
var sonogram = new AmplitudeSonogram(sonoConfig, recording.WavReader);
var sonogram = new AmplitudeSonogram(this.sonoConfig, this.recording.WavReader);
var expectedFile = PathHelper.ResolveAsset("StandardSonograms", "BAC2_20071008_AmplSonogramData.EXPECTED.bin");

// run this once to generate expected test data
Expand All @@ -120,23 +130,9 @@ public void TestAmplitudeSonogram()
[TestMethod]
public void TestDecibelSpectrogram()
{
var recording = new AudioRecording(PathHelper.ResolveAsset("Recordings", "BAC2_20071008-085040.wav"));

// specfied linear scale
var freqScale = new FrequencyScale(nyquist: 11025, frameSize: 1024, hertzGridInterval: 1000);

var sonoConfig = new SonogramConfig
{
WindowSize = freqScale.FinalBinCount * 2,
WindowOverlap = 0.2,
SourceFName = recording.BaseName,
NoiseReductionType = NoiseReductionType.None,
NoiseReductionParameter = 0.0,
};

// DO EQUALITY TEST on the AMPLITUDE SONGOGRAM DATA
// Do not bother with the image because this is only an amplitude spectrogram.
var sonogram = new AmplitudeSonogram(sonoConfig, recording.WavReader);
var sonogram = new AmplitudeSonogram(this.sonoConfig, this.recording.WavReader);

// DO FILE EQUALITY TEST on the DECIBEL SONGOGRAM DATA
// Do not bother with the image because this has been tested elsewhere.
Expand All @@ -157,28 +153,69 @@ public void TestDecibelSpectrogram()
[TestMethod]
public void SonogramDecibelMethodsAreEquivalent()
{
var recording = new AudioRecording(PathHelper.ResolveAsset("Recordings", "BAC2_20071008-085040.wav"));
// Method 1
var sonogram = new AmplitudeSonogram(this.sonoConfig, this.recording.WavReader);
var expectedDecibelSonogram = MFCCStuff.DecibelSpectra(sonogram.Data, sonogram.Configuration.WindowPower, sonogram.SampleRate, sonogram.Configuration.epsilon);

// Method 2: make sure that the decibel spectrum is the same no matter which path we take to calculate it.
var actualDecibelSpectrogram = new SpectrogramStandard(this.sonoConfig, this.recording.WavReader);

// specfied linear scale
var freqScale = new FrequencyScale(nyquist: 11025, frameSize: 1024, hertzGridInterval: 1000);
CollectionAssert.That.AreEqual(expectedDecibelSonogram, actualDecibelSpectrogram.Data, EnvelopeAndFftTests.Delta);
}

var sonoConfig = new SonogramConfig
[TestMethod]
public void TestAnnotatedSonogramWithPlots()
{
// Make a decibel spectrogram
var actualDecibelSpectrogram = new SpectrogramStandard(this.sonoConfig, this.recording.WavReader);

// prepare normalisation bounds for three plots
double minDecibels = -100.0;
double maxDecibels = -50;

//double decibelThreshold = 12.5 dB above -100 dB;
var normThreshold = 0.25;

//plot 1
int minHz = 2000;
int maxHz = 3000;
var decibelArray = SNR.CalculateFreqBandAvIntensity(actualDecibelSpectrogram.Data, minHz, maxHz, actualDecibelSpectrogram.NyquistFrequency);
var normalisedIntensityArray = DataTools.NormaliseInZeroOne(decibelArray, minDecibels, maxDecibels);
var plot1 = new Plot("Intensity 2-3 kHz", normalisedIntensityArray, normThreshold);

//plot 2
minHz = 3000;
maxHz = 4000;
decibelArray = SNR.CalculateFreqBandAvIntensity(actualDecibelSpectrogram.Data, minHz, maxHz, actualDecibelSpectrogram.NyquistFrequency);
normalisedIntensityArray = DataTools.NormaliseInZeroOne(decibelArray, minDecibels, maxDecibels);
var plot2 = new Plot("Intensity 3-4 kHz", normalisedIntensityArray, normThreshold);

//plot 3
minHz = 4000;
maxHz = 5000;
decibelArray = SNR.CalculateFreqBandAvIntensity(actualDecibelSpectrogram.Data, minHz, maxHz, actualDecibelSpectrogram.NyquistFrequency);
normalisedIntensityArray = DataTools.NormaliseInZeroOne(decibelArray, minDecibels, maxDecibels);
var plot3 = new Plot("Intensity 4-5 kHz", normalisedIntensityArray, normThreshold);

// combine the plots
var plots = new List<Plot> { plot1, plot2, plot3 };

// create three events
var startOffset = TimeSpan.Zero;
var events = new List<AcousticEvent>
{
WindowSize = freqScale.FinalBinCount * 2,
WindowOverlap = 0.2,
SourceFName = recording.BaseName,
NoiseReductionType = NoiseReductionType.None,
NoiseReductionParameter = 0.0,
new AcousticEvent(startOffset, 10.0, 10.0, 2000, 3000),
new AcousticEvent(startOffset, 25.0, 10.0, 3000, 4000),
new AcousticEvent(startOffset, 40.0, 10.0, 4000, 5000),
};

// Method 1
var sonogram = new AmplitudeSonogram(sonoConfig, recording.WavReader);
var expectedDecibelSonogram = MFCCStuff.DecibelSpectra(sonogram.Data, sonogram.Configuration.WindowPower, sonogram.SampleRate, sonogram.Configuration.epsilon);
var image = SpectrogramTools.GetSonogramPlusCharts(actualDecibelSpectrogram, events, plots, null);

// Method 2: make sure that the decibel spectrum is the same no matter which path we take to calculate it.
var actualDecibelSpectrogram = new SpectrogramStandard(sonoConfig, recording.WavReader);
// create the image for visual confirmation
image.Save(Path.Combine(this.outputDirectory.FullName, this.recording.BaseName + ".png"));

CollectionAssert.That.AreEqual(expectedDecibelSonogram, actualDecibelSpectrogram.Data, EnvelopeAndFftTests.Delta);
Assert.AreEqual(1621, image.Width);
Assert.AreEqual(647, image.Height);
}
}
}

0 comments on commit 1228ff3

Please sign in to comment.