//######################################################################################################################################################################## //######################################################################################################################################################################## //## STATIC METHODS BELOW ############################################################################################################################################### //######################################################################################################################################################################## //######################################################################################################################################################################## /// <summary> /// TODO - this is long winded way to get file. Need to talk to Mark. /// </summary> public static AudioRecording GetAudioRecording(FileInfo sourceFile, int resampleRate, string opDir, string opFileName) { if (!sourceFile.Exists) { return(null); } string opPath = Path.Combine(opDir, opFileName); //path location/name of extracted recording segment IAudioUtility audioUtility = new MasterAudioUtility(); var info = audioUtility.Info(sourceFile); // Get duration of the source file int startMilliseconds = 0; int endMilliseconds = (int)info.Duration.Value.TotalMilliseconds; MasterAudioUtility.SegmentToWav( sourceFile, new FileInfo(opPath), new AudioUtilityRequest { TargetSampleRate = resampleRate, OffsetStart = TimeSpan.FromMilliseconds(startMilliseconds), OffsetEnd = TimeSpan.FromMilliseconds(endMilliseconds), }); return(new AudioRecording(opPath)); }
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 FileInfo CreateTemporaryAudioFile(FileInfo sourceRecording, DirectoryInfo outDir, int resampleRate) { // put temp FileSegment in same directory as the required output image. var tempAudioSegment = new FileInfo(Path.Combine(outDir.FullName, "tempWavFile.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 }); return(tempAudioSegment); }
/// <summary> /// This method extracts a recording segment and saves it to disk at the location fiOutputSegment. /// </summary> public static void ExtractSegment(FileInfo fiSource, TimeSpan start, TimeSpan end, TimeSpan buffer, int sampleRate, FileInfo fiOutputSegment) { // EXTRACT RECORDING SEGMENT int startMilliseconds = (int)(start.TotalMilliseconds - buffer.TotalMilliseconds); int endMilliseconds = (int)(end.TotalMilliseconds + buffer.TotalMilliseconds); if (startMilliseconds < 0) { startMilliseconds = 0; } ////if (endMilliseconds <= 0) endMilliseconds = (int)(segmentDuration * 60000) - 1;//no need to worry about end MasterAudioUtility.SegmentToWav( fiSource, fiOutputSegment, new AudioUtilityRequest { TargetSampleRate = sampleRate, OffsetStart = TimeSpan.FromMilliseconds(startMilliseconds), OffsetEnd = TimeSpan.FromMilliseconds(endMilliseconds), ////Channel = 2 // set channel number or mixdowntomono=true BUT NOT BOTH!!! ////MixDownToMono =true }); }
public static void Main(Arguments arguments) { // 1. set up the necessary files FileInfo sourceRecording = arguments.Source; FileInfo configFile = arguments.Config.ToFileInfo(); DirectoryInfo opDir = arguments.Output; opDir.Create(); if (arguments.StartOffset.HasValue ^ arguments.EndOffset.HasValue) { throw new InvalidStartOrEndException("If StartOffset or EndOffset is specified, then both must be specified"); } var offsetsProvided = arguments.StartOffset.HasValue && arguments.EndOffset.HasValue; // set default offsets - only use defaults if not provided in argments list TimeSpan?startOffset = null; TimeSpan?endOffset = null; if (offsetsProvided) { startOffset = TimeSpan.FromSeconds(arguments.StartOffset.Value); endOffset = TimeSpan.FromSeconds(arguments.EndOffset.Value); } const string Title = "# MAKE A SONOGRAM FROM AUDIO RECORDING and do OscillationsGeneric activity."; string date = "# DATE AND TIME: " + DateTime.Now; LoggedConsole.WriteLine(Title); LoggedConsole.WriteLine(date); LoggedConsole.WriteLine("# Input audio file: " + sourceRecording.Name); string sourceName = Path.GetFileNameWithoutExtension(sourceRecording.FullName); // 2. get the config dictionary Config configuration = ConfigFile.Deserialize(configFile); // below three lines are examples of retrieving info from Config config // string analysisIdentifier = configuration[AnalysisKeys.AnalysisName]; // bool saveIntermediateWavFiles = (bool?)configuration[AnalysisKeys.SaveIntermediateWavFiles] ?? false; // scoreThreshold = (double?)configuration[AnalysisKeys.EventThreshold] ?? scoreThreshold; // Resample rate must be 2 X the desired Nyquist. Default is that of recording. var resampleRate = configuration.GetIntOrNull(AnalysisKeys.ResampleRate) ?? AppConfigHelper.DefaultTargetSampleRate; var configDict = new Dictionary <string, string>(configuration.ToDictionary()); // #NOISE REDUCTION PARAMETERS //string noisereduce = configDict[ConfigKeys.Mfcc.Key_NoiseReductionType]; configDict[AnalysisKeys.NoiseDoReduction] = "false"; configDict[AnalysisKeys.NoiseReductionType] = "NONE"; configDict[AnalysisKeys.AddAxes] = configuration[AnalysisKeys.AddAxes] ?? "true"; configDict[AnalysisKeys.AddSegmentationTrack] = configuration[AnalysisKeys.AddSegmentationTrack] ?? "true"; configDict[ConfigKeys.Recording.Key_RecordingCallName] = sourceRecording.FullName; configDict[ConfigKeys.Recording.Key_RecordingFileName] = sourceRecording.Name; configDict[AnalysisKeys.AddTimeScale] = configuration[AnalysisKeys.AddTimeScale] ?? "true"; configDict[AnalysisKeys.AddAxes] = configuration[AnalysisKeys.AddAxes] ?? "true"; configDict[AnalysisKeys.AddSegmentationTrack] = configuration[AnalysisKeys.AddSegmentationTrack] ?? "true"; // #################################################################### // print out the sonogram parameters LoggedConsole.WriteLine("\nPARAMETERS"); foreach (KeyValuePair <string, string> kvp in configDict) { LoggedConsole.WriteLine("{0} = {1}", kvp.Key, kvp.Value); } LoggedConsole.WriteLine("Sample Length for detecting oscillations = {0}", SampleLength); // 3: GET RECORDING FileInfo tempAudioSegment = new FileInfo(Path.Combine(opDir.FullName, "tempWavFile.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 }); // 1) get amplitude spectrogram AudioRecording recordingSegment = new AudioRecording(tempAudioSegment.FullName); SonogramConfig sonoConfig = new SonogramConfig(configDict); // default values config BaseSonogram sonogram = new AmplitudeSonogram(sonoConfig, recordingSegment.WavReader); Console.WriteLine("FramesPerSecond = {0}", sonogram.FramesPerSecond); // remove the DC bin sonogram.Data = MatrixTools.Submatrix(sonogram.Data, 0, 1, sonogram.FrameCount - 1, sonogram.Configuration.FreqBinCount); // ############################################################### // DO LocalContrastNormalisation //int fieldSize = 9; //sonogram.Data = LocalContrastNormalisation.ComputeLCN(sonogram.Data, fieldSize); // LocalContrastNormalisation over frequency bins is better and faster. int neighbourhood = 15; double contrastLevel = 0.5; sonogram.Data = NoiseRemoval_Briggs.NoiseReduction_byLCNDivision(sonogram.Data, neighbourhood, contrastLevel); // ############################################################### // lowering the sensitivity threshold increases the number of hits. if (configDict.ContainsKey(AnalysisKeys.OscilDetection2014SensitivityThreshold)) { Oscillations2014.DefaultSensitivityThreshold = double.Parse(configDict[AnalysisKeys.OscilDetection2014SensitivityThreshold]); } if (configDict.ContainsKey(AnalysisKeys.OscilDetection2014SampleLength)) { Oscillations2014.DefaultSampleLength = int.Parse(configDict[AnalysisKeys.OscilDetection2014SensitivityThreshold]); } var list1 = new List <Image>(); //var result = Oscillations2014.GetFreqVsOscillationsDataAndImage(sonogram, 64, "Autocorr-FFT"); //list1.Add(result.FreqOscillationImage); var result = Oscillations2014.GetFreqVsOscillationsDataAndImage(sonogram, "Autocorr-FFT"); list1.Add(result.FreqOscillationImage); result = Oscillations2014.GetFreqVsOscillationsDataAndImage(sonogram, "Autocorr-SVD-FFT"); list1.Add(result.FreqOscillationImage); result = Oscillations2014.GetFreqVsOscillationsDataAndImage(sonogram, "Autocorr-WPD"); list1.Add(result.FreqOscillationImage); Image compositeOscImage1 = ImageTools.CombineImagesInLine(list1.ToArray()); // ############################################################### // init the sonogram image stack var sonogramList = new List <Image>(); var image = sonogram.GetImageFullyAnnotated("AMPLITUDE SPECTROGRAM"); sonogramList.Add(image); //string testPath = @"C:\SensorNetworks\Output\Sonograms\amplitudeSonogram.png"; //image.Save(testPath, ImageFormat.Png); Image envelopeImage = ImageTrack.DrawWaveEnvelopeTrack(recordingSegment, image.Width); sonogramList.Add(envelopeImage); // 2) now draw the standard decibel spectrogram sonogram = new SpectrogramStandard(sonoConfig, recordingSegment.WavReader); // ############################################################### list1 = new List <Image>(); //result = Oscillations2014.GetFreqVsOscillationsDataAndImage(sonogram, 64, "Autocorr-FFT"); //list1.Add(result.FreqOscillationImage); result = Oscillations2014.GetFreqVsOscillationsDataAndImage(sonogram, "Autocorr-FFT"); list1.Add(result.FreqOscillationImage); result = Oscillations2014.GetFreqVsOscillationsDataAndImage(sonogram, "Autocorr-SVD-FFT"); list1.Add(result.FreqOscillationImage); result = Oscillations2014.GetFreqVsOscillationsDataAndImage(sonogram, "Autocorr-WPD"); list1.Add(result.FreqOscillationImage); Image compositeOscImage2 = ImageTools.CombineImagesInLine(list1.ToArray()); // ############################################################### //image = sonogram.GetImageFullyAnnotated("DECIBEL SPECTROGRAM"); //list.Add(image); // combine eight images list1 = new List <Image>(); list1.Add(compositeOscImage1); list1.Add(compositeOscImage2); Image compositeOscImage3 = ImageTools.CombineImagesVertically(list1.ToArray()); string imagePath3 = Path.Combine(opDir.FullName, sourceName + "_freqOscilMatrix.png"); compositeOscImage3.Save(imagePath3, ImageFormat.Png); Image segmentationImage = ImageTrack.DrawSegmentationTrack( sonogram, EndpointDetectionConfiguration.K1Threshold, EndpointDetectionConfiguration.K2Threshold, image.Width); sonogramList.Add(segmentationImage); // 3) now draw the noise reduced decibel spectrogram sonoConfig.NoiseReductionType = NoiseReductionType.Standard; sonoConfig.NoiseReductionParameter = configuration.GetDoubleOrNull(AnalysisKeys.NoiseBgThreshold) ?? 3.0; sonogram = new SpectrogramStandard(sonoConfig, recordingSegment.WavReader); image = sonogram.GetImageFullyAnnotated("NOISE-REDUCED DECIBEL SPECTROGRAM"); sonogramList.Add(image); // ############################################################### // deriving osscilation graph from this noise reduced spectrogram did not work well //Oscillations2014.SaveFreqVsOscillationsDataAndImage(sonogram, sampleLength, algorithmName, opDir); // ############################################################### Image compositeSonogram = ImageTools.CombineImagesVertically(sonogramList); string imagePath2 = Path.Combine(opDir.FullName, sourceName + ".png"); compositeSonogram.Save(imagePath2, ImageFormat.Png); LoggedConsole.WriteLine("\n##### FINISHED FILE ###################################################\n"); }