示例#1
0
        private Lazy <IndexCalculateResult[]> GetLazyIndices <T>(
            AudioRecording recording,
            AnalysisSettings analysisSettings,
            SegmentSettings <T> segmentSettings,
            AcousticIndices.AcousticIndicesConfig acousticConfiguration)
        {
            // Convert the Config config to IndexCalculateConfig class and merge in the unnecesary parameters.

            IndexCalculateResult[] Callback()
            {
                IndexCalculateResult[] subsegmentResults = AcousticIndices.CalculateIndicesInSubsegments(
                    recording,
                    segmentSettings.SegmentStartOffset,
                    segmentSettings.AnalysisIdealSegmentDuration,
                    acousticConfiguration.IndexCalculationDuration.Seconds(),
                    acousticConfiguration.IndexProperties,
                    segmentSettings.Segment.SourceMetadata.SampleRate,
                    acousticConfiguration);

                return(subsegmentResults);
            }

            return(new Lazy <IndexCalculateResult[]>(Callback, LazyThreadSafetyMode.ExecutionAndPublication));
        }
        public override AnalysisResult2 Analyze <T>(AnalysisSettings analysisSettings, SegmentSettings <T> segmentSettings)
        {
            var configuration = (StandardizedFeatureExtractionConfig)analysisSettings.Configuration;
            var audioFile     = segmentSettings.SegmentAudioFile;
            var recording     = new AudioRecording(audioFile.FullName);

            // Configurations non-specific for bands
            TimeSpan indexCalculationDuration = configuration.IndexCalculationDurationTimeSpan;
            TimeSpan bgNoiseNeighbourhood     = configuration.BgNoiseBuffer;

            // Bands
            List <StandardizedFeatureExtractionConfig.BandsProperties> bandsList = configuration.Bands;

            // Check if there are identical bands
            CheckForIdenticalBands(bandsList);

            // Estimate total number of subsegments
            double segmentDurationSeconds = segmentSettings.AnalysisIdealSegmentDuration.TotalSeconds;
            double subsegmentDuration     = indexCalculationDuration.TotalSeconds;
            int    subsegmentCount        = (int)Math.Round(segmentDurationSeconds / subsegmentDuration);
            int    totalSubsegmentCount   = subsegmentCount * bandsList.Count;

            // Store results of all subsegments
            var analysisResults = new AnalysisResult2(analysisSettings, segmentSettings, recording.Duration);

            analysisResults.AnalysisIdentifier = this.Identifier;

            var trackScores = new List <Plot>(totalSubsegmentCount);
            var tracks      = new List <SpectralTrack>(totalSubsegmentCount);

            analysisResults.SummaryIndices  = new SummaryIndexBase[totalSubsegmentCount];
            analysisResults.SpectralIndices = new SpectralIndexBase[totalSubsegmentCount];

            // Create list to store images, one for each band. They are later combined into one image.
            var    list          = new List <Image <Rgb24> >();
            string imagePath     = segmentSettings.SegmentImageFile.FullName;
            int    maxImageWidth = 0;

            int bandCount = 0;

            foreach (var band in bandsList)
            {
                Log.DebugFormat("Starting band {0}/{1}", bandCount + 1, bandsList.Count);

                // Calculate spectral indices

                // get a fresh copy of the ICC config
                var config = (IndexCalculateConfig)((ICloneable)configuration).Clone();

                // Add values specific for band from custom configuration file to config
                config.MinBandWidth = band.Bandwidth.Min;
                config.MaxBandWidth = band.Bandwidth.Max;
                config.FrameLength  = band.FftWindow;
                if (band.MelScale != 0)
                {
                    config.FrequencyScale = FreqScaleType.Mel;
                    config.MelScale       = band.MelScale;
                }
                else
                {
                    config.FrequencyScale = FreqScaleType.Linear;
                }

                // Calculate indices for each subsegment and for each band
                IndexCalculateResult[] subsegmentResults = AcousticIndices.CalculateIndicesInSubsegments(
                    recording,
                    segmentSettings.SegmentStartOffset,
                    segmentSettings.AnalysisIdealSegmentDuration,
                    indexCalculationDuration,
                    config.IndexProperties,
                    segmentSettings.Segment.SourceMetadata.SampleRate,
                    config);

                int columnsAmplitudeSpectrogram = subsegmentResults[0].AmplitudeSpectrogram.GetLength(1);
                double[,] amplitudeSpectrogramSegment = new double[0, columnsAmplitudeSpectrogram];

                for (int i = 0; i < subsegmentResults.Length; i++)
                {
                    var indexCalculateResult = subsegmentResults[i];

                    indexCalculateResult.SummaryIndexValues.FileName  = segmentSettings.Segment.SourceMetadata.Identifier;
                    indexCalculateResult.SpectralIndexValues.FileName = segmentSettings.Segment.SourceMetadata.Identifier;

                    analysisResults.SummaryIndices[bandCount + (i * bandsList.Count)]  = indexCalculateResult.SummaryIndexValues;
                    analysisResults.SpectralIndices[bandCount + (i * bandsList.Count)] = indexCalculateResult.SpectralIndexValues;

                    trackScores.AddRange(indexCalculateResult.TrackScores);
                    if (indexCalculateResult.Tracks != null)
                    {
                        tracks.AddRange(indexCalculateResult.Tracks);
                    }

                    if (analysisSettings.AnalysisImageSaveBehavior.ShouldSave())
                    {
                        // Add amplitude spectrograms of each subsegment together to get amplitude spectrogram of one segment
                        double[,] amplitudeSpectrogramSubsegment = indexCalculateResult.AmplitudeSpectrogram;
                        amplitudeSpectrogramSegment = MatrixTools.ConcatenateMatrixRows(
                            amplitudeSpectrogramSegment,
                            amplitudeSpectrogramSubsegment);
                    }
                }

                if (analysisSettings.AnalysisImageSaveBehavior.ShouldSave())
                {
                    // Create image of amplitude spectrogram
                    var image = ImageTools.DrawReversedMatrix(MatrixTools.MatrixRotate90Anticlockwise(amplitudeSpectrogramSegment));

                    // Label information
                    string minBandWidth = band.Bandwidth.Min.ToString();
                    string maxBandWidth = band.Bandwidth.Max.ToString();
                    string fftWindow    = band.FftWindow.ToString();
                    string mel;
                    string melScale;
                    if (band.MelScale != 0)
                    {
                        mel      = "Mel";
                        melScale = band.MelScale.ToString();
                    }
                    else
                    {
                        mel      = "Standard";
                        melScale = 0.ToString();
                    }

                    // Create label
                    string   segmentSeparator = "_";
                    string[] segments         = { minBandWidth, maxBandWidth, fftWindow, mel, melScale };
                    string   labelText        = segments.Aggregate(string.Empty, (aggregate, item) => aggregate + segmentSeparator + item);

                    var stringFont = Drawing.Arial14;
                    int width      = 250;
                    int height     = image.Height;
                    var label      = new Image <Rgb24>(width, height);
                    label.Mutate(g1 =>
                    {
                        g1.Clear(Color.Gray);
                        g1.DrawText(labelText, stringFont, Color.Black, new PointF(4, 30));
                        g1.DrawLine(new Pen(Color.Black, 1), 0, 0, width, 0); //draw upper boundary
                        g1.DrawLine(new Pen(Color.Black, 1), 0, 1, width, 1); //draw upper boundary
                    });

                    var labelledImage = ImageTools.CombineImagesInLine(label, image);

                    // Add labeled image to list
                    list.Add(labelledImage);

                    // Update maximal width of image
                    if (image.Width > maxImageWidth)
                    {
                        maxImageWidth = image.Width;
                    }
                }

                bandCount += 1;
                Log.InfoFormat("Completed band {0}/{1}", bandCount, bandsList.Count);
            }

            if (analysisSettings.AnalysisDataSaveBehavior)
            {
                this.WriteSummaryIndicesFile(segmentSettings.SegmentSummaryIndicesFile, analysisResults.SummaryIndices);
                analysisResults.SummaryIndicesFile  = segmentSettings.SegmentSummaryIndicesFile;
                analysisResults.SpectraIndicesFiles =
                    this.WriteSpectrumIndicesFiles(
                        segmentSettings.SegmentSpectrumIndicesDirectory,
                        Path.GetFileNameWithoutExtension(segmentSettings.SegmentAudioFile.Name),
                        analysisResults.SpectralIndices);
            }

            if (analysisSettings.AnalysisImageSaveBehavior.ShouldSave())
            {
                var finalImage = ImageTools.CombineImagesVertically(list, maxImageWidth);
                finalImage.Save(imagePath);
                analysisResults.ImageFile = new FileInfo(imagePath);
                LoggedConsole.WriteLine("See {0} for spectrogram pictures", imagePath);
            }

            return(analysisResults);
        }