public void Validate(TimeSpan defaultIndexCalculationDuration) { SpectralIndexValues.CheckExistenceOfSpectralIndexValues(this.IndexProperties); // if tiling output we need to be able to parse the date from the file name Log.Info("Image tiling is " + (this.TileOutput ? string.Empty : "NOT ") + "enabled"); if (this.TileOutput) { if (!this.RequireDateInFilename) { throw new ConfigFileException( "If TileImageOutput is set then RequireDateInFilename must be set as well"); } } // set IndexCalculationDuration i.e. duration of a subsegment if (this.IndexCalculationDuration <= 0) { this.IndexCalculationDuration = defaultIndexCalculationDuration.TotalSeconds; Log.Warn( "IndexCalculationDuration from config file is invalid" + $" (Used default value = {this.IndexCalculationDuration})"); } if (this.TileOutput && this.IndexCalculationDuration != 60.0) { throw new ConfigFileException( "Invalid configuration detected: tile image output is enabled but " + "ICD != 60.0 so the images won'tbe created"); } }
public void TestOfSpectralIndices_ICD20() { //var indexPropertiesConfig = PathHelper.ResolveConfigFile(@"IndexPropertiesConfig.yml"); var sourceRecording = PathHelper.ResolveAsset(@"Recordings\BAC2_20071008-085040.wav"); var configFile = PathHelper.ResolveConfigFile(@"Towsey.Acoustic.yml"); // var outputDir = this.outputDirectory; // Create temp directory to store output if (!this.outputDirectory.Exists) { this.outputDirectory.Create(); } var recording = new AudioRecording(sourceRecording); // CHANGE CONFIG PARAMETERS HERE IF REQUIRED var indexCalculateConfig = ConfigFile.Deserialize <IndexCalculateConfig>(configFile); indexCalculateConfig.IndexCalculationDurationTimeSpan = TimeSpan.FromSeconds(20); var results = IndexCalculate.Analysis( recording, TimeSpan.FromSeconds(40), // assume that this is the third of three 20 second subsegments indexCalculateConfig.IndexProperties, 22050, TimeSpan.Zero, indexCalculateConfig, returnSonogramInfo: true); var spectralIndices = results.SpectralIndexValues; // TEST the SPECTRAL INDICES var resourcesDir = PathHelper.ResolveAssetPath("Indices"); var expectedSpectrumFile = new FileInfo(resourcesDir + "\\BGN_ICD20.bin"); //Binary.Serialize(expectedSpectrumFile, spectralIndices.BGN); var expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.BGN, AllowedDelta); expectedSpectrumFile = new FileInfo(resourcesDir + "\\CVR_ICD20.bin"); //Binary.Serialize(expectedSpectrumFile, spectralIndices.CVR); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.CVR, AllowedDelta); var outputImagePath1 = Path.Combine(this.outputDirectory.FullName, "SpectralIndices_ICD20.png"); var image = SpectralIndexValues.CreateImageOfSpectralIndices(spectralIndices); image.Save(outputImagePath1); }
/// <summary> /// Compress high resolution indices - intended to be used when summarizing results. /// Summarize method not yet written. /// </summary> /// <param name="analysisResults"></param> /// <param name="indexResults"></param> /// <param name="highResolutionParsedConfiguration"></param> private void SummarizeHighResolutionIndices( AnalysisResult2 analysisResults, IndexCalculateResult[] indexResults, AcousticIndices.AcousticIndicesConfig highResolutionParsedConfiguration) { // NOW COMPRESS THE HI-RESOLUTION SPECTRAL INDICES TO LOW RES double lowResolution = highResolutionParsedConfiguration.GetDoubleOrNull("LowResolution") ?? 60.0; TimeSpan imageScale = TimeSpan.FromSeconds(lowResolution); TimeSpan dataScale = highResolutionParsedConfiguration.IndexCalculationDuration.Seconds(); var dictionaryOfSpectra = indexResults.Select(icr => icr.SpectralIndexValues).ToArray().ToTwoDimensionalArray(SpectralIndexValues.CachedSelectors, TwoDimensionalArray.Rotate90ClockWise); var spectralSelection = IndexMatrices.CompressIndexSpectrograms(dictionaryOfSpectra, imageScale, dataScale); // check that have not compressed matrices to zero length double[,] matrix = spectralSelection.First().Value; if (matrix.GetLength(0) == 0 || matrix.GetLength(1) == 0) { LoggedConsole.WriteErrorLine("WARNING: SPECTRAL INDEX MATRICES compressed to zero length!!!!!!!!!!!!!!!!!!!!!!!!"); } // Place LOW RESOLUTION SPECTRAL INDICES INTO analysisResults before returning. //int windowLength = (int?)highResolutionConfig[AnalysisKeys.FrameLength] ?? IndexCalculate.DefaultWindowSize; var indexProperties = highResolutionParsedConfiguration.IndexProperties; SpectralIndexValues.CheckExistenceOfSpectralIndexValues(indexProperties); // Init a new spectral indices class and populate it with spectral indices var spectrums = SpectralIndexValues.ImportFromDictionary(spectralSelection); for (int i = 0; i < spectrums.Length; i++) { spectrums[i].ResultStartSeconds = (analysisResults.SegmentStartOffset + TimeSpan.FromSeconds(i * lowResolution)).TotalSeconds; spectrums[i].SegmentDurationSeconds = imageScale.TotalSeconds; spectrums[i].FileName = ((SegmentSettings <object>)analysisResults.SegmentSettings).Segment.SourceMetadata.Identifier; } // assign to the analysis result analysisResults.SpectralIndices = spectrums; // TODO TODO TODO // ALSO NEED TO COMPRESS THE analysisResults.SummaryIndices To LOW RESOLUTION //var summaryIndexValues = new SummaryIndexValues(); //summaryIndexValues.BackgroundNoise = ETC; // ETC //var summaryiv = new SummaryIndexValues[1]; //summaryiv[0] = summaryIndexValues; //analysisResults.SummaryIndices = summaryiv; }
public void TestOfSpectralIndices_Octave() { // create a two-minute artificial recording containing five harmonics. int sampleRate = 64000; double duration = 120; // signal duration in seconds int[] harmonics = { 500, 1000, 2000, 4000, 8000 }; var recording = DspFilters.GenerateTestRecording(sampleRate, duration, harmonics, WaveType.Sine); // cut out one minute from 30 - 90 seconds and incorporate into AudioRecording int startSample = sampleRate * 30; // start two minutes into recording int subsegmentSampleCount = sampleRate * 60; // get 60 seconds double[] subsamples = DataTools.Subarray(recording.WavReader.Samples, startSample, subsegmentSampleCount); var wr = new Acoustics.Tools.Wav.WavReader(subsamples, 1, 16, sampleRate); var subsegmentRecording = new AudioRecording(wr); //var indexPropertiesConfig = PathHelper.ResolveConfigFile(@"IndexPropertiesConfig.yml"); var configFile = PathHelper.ResolveConfigFile(@"Towsey.Acoustic.yml"); // Create temp directory to store output if (!this.outputDirectory.Exists) { this.outputDirectory.Create(); } // CHANGE CONFIG PARAMETERS HERE IF REQUIRED var indexCalculateConfig = ConfigFile.Deserialize <IndexCalculateConfig>(configFile); indexCalculateConfig.FrequencyScale = FreqScaleType.Octave; var freqScale = new FrequencyScale(indexCalculateConfig.FrequencyScale); indexCalculateConfig.FrameLength = freqScale.WindowSize; var results = IndexCalculate.Analysis( subsegmentRecording, TimeSpan.Zero, indexCalculateConfig.IndexProperties, sampleRate, TimeSpan.Zero, indexCalculateConfig, returnSonogramInfo: true); var spectralIndices = results.SpectralIndexValues; // draw the output image of all spectral indices var outputImagePath1 = Path.Combine(this.outputDirectory.FullName, "SpectralIndices_Octave.png"); var image = SpectralIndexValues.CreateImageOfSpectralIndices(spectralIndices); image.Save(outputImagePath1); // TEST the BGN SPECTRAL INDEX Assert.AreEqual(256, spectralIndices.BGN.Length); var resourcesDir = PathHelper.ResolveAssetPath("Indices"); var expectedSpectrumFile = new FileInfo(resourcesDir + "\\BGN_OctaveScale.bin"); //Binary.Serialize(expectedSpectrumFile, spectralIndices.BGN); var expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.BGN, AllowedDelta); expectedSpectrumFile = new FileInfo(resourcesDir + "\\CVR_OctaveScale.bin"); //Binary.Serialize(expectedSpectrumFile, spectralIndices.CVR); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.CVR, AllowedDelta); }
public void TestOfSpectralIndices() { //var indexPropertiesConfig = PathHelper.ResolveConfigFile(@"IndexPropertiesConfig.yml"); var sourceRecording = PathHelper.ResolveAsset(@"Recordings\BAC2_20071008-085040.wav"); var configFile = PathHelper.ResolveConfigFile(@"Towsey.Acoustic.yml"); // var outputDir = this.outputDirectory; var resourcesDir = PathHelper.ResolveAssetPath("Indices"); if (!this.outputDirectory.Exists) { this.outputDirectory.Create(); } var indexCalculateConfig = ConfigFile.Deserialize <IndexCalculateConfig>(configFile); // CHANGE CONFIG PARAMETERS HERE IF REQUIRED //indexCalculateConfig.IndexCalculationDuration = TimeSpan.FromSeconds(20); //indexCalculateConfig.SetTypeOfFreqScale("Octave"); var results = IndexCalculate.Analysis( new AudioRecording(sourceRecording), TimeSpan.Zero, indexCalculateConfig.IndexProperties, 22050, TimeSpan.Zero, indexCalculateConfig, returnSonogramInfo: true); var spectralIndices = results.SpectralIndexValues; // TEST the SPECTRAL INDICES // After serializing the expected vector and writing to the resources directory, comment the Binary.Serialise line. // 1:ACI var expectedSpectrumFile = new FileInfo(resourcesDir + "\\ACI.bin"); //Binary.Serialize(expectedSpectrumFile, spectralIndices.ACI); var expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.ACI, AllowedDelta); // 2:BGN expectedSpectrumFile = new FileInfo(resourcesDir + "\\BGN.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.BGN); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.BGN, AllowedDelta); // 3:CVR expectedSpectrumFile = new FileInfo(resourcesDir + "\\CVR.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.CVR); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.CVR, AllowedDelta); // 4:ENT expectedSpectrumFile = new FileInfo(resourcesDir + "\\ENT.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.ENT); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.ENT, AllowedDelta); // 5:EVN expectedSpectrumFile = new FileInfo(resourcesDir + "\\EVN.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.EVN); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.EVN, AllowedDelta); // 6:OSC expectedSpectrumFile = new FileInfo(resourcesDir + "\\OSC.bin"); //Binary.Serialize(expectedSpectrumFile, spectralIndices.OSC); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.OSC, AllowedDelta); // 7:PMN expectedSpectrumFile = new FileInfo(resourcesDir + "\\PMN.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.PMN); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.PMN, AllowedDelta); // 8:RHZ expectedSpectrumFile = new FileInfo(resourcesDir + "\\RHZ.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.RHZ); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.RHZ, AllowedDelta); // 9:RNG expectedSpectrumFile = new FileInfo(resourcesDir + "\\RNG.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.RNG); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.RNG, AllowedDelta); // 10:RPS expectedSpectrumFile = new FileInfo(resourcesDir + "\\RPS.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.RPS); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.RPS, AllowedDelta); // 11:RVT expectedSpectrumFile = new FileInfo(resourcesDir + "\\RVT.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.RVT); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.RVT, AllowedDelta); // 12:SPT expectedSpectrumFile = new FileInfo(resourcesDir + "\\SPT.bin"); // Binary.Serialize(expectedSpectrumFile, spectralIndices.SPT); expectedVector = Binary.Deserialize <double[]>(expectedSpectrumFile); CollectionAssert.That.AreEqual(expectedVector, spectralIndices.SPT, AllowedDelta); var outputImagePath = Path.Combine(this.outputDirectory.FullName, "SpectralIndices.png"); var image = SpectralIndexValues.CreateImageOfSpectralIndices(spectralIndices); image.Save(outputImagePath); }
[DataRow(0.1, 35990)] // at this scale 10 pixels are missing... image is padded by 0 px, and misisng 10px public void TestImagesHaveCorrectLength(double renderScale, int expectedWidth) { // this value just represents a 'render as much as you can until this limit' threshold const int ImageWidth = 1024; var dataScale = 0.1.Seconds(); var imageScale = renderScale.Seconds(); var recordingDuration = 3599.Seconds(); // we simulate rendering the last tile at each resolution var tileDuration = imageScale.Multiply(ImageWidth); var numberOfTiles = (int)Math.Floor(recordingDuration.TotalSeconds / tileDuration.TotalSeconds); var startTime = tileDuration.Multiply(numberOfTiles); // 1 second short of an hour - this is the test case var endTime = recordingDuration; var config = new LdSpectrogramConfig(); var generationData = new IndexGenerationData() { IndexCalculationDuration = dataScale, FrameLength = 512, FrameStep = 0, RecordingDuration = recordingDuration, }; var indexProperties = IndexProperties.GetIndexProperties(PathHelper.ResolveConfigFile("IndexPropertiesConfig.yml")); // create some fake spectra int duration = (int)(recordingDuration.TotalSeconds / dataScale.TotalSeconds); var spectra = new Dictionary <string, double[, ]>(); foreach (var key in SpectralIndexValues.GetKeys()) { spectra.Add(key, new double[256, duration]); var bgnKey = nameof(SpectralIndexValues.BGN); if (key == bgnKey) { spectra[bgnKey].Fill(indexProperties[bgnKey].DefaultValue); } // due to a bug in DrawRgbColourMatrix the ACI calculation ends up being NaN. // This we fill one of our other spectra to a non-zero value to get the black colour we desire // Bug reference: https://github.com/QutEcoacoustics/audio-analysis/issues/154 var sumKey = nameof(SpectralIndexValues.SUM); if (key == sumKey) { // this forces ACI calculation to 0 / 1 instead of 0 / 0 spectra[sumKey].Fill(1.0); } } string basename = "abc"; var image = ZoomCommon.DrawIndexSpectrogramCommon( config, generationData, indexProperties, startTime, endTime, dataScale, imageScale, ImageWidth, spectra, basename); // since we just asked for a fragment of the image at the end, // the expected width is just for that last fragment var lastWidth = expectedWidth - (numberOfTiles * ImageWidth); Assert.That.ImageIsSize(lastWidth, 256, image); Bitmap bitmap = (Bitmap)image; // test output for debugging //image.Save("./" + renderScale + ".png"); Assert.That.ImageRegionIsColor(new Rectangle(0, 0, lastWidth, 256), Color.Black, bitmap, 0); }