public static AudioToSonogramResult AnalyseOneRecording( FileInfo sourceRecording, Dictionary <string, string> configDict, TimeSpan localEventStart, TimeSpan localEventEnd, int minHz, int maxHz, DirectoryInfo outDirectory) { // set a threshold for determining energy distribution in call // NOTE: value of this threshold depends on whether working with decibel, energy or amplitude values const double threshold = 9.0; int resampleRate = AppConfigHelper.DefaultTargetSampleRate; if (configDict.ContainsKey(AnalysisKeys.ResampleRate)) { resampleRate = int.Parse(configDict[AnalysisKeys.ResampleRate]); } configDict[ConfigKeys.Recording.Key_RecordingCallName] = sourceRecording.FullName; configDict[ConfigKeys.Recording.Key_RecordingFileName] = sourceRecording.Name; // 1: GET RECORDING and make temporary copy // put temp audio FileSegment in same directory as the required output image. var tempAudioSegment = TempFileHelper.NewTempFile(outDirectory, "wav"); // delete the temp audio file if it already exists. if (File.Exists(tempAudioSegment.FullName)) { File.Delete(tempAudioSegment.FullName); } // This line creates a temporary version of the source file downsampled as per entry in the config file MasterAudioUtility.SegmentToWav(sourceRecording, tempAudioSegment, new AudioUtilityRequest() { TargetSampleRate = resampleRate }); // 2: Generate sonogram image files AudioToSonogramResult result = GenerateSpectrogramImages(tempAudioSegment, configDict, outDirectory); // 3: GET the SNR statistics TimeSpan eventDuration = localEventEnd - localEventStart; result.SnrStatistics = SNR.Calculate_SNR_ShortRecording(tempAudioSegment, configDict, localEventStart, eventDuration, minHz, maxHz, threshold); // 4: Delete the temp file File.Delete(tempAudioSegment.FullName); return(result); }
public static AudioToSonogramResult GenerateFourSpectrogramImages( FileInfo sourceRecording, FileInfo path2SoxSpectrogram, Dictionary <string, string> configDict, bool dataOnly = false, bool makeSoxSonogram = false) { var result = new AudioToSonogramResult(); if (dataOnly && makeSoxSonogram) { throw new ArgumentException("Can't produce data only for a SoX sonogram"); } if (makeSoxSonogram) { SpectrogramTools.MakeSonogramWithSox(sourceRecording, configDict, path2SoxSpectrogram); result.Path2SoxImage = path2SoxSpectrogram; } else if (dataOnly) { var recordingSegment = new AudioRecording(sourceRecording.FullName); var sonoConfig = new SonogramConfig(configDict); // default values config // disable noise removal sonoConfig.NoiseReductionType = NoiseReductionType.None; Log.Warn("Noise removal disabled!"); var sonogram = new SpectrogramStandard(sonoConfig, recordingSegment.WavReader); result.DecibelSpectrogram = sonogram; } else { // init the image stack var list = new List <Image>(); // IMAGE 1) draw amplitude spectrogram var recordingSegment = new AudioRecording(sourceRecording.FullName); var sonoConfig = new SonogramConfig(configDict); // default values config // disable noise removal for first two spectrograms var disabledNoiseReductionType = sonoConfig.NoiseReductionType; sonoConfig.NoiseReductionType = NoiseReductionType.None; BaseSonogram sonogram = new AmplitudeSonogram(sonoConfig, recordingSegment.WavReader); // remove the DC bin if it has not already been removed. // Assume test of divisible by 2 is good enough. int binCount = sonogram.Data.GetLength(1); if (!binCount.IsEven()) { sonogram.Data = MatrixTools.Submatrix(sonogram.Data, 0, 1, sonogram.FrameCount - 1, binCount - 1); } //save spectrogram data at this point - prior to noise reduction var spectrogramDataBeforeNoiseReduction = sonogram.Data; const double neighbourhoodSeconds = 0.25; int neighbourhoodFrames = (int)(sonogram.FramesPerSecond * neighbourhoodSeconds); const double lcnContrastLevel = 0.001; LoggedConsole.WriteLine("LCN: FramesPerSecond (Prior to LCN) = {0}", sonogram.FramesPerSecond); LoggedConsole.WriteLine("LCN: Neighbourhood of {0} seconds = {1} frames", neighbourhoodSeconds, neighbourhoodFrames); const int lowPercentile = 20; sonogram.Data = NoiseRemoval_Briggs.NoiseReduction_byLowestPercentileSubtraction(sonogram.Data, lowPercentile); sonogram.Data = NoiseRemoval_Briggs.NoiseReduction_byLCNDivision(sonogram.Data, neighbourhoodFrames, lcnContrastLevel); //sonogram.Data = NoiseRemoval_Briggs.NoiseReduction_byLowestPercentileSubtraction(sonogram.Data, lowPercentile); var image = sonogram.GetImageFullyAnnotated("AMPLITUDE SPECTROGRAM + Bin LCN (Local Contrast Normalisation)"); list.Add(image); //string path2 = @"C:\SensorNetworks\Output\Sonograms\dataInput2.png"; //Histogram.DrawDistributionsAndSaveImage(sonogram.Data, path2); // double[,] matrix = sonogram.Data; double[,] matrix = ImageTools.WienerFilter(sonogram.Data, 3); double ridgeThreshold = 0.25; byte[,] hits = RidgeDetection.Sobel5X5RidgeDetectionExperiment(matrix, ridgeThreshold); hits = RidgeDetection.JoinDisconnectedRidgesInMatrix(hits, matrix, ridgeThreshold); image = SpectrogramTools.CreateFalseColourAmplitudeSpectrogram(spectrogramDataBeforeNoiseReduction, null, hits); image = sonogram.GetImageAnnotatedWithLinearHerzScale(image, "AMPLITUDE SPECTROGRAM + LCN + ridge detection"); list.Add(image); Image envelopeImage = ImageTrack.DrawWaveEnvelopeTrack(recordingSegment, image.Width); list.Add(envelopeImage); // IMAGE 2) now draw the standard decibel spectrogram sonogram = new SpectrogramStandard(sonoConfig, recordingSegment.WavReader); result.DecibelSpectrogram = (SpectrogramStandard)sonogram; image = sonogram.GetImageFullyAnnotated("DECIBEL SPECTROGRAM"); list.Add(image); Image segmentationImage = ImageTrack.DrawSegmentationTrack( sonogram, EndpointDetectionConfiguration.K1Threshold, EndpointDetectionConfiguration.K2Threshold, image.Width); list.Add(segmentationImage); // keep the sonogram data for later use double[,] dbSpectrogramData = (double[, ])sonogram.Data.Clone(); // 3) now draw the noise reduced decibel spectrogram // #NOISE REDUCTION PARAMETERS - restore noise reduction ################################################################## sonoConfig.NoiseReductionType = disabledNoiseReductionType; sonoConfig.NoiseReductionParameter = double.Parse(configDict[AnalysisKeys.NoiseBgThreshold] ?? "2.0"); // #NOISE REDUCTION PARAMETERS - MARINE HACK ################################################################## //sonoConfig.NoiseReductionType = NoiseReductionType.FIXED_DYNAMIC_RANGE; //sonoConfig.NoiseReductionParameter = 80.0; sonogram = new SpectrogramStandard(sonoConfig, recordingSegment.WavReader); image = sonogram.GetImageFullyAnnotated("DECIBEL SPECTROGRAM + Lamel noise subtraction"); list.Add(image); // keep the sonogram data for later use double[,] nrSpectrogramData = sonogram.Data; // 4) A FALSE-COLOUR VERSION OF SPECTROGRAM // ########################### SOBEL ridge detection ridgeThreshold = 3.5; matrix = ImageTools.WienerFilter(dbSpectrogramData, 3); hits = RidgeDetection.Sobel5X5RidgeDetectionExperiment(matrix, ridgeThreshold); // ########################### EIGEN ridge detection //double ridgeThreshold = 6.0; //double dominanceThreshold = 0.7; //var rotatedData = MatrixTools.MatrixRotate90Anticlockwise(dbSpectrogramData); //byte[,] hits = RidgeDetection.StructureTensorRidgeDetection(rotatedData, ridgeThreshold, dominanceThreshold); //hits = MatrixTools.MatrixRotate90Clockwise(hits); // ########################### EIGEN ridge detection image = SpectrogramTools.CreateFalseColourDecibelSpectrogram(dbSpectrogramData, nrSpectrogramData, hits); image = sonogram.GetImageAnnotatedWithLinearHerzScale(image, "DECIBEL SPECTROGRAM - Colour annotated"); list.Add(image); // 5) TODO: ONE OF THESE YEARS FIX UP THE CEPTRAL SONOGRAM ////SpectrogramCepstral cepgram = new SpectrogramCepstral((AmplitudeSonogram)amplitudeSpg); ////var mti3 = SpectrogramTools.Sonogram2MultiTrackImage(sonogram, configDict); ////var image3 = mti3.GetImage(); ////image3.Save(fiImage.FullName + "3", ImageFormat.Png); // 6) COMBINE THE SPECTROGRAM IMAGES result.CompositeImage = ImageTools.CombineImagesVertically(list); } return(result); }
/// <summary> /// Calculates the following spectrograms as per content of config.yml file: /// Waveform: true. /// DifferenceSpectrogram: true. /// DecibelSpectrogram: true. /// DecibelSpectrogram_NoiseReduced: true. /// DecibelSpectrogram_Ridges: true. /// AmplitudeSpectrogram_LocalContrastNormalization: true. /// SoxSpectrogram: false. /// Experimental: true. /// </summary> /// <param name="sourceRecording">The name of the original recording.</param> /// <param name="configInfo">Contains parameter info to make spectrograms.</param> /// <param name="sourceRecordingName">.Name of source recording. Required only spectrogram labels.</param> public static AudioToSonogramResult GenerateSpectrogramImages( FileInfo sourceRecording, AnalyzerConfig configInfo, string sourceRecordingName) { //int signalLength = recordingSegment.WavReader.GetChannel(0).Length; var recordingSegment = new AudioRecording(sourceRecording.FullName); int sampleRate = recordingSegment.WavReader.SampleRate; var result = new AudioToSonogramResult(); // init the image stack var list = new List <Image>(); bool doWaveForm = configInfo.GetBoolOrNull("Waveform") ?? false; bool doDecibelSpectrogram = configInfo.GetBoolOrNull("DecibelSpectrogram") ?? false; bool doNoiseReducedSpectrogram = configInfo.GetBoolOrNull("DecibelSpectrogram_NoiseReduced") ?? true; bool doDifferenceSpectrogram = configInfo.GetBoolOrNull("DifferenceSpectrogram") ?? false; bool doLcnSpectrogram = configInfo.GetBoolOrNull("AmplitudeSpectrogram_LocalContrastNormalization") ?? false; bool doCepstralSpectrogram = configInfo.GetBoolOrNull("CepstralSpectrogram") ?? false; bool doExperimentalSpectrogram = configInfo.GetBoolOrNull("Experimental") ?? false; //Don't do SOX spectrogram. //bool doSoxSpectrogram = configInfo.GetBool("SoxSpectrogram"); int frameSize = configInfo.GetIntOrNull("FrameLength") ?? 512; int frameStep = configInfo.GetIntOrNull("FrameStep") ?? 0; // must calculate this because used later on. double frameOverlap = (frameSize - frameStep) / (double)frameSize; // Default noiseReductionType = Standard var bgNoiseThreshold = configInfo.GetDoubleOrNull("BgNoiseThreshold") ?? 3.0; // EXTRACT ENVELOPE and SPECTROGRAM FROM RECORDING SEGMENT var dspOutput1 = DSP_Frames.ExtractEnvelopeAndFfts(recordingSegment, frameSize, frameStep); var sonoConfig = new SonogramConfig() { epsilon = recordingSegment.Epsilon, SampleRate = sampleRate, WindowSize = frameSize, WindowStep = frameStep, WindowOverlap = frameOverlap, WindowPower = dspOutput1.WindowPower, Duration = recordingSegment.Duration, NoiseReductionType = NoiseReductionType.Standard, NoiseReductionParameter = bgNoiseThreshold, }; // IMAGE 1) draw the WAVEFORM if (doWaveForm) { var minValues = dspOutput1.MinFrameValues; var maxValues = dspOutput1.MaxFrameValues; int height = configInfo.GetIntOrNull("WaveformHeight") ?? 180; var waveformImage = GetWaveformImage(minValues, maxValues, height); // add in the title bar and time scales. string title = $"WAVEFORM - {sourceRecordingName} (min value={dspOutput1.MinSignalValue:f3}, max value={dspOutput1.MaxSignalValue:f3})"; var titleBar = BaseSonogram.DrawTitleBarOfGrayScaleSpectrogram(title, waveformImage.Width); var startTime = TimeSpan.Zero; var xAxisTicInterval = TimeSpan.FromSeconds(1); TimeSpan xAxisPixelDuration = TimeSpan.FromSeconds(frameStep / (double)sampleRate); var labelInterval = TimeSpan.FromSeconds(5); waveformImage = BaseSonogram.FrameSonogram(waveformImage, titleBar, startTime, xAxisTicInterval, xAxisPixelDuration, labelInterval); list.Add(waveformImage); } // Draw various decibel spectrograms if (doDecibelSpectrogram || doNoiseReducedSpectrogram || doDifferenceSpectrogram || doExperimentalSpectrogram) { // disable noise removal for first spectrogram var disabledNoiseReductionType = sonoConfig.NoiseReductionType; sonoConfig.NoiseReductionType = NoiseReductionType.None; //Get the decibel spectrogram var decibelSpectrogram = new SpectrogramStandard(sonoConfig, dspOutput1.AmplitudeSpectrogram); result.DecibelSpectrogram = decibelSpectrogram; double[,] dbSpectrogramData = (double[, ])decibelSpectrogram.Data.Clone(); // IMAGE 2) DecibelSpectrogram if (doDecibelSpectrogram) { var image3 = decibelSpectrogram.GetImageFullyAnnotated($"DECIBEL SPECTROGRAM ({sourceRecordingName})"); list.Add(image3); } if (doNoiseReducedSpectrogram || doExperimentalSpectrogram || doDifferenceSpectrogram) { sonoConfig.NoiseReductionType = disabledNoiseReductionType; sonoConfig.NoiseReductionParameter = bgNoiseThreshold; double[] spectralDecibelBgn = NoiseProfile.CalculateBackgroundNoise(decibelSpectrogram.Data); decibelSpectrogram.Data = SNR.TruncateBgNoiseFromSpectrogram(decibelSpectrogram.Data, spectralDecibelBgn); decibelSpectrogram.Data = SNR.RemoveNeighbourhoodBackgroundNoise(decibelSpectrogram.Data, nhThreshold: bgNoiseThreshold); // IMAGE 3) DecibelSpectrogram - noise reduced if (doNoiseReducedSpectrogram) { var image4 = decibelSpectrogram.GetImageFullyAnnotated($"DECIBEL SPECTROGRAM + Lamel noise subtraction. ({sourceRecordingName})"); list.Add(image4); } // IMAGE 4) EXPERIMENTAL Spectrogram if (doExperimentalSpectrogram) { sonoConfig.NoiseReductionType = disabledNoiseReductionType; var image5 = GetDecibelSpectrogram_Ridges(dbSpectrogramData, decibelSpectrogram, sourceRecordingName); list.Add(image5); } // IMAGE 5) draw difference spectrogram if (doDifferenceSpectrogram) { var differenceThreshold = configInfo.GetDoubleOrNull("DifferenceThreshold") ?? 3.0; var image6 = GetDifferenceSpectrogram(dbSpectrogramData, differenceThreshold); image6 = BaseSonogram.GetImageAnnotatedWithLinearHertzScale(image6, sampleRate, frameStep, $"DECIBEL DIFFERENCE SPECTROGRAM ({sourceRecordingName})"); list.Add(image6); } } } // IMAGE 6) Cepstral Spectrogram if (doCepstralSpectrogram) { var image6 = GetCepstralSpectrogram(sonoConfig, recordingSegment, sourceRecordingName); list.Add(image6); } // 7) AmplitudeSpectrogram_LocalContrastNormalization if (doLcnSpectrogram) { var neighbourhoodSeconds = configInfo.GetDoubleOrNull("NeighbourhoodSeconds") ?? 0.5; var lcnContrastParameter = configInfo.GetDoubleOrNull("LcnContrastLevel") ?? 0.4; var image8 = GetLcnSpectrogram(sonoConfig, recordingSegment, sourceRecordingName, neighbourhoodSeconds, lcnContrastParameter); list.Add(image8); } // 8) SOX SPECTROGRAM //if (doSoxSpectrogram) //{ //Log.Warn("SoX spectrogram set to true but is ignored when running as an IAnalyzer"); // The following parameters were once used to implement a sox spectrogram. //bool makeSoxSonogram = configuration.GetBoolOrNull(AnalysisKeys.MakeSoxSonogram) ?? false; //configDict[AnalysisKeys.SonogramTitle] = configuration[AnalysisKeys.SonogramTitle] ?? "Sonogram"; //configDict[AnalysisKeys.SonogramComment] = configuration[AnalysisKeys.SonogramComment] ?? "Sonogram produced using SOX"; //configDict[AnalysisKeys.SonogramColored] = configuration[AnalysisKeys.SonogramColored] ?? "false"; //configDict[AnalysisKeys.SonogramQuantisation] = configuration[AnalysisKeys.SonogramQuantisation] ?? "128"; //configDict[AnalysisKeys.AddTimeScale] = configuration[AnalysisKeys.AddTimeScale] ?? "true"; //configDict[AnalysisKeys.AddAxes] = configuration[AnalysisKeys.AddAxes] ?? "true"; //configDict[AnalysisKeys.AddSegmentationTrack] = configuration[AnalysisKeys.AddSegmentationTrack] ?? "true"; // var soxFile = new FileInfo(Path.Combine(output.FullName, sourceName + "SOX.png")); // SpectrogramTools.MakeSonogramWithSox(sourceRecording, configDict, path2SoxSpectrogram); // list.Add(image7); //} // COMBINE THE SPECTROGRAM IMAGES result.CompositeImage = ImageTools.CombineImagesVertically(list); return(result); }
public static AudioToSonogramResult GenerateSpectrogramImages(FileInfo sourceRecording, Dictionary <string, string> configDict, DirectoryInfo outputDirectory) { // the source name was set up in the Analyse() method. But it could also be obtained directly from recording. string sourceName = configDict[ConfigKeys.Recording.Key_RecordingFileName]; sourceName = Path.GetFileNameWithoutExtension(sourceName); var result = new AudioToSonogramResult(); // init the image stack var list = new List <Image>(); // 1) draw amplitude spectrogram var recordingSegment = new AudioRecording(sourceRecording.FullName); // default values config except disable noise removal for first two spectrograms SonogramConfig sonoConfig = new SonogramConfig(configDict) { NoiseReductionType = NoiseReductionType.None }; BaseSonogram sonogram = new AmplitudeSonogram(sonoConfig, recordingSegment.WavReader); // remove the DC bin sonogram.Data = MatrixTools.Submatrix(sonogram.Data, 0, 1, sonogram.FrameCount - 1, sonogram.Configuration.FreqBinCount); // save spectrogram data at this point - prior to noise reduction double[,] spectrogramDataBeforeNoiseReduction = sonogram.Data; const int lowPercentile = 20; const double neighbourhoodSeconds = 0.25; int neighbourhoodFrames = (int)(sonogram.FramesPerSecond * neighbourhoodSeconds); const double lcnContrastLevel = 0.25; ////LoggedConsole.WriteLine("LCN: FramesPerSecond (Prior to LCN) = {0}", sonogram.FramesPerSecond); ////LoggedConsole.WriteLine("LCN: Neighbourhood of {0} seconds = {1} frames", neighbourhoodSeconds, neighbourhoodFrames); sonogram.Data = NoiseRemoval_Briggs.NoiseReduction_ShortRecordings_SubtractAndLCN(sonogram.Data, lowPercentile, neighbourhoodFrames, lcnContrastLevel); // draw amplitude spectrogram unannotated FileInfo outputImage1 = new FileInfo(Path.Combine(outputDirectory.FullName, sourceName + ".amplitd.bmp")); ImageTools.DrawReversedMatrix(MatrixTools.MatrixRotate90Anticlockwise(sonogram.Data), outputImage1.FullName); // draw amplitude spectrogram annotated var image = sonogram.GetImageFullyAnnotated("AMPLITUDE SPECTROGRAM + Bin LCN (Local Contrast Normalisation)"); list.Add(image); ////string path2 = @"C:\SensorNetworks\Output\Sonograms\dataInput2.png"; ////Histogram.DrawDistributionsAndSaveImage(sonogram.Data, path2); // 2) A FALSE-COLOUR VERSION OF AMPLITUDE SPECTROGRAM double ridgeThreshold = 0.20; double[,] matrix = ImageTools.WienerFilter(sonogram.Data, 3); byte[,] hits = RidgeDetection.Sobel5X5RidgeDetectionExperiment(matrix, ridgeThreshold); hits = RidgeDetection.JoinDisconnectedRidgesInMatrix(hits, matrix, ridgeThreshold); image = SpectrogramTools.CreateFalseColourAmplitudeSpectrogram(spectrogramDataBeforeNoiseReduction, null, hits); image = sonogram.GetImageAnnotatedWithLinearHerzScale(image, "AMPLITUDE SPECTROGRAM + LCN + ridge detection"); list.Add(image); Image envelopeImage = ImageTrack.DrawWaveEnvelopeTrack(recordingSegment, image.Width); list.Add(envelopeImage); // 3) now draw the standard decibel spectrogram sonogram = new SpectrogramStandard(sonoConfig, recordingSegment.WavReader); // remove the DC bin sonogram.Data = MatrixTools.Submatrix(sonogram.Data, 0, 1, sonogram.FrameCount - 1, sonogram.Configuration.FreqBinCount); // draw decibel spectrogram unannotated FileInfo outputImage2 = new FileInfo(Path.Combine(outputDirectory.FullName, sourceName + ".deciBel.bmp")); ImageTools.DrawReversedMatrix(MatrixTools.MatrixRotate90Anticlockwise(sonogram.Data), outputImage2.FullName); image = sonogram.GetImageFullyAnnotated("DECIBEL SPECTROGRAM"); list.Add(image); Image segmentationImage = ImageTrack.DrawSegmentationTrack( sonogram, EndpointDetectionConfiguration.K1Threshold, EndpointDetectionConfiguration.K2Threshold, image.Width); list.Add(segmentationImage); // keep the sonogram data (NOT noise reduced) for later use double[,] dbSpectrogramData = (double[, ])sonogram.Data.Clone(); // 4) now draw the noise reduced decibel spectrogram sonoConfig.NoiseReductionType = NoiseReductionType.Standard; sonoConfig.NoiseReductionParameter = 3; ////sonoConfig.NoiseReductionType = NoiseReductionType.SHORT_RECORDING; ////sonoConfig.NoiseReductionParameter = 50; sonogram = new SpectrogramStandard(sonoConfig, recordingSegment.WavReader); // draw decibel spectrogram unannotated FileInfo outputImage3 = new FileInfo(Path.Combine(outputDirectory.FullName, sourceName + ".noNoise_dB.bmp")); ImageTools.DrawReversedMatrix(MatrixTools.MatrixRotate90Anticlockwise(sonogram.Data), outputImage3.FullName); image = sonogram.GetImageFullyAnnotated("DECIBEL SPECTROGRAM + Lamel noise subtraction"); list.Add(image); // keep the sonogram data for later use double[,] nrSpectrogramData = sonogram.Data; // 5) A FALSE-COLOUR VERSION OF DECIBEL SPECTROGRAM ridgeThreshold = 2.5; matrix = ImageTools.WienerFilter(dbSpectrogramData, 3); hits = RidgeDetection.Sobel5X5RidgeDetectionExperiment(matrix, ridgeThreshold); image = SpectrogramTools.CreateFalseColourDecibelSpectrogram(dbSpectrogramData, nrSpectrogramData, hits); image = sonogram.GetImageAnnotatedWithLinearHerzScale(image, "DECIBEL SPECTROGRAM - Colour annotated"); list.Add(image); // 6) COMBINE THE SPECTROGRAM IMAGES Image compositeImage = ImageTools.CombineImagesVertically(list); FileInfo outputImage = new FileInfo(Path.Combine(outputDirectory.FullName, sourceName + ".5spectro.png")); compositeImage.Save(outputImage.FullName, ImageFormat.Png); result.SpectrogramFile = outputImage; // 7) Generate the FREQUENCY x OSCILLATIONS Graphs and csv data ////bool saveData = true; ////bool saveImage = true; ////double[] oscillationsSpectrum = Oscillations2014.GenerateOscillationDataAndImages(sourceRecording, configDict, saveData, saveImage); return(result); }
/// <summary> /// This method written 18-09-2014 to process Mangalam's CNN recordings. /// Calculate the SNR statistics for each recording and then write info back to csv file /// </summary> public static void Main(Arguments arguments) { // set preprocessing parameter bool doPreprocessing = true; var output = arguments.Output; if (!output.Exists) { output.Create(); } Log.InfoFormat("# PRE-PROCESS SHORT AUDIO RECORDINGS FOR Convolutional DNN"); Log.InfoFormat("# DATE AND TIME: " + DateTime.Now); Log.InfoFormat("# Input .csv file: " + arguments.Source); Log.InfoFormat("# Configure file: " + arguments.Config); Log.InfoFormat("# Output directry: " + arguments.Output); // 1. set up the necessary files FileInfo csvFileInfo = arguments.Source; FileInfo configFile = arguments.Config.ToFileInfo(); // 2. get the config dictionary var configDict = GetConfigurationForConvCnn(configFile); // print out the parameters LoggedConsole.WriteLine("\nPARAMETERS"); foreach (var kvp in configDict) { LoggedConsole.WriteLine("{0} = {1}", kvp.Key, kvp.Value); } // set up header of the output file string outputPath = Path.Combine(output.FullName, "SNRInfoForConvDnnDataset.csv"); using (StreamWriter writer = new StreamWriter(outputPath)) { string header = AudioToSonogramResult.GetCsvHeader(); writer.WriteLine(header); } // following int's are counters to monitor file availability int lineNumber = 0; int fileExistsCount = 0; int fileLocationNotInCsv = 0; int fileInCsvDoesNotExist = 0; // keep track of species names and distribution of classes. // following dictionaries are to monitor species numbers var speciesCounts = new SpeciesCounts(); // read through the csv file containing info about recording locations and call bounds try { var file = new FileStream(csvFileInfo.FullName, FileMode.Open); var sr = new StreamReader(file); // read the header and discard string strLine; lineNumber++; while ((strLine = sr.ReadLine()) != null) { lineNumber++; if (lineNumber % 5000 == 0) { Console.WriteLine(lineNumber); } // cannot use next line because reads the entire file ////var data = Csv.ReadFromCsv<string[]>(csvFileInfo).ToList(); // read single record from csv file var record = CsvDataRecord.ReadLine(strLine); if (record.Path == null) { fileLocationNotInCsv++; ////string warning = String.Format("######### WARNING: line {0} NULL PATH FIELD >>>null<<<", count); ////LoggedConsole.WriteWarnLine(warning); continue; } var sourceRecording = record.Path; var sourceDirectory = sourceRecording.Directory; string parentDirectoryName = sourceDirectory.Parent.Name; //var imageOpDir = new DirectoryInfo(output.FullName + @"\" + parentDirectoryName); ////DirectoryInfo imageOpDir = new DirectoryInfo(outDirectory.FullName + @"\" + parentDirectoryName + @"\" + directoryName); ////DirectoryInfo localSourceDir = new DirectoryInfo(@"C:\SensorNetworks\WavFiles\ConvDNNData"); ////sourceRecording = Path.Combine(localSourceDir.FullName + @"\" + parentDirectoryName + @"\" + directoryName, fileName).ToFileInfo(); ////record.path = sourceRecording; /* ####################################### */ // TO TEST SMALL PORTION OF DATA because total data is too large. doPreprocessing = false || parentDirectoryName.Equals("0"); if (!sourceRecording.Exists) { fileInCsvDoesNotExist++; string warning = string.Format("FILE DOES NOT EXIST >>>," + sourceRecording.Name); using (var writer = new StreamWriter(outputPath, true)) { writer.WriteLine(warning); } continue; } // #################################################################### if (doPreprocessing) { AudioToSonogramResult result = AnalyseOneRecording(record, configDict, output); string line = result.WriteResultAsLineOfCsv(); // It is helpful to write to the output file as we go, so as to keep a record of where we are up to. // This requires to open and close the output file at each iteration using (var writer = new StreamWriter(outputPath, true)) { writer.WriteLine(line); } } // everything should be OK - have jumped through all the hoops. fileExistsCount++; // keep track of species names and distribution of classes. speciesCounts.AddSpeciesCount(record.CommonTags); speciesCounts.AddSpeciesId(record.CommonTags, record.SpeciesTags); speciesCounts.AddSiteName(record.SiteName); } // end while() string classDistributionOpPath = Path.Combine(output.FullName, "ClassDistributionsForConvDnnDataset.csv"); speciesCounts.Save(classDistributionOpPath); } catch (IOException e) { LoggedConsole.WriteLine("Something went seriously bloody wrong!"); LoggedConsole.WriteLine(e.ToString()); return; } LoggedConsole.WriteLine("fileLocationNotInCsv =" + fileLocationNotInCsv); LoggedConsole.WriteLine("fileInCsvDoesNotExist=" + fileInCsvDoesNotExist); LoggedConsole.WriteLine("fileExistsCount =" + fileExistsCount); LoggedConsole.WriteLine("\n##### FINISHED FILE ############################\n"); }