/// <summary> /// This method calls IndexCalculateSixOnly.Analysis() to calculate six spectral indices /// and then calls ContentSignatures.AnalyzeOneMinute() to obtain a content description derived from those indices and an array of functional templates. /// </summary> public override AnalysisResult2 Analyze <T>(AnalysisSettings analysisSettings, SegmentSettings <T> segmentSettings) { // set the start time for the current recording segment. Default is zero. var elapsedTimeAtStartOfRecording = segmentSettings.SegmentStartOffset; var startMinuteId = (int)Math.Round(elapsedTimeAtStartOfRecording.TotalMinutes); var audioFile = segmentSettings.SegmentAudioFile; var recording = new AudioRecording(audioFile.FullName); // Calculate six spectral indices. var segmentResults = IndexCalculateSixOnly.Analysis( recording, segmentSettings.SegmentStartOffset, segmentSettings.Segment.SourceMetadata.SampleRate); // DO THE CONTENT DESCRIPTION FOR ONE MINUTE HERE // First get acoustic indices for one minute, convert to Dictionary and normalize the values. var indicesDictionary = segmentResults.AsArray().ToTwoDimensionalArray(SpectralIndexValuesForContentDescription.CachedSelectors); //var indicesDictionary = IndexCalculateSixOnly.ConvertIndicesToDictionary(segmentResults); foreach (string key in ContentSignatures.IndexNames) { var indexBounds = ContentSignatures.IndexValueBounds[key]; var indexArray = indicesDictionary[key]; var normalisedVector = DataTools.NormaliseInZeroOne(indexArray, indexBounds[0], indexBounds[1]); indicesDictionary[key] = normalisedVector; } // scan templates over one minute of indices to get content description var descriptionResultForOneMinute = ContentSignatures.AnalyzeOneMinute( this.functionalTemplates, this.templatesAsDictionary, indicesDictionary.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.GetRow(0)), // this line converts dictionary of one-row matrices to dictionary of arrays. startMinuteId); // set up the analysis results to return var analysisResults = new AnalysisResult2(analysisSettings, segmentSettings, recording.Duration) { AnalysisIdentifier = this.Identifier, SpectralIndices = new SpectralIndexBase[] { // Transfer the spectral index results to AnalysisResults // TODO: consider not returning this value if it is not needed in summarize segmentResults, }, MiscellaneousResults = { { nameof(DescriptionResult), descriptionResultForOneMinute }, }, }; analysisResults.SpectralIndices[0].ResultStartSeconds = segmentSettings.SegmentStartOffset.TotalSeconds; //spectralIndexBase.ResultStartSeconds >= result.SegmentStartOffset.TotalSeconds, return(analysisResults); }
/// <summary> /// This is cut down version of the method of same name in LDSpectrogramRGB.cs. /// </summary> /// <param name="ldSpectrogramConfig">config for ldfc spectrogram.</param> /// <param name="outputDirectory">outputDirectory.</param> /// <param name="indexGenerationData">indexGenerationData.</param> /// <param name="basename">stem name of the original recording.</param> /// <param name="indexSpectrograms">Optional spectra to pass in. If specified the spectra will not be loaded from disk!.</param> private static string DrawSpectrogramsFromSpectralIndices( LdSpectrogramConfig ldSpectrogramConfig, DirectoryInfo outputDirectory, IndexGenerationData indexGenerationData, string basename, Dictionary <string, double[, ]> indexSpectrograms = null) { string colorMap1 = ldSpectrogramConfig.ColorMap1; // SpectrogramConstants.RGBMap_ACI_ENT_EVN; string colorMap2 = ldSpectrogramConfig.ColorMap2; // SpectrogramConstants.RGBMap_BGN_PMN_OSC; double blueEnhanceParameter = ldSpectrogramConfig.BlueEnhanceParameter.Value; var cs1 = new LDSpectrogramRGB(ldSpectrogramConfig, indexGenerationData, colorMap1); string fileStem = basename; cs1.FileName = fileStem; // calculate start time by combining DatetimeOffset with minute offset. cs1.StartOffset = indexGenerationData.AnalysisStartOffset; if (indexGenerationData.RecordingStartDate.HasValue) { DateTimeOffset dto = (DateTimeOffset)indexGenerationData.RecordingStartDate; cs1.RecordingStartDate = dto; if (dto != null) { cs1.StartOffset = dto.TimeOfDay + cs1.StartOffset; } } var indexProperties = IndexCalculateSixOnly.GetIndexProperties(); cs1.SetSpectralIndexProperties(indexProperties); // Load the Index Spectrograms into a Dictionary cs1.LoadSpectrogramDictionary(indexSpectrograms); if (cs1.GetCountOfSpectrogramMatrices() == 0) { Log.Error("No spectrogram matrices in the dictionary. Spectrogram files do not exist?"); throw new InvalidOperationException("Cannot find spectrogram matrix files"); } // draw all available gray scale index spectrograms. var keys = indexProperties.Keys.ToArray(); cs1.DrawGreyScaleSpectrograms(outputDirectory, fileStem, keys); // create two false-color spectrogram images var image1NoChrome = cs1.DrawFalseColorSpectrogramChromeless(cs1.ColorMode, colorMap1, blueEnhanceParameter); var image2NoChrome = cs1.DrawFalseColorSpectrogramChromeless(cs1.ColorMode, colorMap2, blueEnhanceParameter); var spacer = new Image <Rgb24>(image1NoChrome.Width, 10); var imageList = new[] { image1NoChrome, spacer, image2NoChrome, spacer }; Image image3 = ImageTools.CombineImagesVertically(imageList); var outputPath = FilenameHelpers.AnalysisResultPath(outputDirectory, fileStem, "2Maps", "png"); image3.Save(outputPath); return(outputPath); }