public static void Execute(Arguments arguments) { if (arguments == null) { arguments = Dev(); } string opFName = ANALYSIS_NAME + ".txt"; FileInfo opPath = arguments.Output.CombineFile(opFName); string audioFileName = arguments.Source.Name; Log.Verbosity = 1; string title = "# FOR DETECTION OF ACOUSTIC EVENTS HAVING A GRID OR GRATING STRUCTURE"; string date = "# DATE AND TIME: " + DateTime.Now; LoggedConsole.WriteLine(title); LoggedConsole.WriteLine(date); LoggedConsole.WriteLine("# Output folder: " + arguments.Output); LoggedConsole.WriteLine("# Recording file: " + arguments.Source.Name); FileTools.WriteTextFile(opPath.FullName, date + "\n# Recording file: " + audioFileName); //READ PARAMETER VALUES FROM INI FILE var configuration = new ConfigDictionary(arguments.Config); Dictionary <string, string> configDict = configuration.GetTable(); Dictionary <string, string> .KeyCollection keys = configDict.Keys; int startMinute = 5; //dummy value var fiSegmentOfSourceFile = arguments.Source; var diOutputDir = arguments.Output; //############################################################################################################################################# DataTable dt = AnalysisReturnsDataTable(startMinute, fiSegmentOfSourceFile, configDict, diOutputDir); //############################################################################################################################################# if (dt == null) { Log.WriteLine("\n\n\n##############################\n WARNING! No events returned."); } else { //LoggedConsole.WriteLine("\tRecording Duration: {0:f2}seconds", recordingTimeSpan.TotalSeconds); LoggedConsole.WriteLine("# Event count for minute {0} = {1}", startMinute, dt.Rows.Count); DataTableTools.WriteTable2Console(dt); } LoggedConsole.WriteLine("# Finished recording:- " + arguments.Source.FullName); }
public static void Execute(Arguments arguments) { MainEntry.WarnIfDeveloperEntryUsed(); string title = "# EVENT PATTERN RECOGNITION."; string date = "# DATE AND TIME: " + DateTime.Now; Log.WriteLine(title); Log.WriteLine(date); Log.Verbosity = 1; string targetName = arguments.Target; // prefix of name of created files var input = arguments.Source; string recordingFileName = input.Name; string recordingDirectory = input.DirectoryName; DirectoryInfo outputDir = arguments.Config.ToFileInfo().Directory; FileInfo targetPath = outputDir.CombineFile(targetName + "_target.txt"); FileInfo targetNoNoisePath = outputDir.CombineFile(targetName + "_targetNoNoise.txt"); FileInfo noisePath = outputDir.CombineFile(targetName + "_noise.txt"); FileInfo targetImagePath = outputDir.CombineFile(targetName + "_target.png"); FileInfo paramsPath = outputDir.CombineFile(targetName + "_params.txt"); Log.WriteIfVerbose("# Output folder =" + outputDir); //i: GET RECORDING AudioRecording recording = new AudioRecording(input.FullName); //if (recording.SampleRate != 22050) recording.ConvertSampleRate22kHz(); THIS METHOD CALL IS OBSOLETE int sr = recording.SampleRate; //ii: READ PARAMETER VALUES FROM INI FILE var config = new ConfigDictionary(arguments.Config); Dictionary <string, string> dict = config.GetTable(); // framing parameters //double frameOverlap = FeltTemplates_Use.FeltFrameOverlap; // default = 0.5 double frameOverlap = double.Parse(dict["FRAME_OVERLAP"]); //frequency band int minHz = int.Parse(dict["MIN_HZ"]); int maxHz = int.Parse(dict["MAX_HZ"]); // oscillation OD parameters double dctDuration = double.Parse(dict[OscillationRecogniser.key_DCT_DURATION]); // 2.0; // seconds double dctThreshold = double.Parse(dict[OscillationRecogniser.key_DCT_THRESHOLD]); // 0.5; int minOscilFreq = int.Parse(dict[OscillationRecogniser.key_MIN_OSCIL_FREQ]); // 4; int maxOscilFreq = int.Parse(dict[OscillationRecogniser.key_MAX_OSCIL_FREQ]); // 5; bool normaliseDCT = false; // iii initialize the sonogram config class. SonogramConfig sonoConfig = new SonogramConfig(); //default values config sonoConfig.SourceFName = recording.BaseName; //sonoConfig.WindowSize = windowSize; sonoConfig.WindowOverlap = frameOverlap; // iv: generate the sonogram BaseSonogram sonogram = new SpectrogramStandard(sonoConfig, recording.WavReader); Log.WriteLine("Frames: Size={0}, Count={1}, Duration={2:f1}ms, Overlap={5:f2}%, Offset={3:f1}ms, Frames/s={4:f1}", sonogram.Configuration.WindowSize, sonogram.FrameCount, sonogram.FrameDuration * 1000, sonogram.FrameStep * 1000, sonogram.FramesPerSecond, frameOverlap); int binCount = (int)(maxHz / sonogram.FBinWidth) - (int)(minHz / sonogram.FBinWidth) + 1; Log.WriteIfVerbose("Freq band: {0} Hz - {1} Hz. (Freq bin count = {2})", minHz, maxHz, binCount); // v: extract the subband energy array Log.WriteLine("# Start extracting target event."); double[] dBArray = SNR.DecibelsInSubband(sonogram.Data, minHz, maxHz, sonogram.FBinWidth); for (int i = 0; i < sonogram.FrameCount; i++) { dBArray[i] /= binCount; // get average dB energy } double Q = 0.0; double SD = 0.0; throw new NotImplementedException("Mike changed the API here, I don't know how to fix it."); dBArray = new[] { 0.0 }; // SNR.NoiseSubtractMode(dBArray, out Q, out SD); double maxDB = 6.0; double dBThreshold = 2 * SD / maxDB; //set dB threshold to 2xSD above background noise dBArray = SNR.NormaliseDecibelArray_ZeroOne(dBArray, maxDB); dBArray = DataTools.filterMovingAverage(dBArray, 7); //Log.WriteLine("Q ={0}", Q); //Log.WriteLine("SD={0}", SD); //Log.WriteLine("Th={0}", dBThreshold); //normalised threshhold // ############################################################################################################################################# // vi: look for oscillation at required OR for ground parrots. double[] odScores = Oscillations2010.DetectOscillationsInScoreArray(dBArray, dctDuration, sonogram.FramesPerSecond, dctThreshold, normaliseDCT, minOscilFreq, maxOscilFreq); //odScores = SNR.NoiseSubtractMode(odScores, out Q, out SD); double maxOD = 1.0; odScores = SNR.NormaliseDecibelArray_ZeroOne(odScores, maxOD); odScores = DataTools.filterMovingAverage(odScores, 5); //odScores = DataTools.NormaliseMatrixValues(odScores); //NormaliseMatrixValues 0 - 1 //double odThreshold = (10 * SD) / maxOD; //set od threshold to 2xSD above background noise //double odThreshold = dctThreshold; double odThreshold = 0.4; Log.WriteLine("Max={0}", odScores.Max()); //Log.WriteLine("Q ={0}", Q); //Log.WriteLine("SD ={0}", SD); Log.WriteLine("Th ={0}", dctThreshold); //normalised threshhold // ############################################################################################################################################# // vii: LOOK FOR GROUND PARROTS USING TEMPLATE var template = GroundParrotRecogniser.ReadGroundParrotTemplateAsList(sonogram); double[] gpScores = DetectEPR(template, sonogram, odScores, odThreshold); gpScores = DataTools.normalise(gpScores); //NormaliseMatrixValues 0 - 1 // ############################################################################################################################################# // iv: SAVE extracted event as matrix of dB intensity values //FileTools.WriteMatrix2File(template, targetPath); // write template values to file PRIOR to noise removal. //FileTools.WriteMatrix2File(templateMinusNoise, targetNoNoisePath); // write template values to file AFTER to noise removal. //FileTools.WriteArray2File(noiseSubband, noisePath); // v: SAVE image of extracted event in the original sonogram string sonogramImagePath = outputDir + Path.GetFileNameWithoutExtension(recordingFileName) + ".png"; //DrawSonogram(sonogram, sonogramImagePath, dBArray, dBThreshold / maxDB, odScores, dctThreshold, gpScores, template); }
} //AddContext2Table() public Tuple <DataTable, DataTable> ProcessCsvFile(FileInfo fiCsvFile, FileInfo fiConfigFile) { DataTable dt = CsvTools.ReadCSVToTable(fiCsvFile.FullName, true); //get original data table if ((dt == null) || (dt.Rows.Count == 0)) { return(null); } //get its column headers var dtHeaders = new List <string>(); var dtTypes = new List <Type>(); foreach (DataColumn col in dt.Columns) { dtHeaders.Add(col.ColumnName); dtTypes.Add(col.DataType); } List <string> displayHeaders = null; //check if config file contains list of display headers if (fiConfigFile != null) { var configuration = new ConfigDictionary(fiConfigFile.FullName); Dictionary <string, string> configDict = configuration.GetTable(); if (configDict.ContainsKey(Keys.DISPLAY_COLUMNS)) { displayHeaders = configDict[Keys.DISPLAY_COLUMNS].Split(',').ToList(); } } //if config file does not exist or does not contain display headers then use the original headers if (displayHeaders == null) { displayHeaders = dtHeaders; //use existing headers if user supplies none. } //now determine how to display tracks in display datatable Type[] displayTypes = new Type[displayHeaders.Count]; bool[] canDisplay = new bool[displayHeaders.Count]; for (int i = 0; i < displayTypes.Length; i++) { displayTypes[i] = typeof(double); canDisplay[i] = false; if (dtHeaders.Contains(displayHeaders[i])) { canDisplay[i] = true; } } DataTable table2Display = DataTableTools.CreateTable(displayHeaders.ToArray(), displayTypes); foreach (DataRow row in dt.Rows) { DataRow newRow = table2Display.NewRow(); for (int i = 0; i < canDisplay.Length; i++) { if (canDisplay[i]) { newRow[displayHeaders[i]] = row[displayHeaders[i]]; } else { newRow[displayHeaders[i]] = 0.0; } } table2Display.Rows.Add(newRow); } //order the table if possible if (dt.Columns.Contains(AudioAnalysisTools.Keys.EVENT_START_ABS)) { dt = DataTableTools.SortTable(dt, AudioAnalysisTools.Keys.EVENT_START_ABS + " ASC"); } else if (dt.Columns.Contains(AudioAnalysisTools.Keys.EVENT_COUNT)) { dt = DataTableTools.SortTable(dt, AudioAnalysisTools.Keys.EVENT_COUNT + " ASC"); } else if (dt.Columns.Contains(AudioAnalysisTools.Keys.INDICES_COUNT)) { dt = DataTableTools.SortTable(dt, AudioAnalysisTools.Keys.INDICES_COUNT + " ASC"); } else if (dt.Columns.Contains(AudioAnalysisTools.Keys.START_MIN)) { dt = DataTableTools.SortTable(dt, AudioAnalysisTools.Keys.START_MIN + " ASC"); } table2Display = NormaliseColumnsOfDataTable(table2Display); return(System.Tuple.Create(dt, table2Display)); } // ProcessCsvFile()
/// <summary> /// A WRAPPER AROUND THE analyser.Analyse(analysisSettings) METHOD /// To be called as an executable with command line arguments. /// </summary> /// <param name="sourcePath"></param> /// <param name="configPath"></param> /// <param name="outputPath"></param> public static int Execute(string[] args) { int status = 0; if (args.Length < 4) { Console.WriteLine("Require at least 4 command line arguments."); status = 1; return(status); } //GET FIRST THREE OBLIGATORY COMMAND LINE ARGUMENTS string recordingPath = args[0]; string configPath = args[1]; string outputDir = args[2]; FileInfo fiSource = new FileInfo(recordingPath); if (!fiSource.Exists) { Console.WriteLine("Source file does not exist: " + recordingPath); status = 2; return(status); } FileInfo fiConfig = new FileInfo(configPath); if (!fiConfig.Exists) { Console.WriteLine("Config file does not exist: " + configPath); status = 2; return(status); } DirectoryInfo diOP = new DirectoryInfo(outputDir); if (!diOP.Exists) { Console.WriteLine("Output directory does not exist: " + outputDir); status = 2; return(status); } //INIT SETTINGS AnalysisSettings analysisSettings = new AnalysisSettings(); analysisSettings.ConfigFile = fiConfig; analysisSettings.AnalysisRunDirectory = diOP; analysisSettings.AudioFile = null; analysisSettings.EventsFile = null; analysisSettings.IndicesFile = null; analysisSettings.ImageFile = null; TimeSpan tsStart = new TimeSpan(0, 0, 0); TimeSpan tsDuration = new TimeSpan(0, 0, 0); var configuration = new ConfigDictionary(analysisSettings.ConfigFile.FullName); analysisSettings.ConfigDict = configuration.GetTable(); //PROCESS REMAINDER OF THE OPTIONAL COMMAND LINE ARGUMENTS for (int i = 3; i < args.Length; i++) { string[] parts = args[i].Split(':'); if (parts[0].StartsWith("-tmpwav")) { var outputWavPath = Path.Combine(outputDir, parts[1]); analysisSettings.AudioFile = new FileInfo(outputWavPath); } else if (parts[0].StartsWith("-events")) { string eventsPath = Path.Combine(outputDir, parts[1]); analysisSettings.EventsFile = new FileInfo(eventsPath); } else if (parts[0].StartsWith("-indices")) { string indicesPath = Path.Combine(outputDir, parts[1]); analysisSettings.IndicesFile = new FileInfo(indicesPath); } else if (parts[0].StartsWith("-sgram")) { string sonoImagePath = Path.Combine(outputDir, parts[1]); analysisSettings.ImageFile = new FileInfo(sonoImagePath); } else if (parts[0].StartsWith("-start")) { int s = Int32.Parse(parts[1]); tsStart = new TimeSpan(0, 0, s); } else if (parts[0].StartsWith("-duration")) { int s = Int32.Parse(parts[1]); tsDuration = new TimeSpan(0, 0, s); if (tsDuration.TotalMinutes > 10) { Console.WriteLine("Segment duration cannot exceed 10 minutes."); status = 3; return(status); } } } //EXTRACT THE REQUIRED RECORDING SEGMENT FileInfo tempF = analysisSettings.AudioFile; if (tsDuration.TotalSeconds == 0) //Process entire file { AudioFilePreparer.PrepareFile(fiSource, tempF, new AudioUtilityRequest { SampleRate = LSKiwiHelper.RESAMPLE_RATE }); //var fiSegment = AudioFilePreparer.PrepareFile(diOutputDir, fiSourceFile, , Human2.RESAMPLE_RATE); } else { AudioFilePreparer.PrepareFile(fiSource, tempF, new AudioUtilityRequest { SampleRate = LSKiwiHelper.RESAMPLE_RATE, OffsetStart = tsStart, OffsetEnd = tsStart.Add(tsDuration) }); //var fiSegmentOfSourceFile = AudioFilePreparer.PrepareFile(diOutputDir, new FileInfo(recordingPath), MediaTypes.MediaTypeWav, TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(3), RESAMPLE_RATE); } //DO THE ANALYSIS //############################################################################################################################################# IAnalyser analyser = new LSKiwi2(); AnalysisResult result = analyser.Analyse(analysisSettings); DataTable dt = result.Data; //############################################################################################################################################# //ADD IN ADDITIONAL INFO TO RESULTS TABLE if (dt != null) { AddContext2Table(dt, tsStart, result.AudioDuration); CsvTools.DataTable2CSV(dt, analysisSettings.EventsFile.FullName); //DataTableTools.WriteTable(augmentedTable); } else { return(-993); //error!! } return(status); }
public static void Execute(Arguments arguments) { string date = "# DATE AND TIME: " + DateTime.Now; Log.WriteLine("# DETECTING LOW FREQUENCY AMPLITUDE OSCILLATIONS"); Log.WriteLine(date); Log.Verbosity = 1; FileInfo recordingFile = arguments.Source; FileInfo iniPath = arguments.Config.ToFileInfo(); DirectoryInfo outputDir = arguments.Output; string opFName = "OcillationReconiserResults.cav"; string opPath = outputDir + opFName; Log.WriteIfVerbose("# Output folder =" + outputDir); //READ PARAMETER VALUES FROM INI FILE var config = new ConfigDictionary(iniPath); Dictionary <string, string> dict = config.GetTable(); Dictionary <string, string> .KeyCollection keys = dict.Keys; bool doSegmentation = bool.Parse(dict[key_DO_SEGMENTATION]); int minHz = int.Parse(dict[key_MIN_HZ]); int maxHz = int.Parse(dict[key_MAX_HZ]); double frameOverlap = double.Parse(dict[key_FRAME_OVERLAP]); double dctDuration = double.Parse(dict[key_DCT_DURATION]); //duration of DCT in seconds double dctThreshold = double.Parse(dict[key_DCT_THRESHOLD]); //minimum acceptable value of a DCT coefficient int minOscilFreq = int.Parse(dict[key_MIN_OSCIL_FREQ]); //ignore oscillations below this threshold freq int maxOscilFreq = int.Parse(dict[key_MAX_OSCIL_FREQ]); //ignore oscillations above this threshold freq double minDuration = double.Parse(dict[key_MIN_DURATION]); //min duration of event in seconds double maxDuration = double.Parse(dict[key_MAX_DURATION]); //max duration of event in seconds double eventThreshold = double.Parse(dict[key_EVENT_THRESHOLD]); //min score for an acceptable event int DRAW_SONOGRAMS = int.Parse(dict[key_DRAW_SONOGRAMS]); //options to draw sonogram Log.WriteIfVerbose("Freq band: {0} Hz - {1} Hz.)", minHz, maxHz); Log.WriteIfVerbose("Oscill bounds: " + minOscilFreq + " - " + maxOscilFreq + " Hz"); Log.WriteIfVerbose("minAmplitude = " + dctThreshold); Log.WriteIfVerbose("Duration bounds: " + minDuration + " - " + maxDuration + " seconds"); //############################################################################################################################################# var results = Execute_ODDetect(recordingFile, doSegmentation, minHz, maxHz, frameOverlap, dctDuration, dctThreshold, minOscilFreq, maxOscilFreq, eventThreshold, minDuration, maxDuration); Log.WriteLine("# Finished detecting oscillation events."); //############################################################################################################################################# var sonogram = results.Item1; var hits = results.Item2; var scores = results.Item3; var predictedEvents = results.Item4; var intensity = results.Item5; var analysisDuration = results.Item6; Log.WriteLine("# Event Count = " + predictedEvents.Count()); int pcHIF = 100; if (intensity != null) { int hifCount = intensity.Count(p => p >= 0.001); //count of high intensity frames pcHIF = 100 * hifCount / sonogram.FrameCount; } //write event count to results file. double sigDuration = sonogram.Duration.TotalSeconds; string fname = recordingFile.BaseName(); int count = predictedEvents.Count; //string str = String.Format("#RecordingName\tDuration(sec)\t#Ev\tCompT(ms)\t%hiFrames\n{0}\t{1}\t{2}\t{3}\t{4}\n", fname, sigDuration, count, analysisDuration.TotalMilliseconds, pcHIF); string str = string.Format("{0}\t{1}\t{2}\t{3}\t{4}", fname, sigDuration, count, analysisDuration.TotalMilliseconds, pcHIF); StringBuilder sb = AcousticEvent.WriteEvents(predictedEvents, str); FileTools.WriteTextFile(opPath, sb.ToString()); //draw images of sonograms string imagePath = outputDir + fname + ".png"; if (DRAW_SONOGRAMS == 2) { DrawSonogram(sonogram, imagePath, hits, scores, predictedEvents, eventThreshold, intensity); } else if (DRAW_SONOGRAMS == 1 && predictedEvents.Count > 0) { DrawSonogram(sonogram, imagePath, hits, scores, predictedEvents, eventThreshold, intensity); } Log.WriteLine("# Finished recording:- " + recordingFile.Name); }
/// <summary> /// Wraps up the resources into a template.ZIP file /// and then runs a test on the source recording. /// </summary> public static void Execute(Arguments arguments) { if (arguments == null) { arguments = Dev(); } string title = "# EDIT TEMPLATE."; string date = "# DATE AND TIME: " + DateTime.Now; Log.WriteLine(title); Log.WriteLine(date); //ZIP THE OUTPUT FILES const bool ZipOutput = true; FileInfo iniPath = arguments.Config; string[] nameComponents = (Path.GetFileNameWithoutExtension(iniPath.Name)).Split('_'); string targetName = nameComponents[0] + "_" + nameComponents[1]; //i: Set up the file names DirectoryInfo outputDir = iniPath.Directory; FileInfo targetImagePath = outputDir.CombineFile(targetName + "_target.png"); // input image file FileInfo binaryOpPath = outputDir.CombineFile(targetName + "_binary.bmp"); FileInfo trinaryOpPath = outputDir.CombineFile(targetName + "_trinary.bmp"); FileInfo sprOpPath = outputDir.CombineFile(targetName + "_spr.txt"); // syntactic pattern recognition file //additional files to be zipped up with template FileInfo targetPath = outputDir.CombineFile(targetName + "_target.txt"); FileInfo targetNoNoisePath = outputDir.CombineFile(targetName + "_targetNoNoise.txt"); FileInfo noisePath = outputDir.CombineFile(targetName + "_noise.txt"); //ii: READ PARAMETER VALUES FROM INI FILE var config = new ConfigDictionary(iniPath); Dictionary <string, string> dict = config.GetTable(); string sourceFile = dict[FeltTemplate_Create.key_SOURCE_RECORDING]; string sourceDir = dict[FeltTemplate_Create.key_SOURCE_DIRECTORY]; double dB_Threshold = double.Parse(dict[FeltTemplate_Create.key_DECIBEL_THRESHOLD]); double maxTemplateIntensity = double.Parse(dict[FeltTemplate_Create.key_TEMPLATE_MAX_INTENSITY]); int neighbourhood = int.Parse(dict[FeltTemplate_Create.key_DONT_CARE_NH]); //the do not care neighbourhood int lineLength = int.Parse(dict[FeltTemplate_Create.key_LINE_LENGTH]); double templateThreshold = dB_Threshold / maxTemplateIntensity; int bitmapThreshold = (int)(255 - (templateThreshold * 255)); Log.WriteLine("#################################### WRITE THE BINARY TEMPLATE ##################################"); Bitmap bitmap = ImageTools.ReadImage2Bitmap(targetImagePath.FullName); var binaryBmp = Image2BinaryBitmap(bitmap, bitmapThreshold); binaryBmp.Save(binaryOpPath.FullName); Log.WriteLine("#################################### WRITE THE TRINARY TEMPLATE ##################################"); var trinaryBmp = Image2TrinaryBitmap(binaryBmp, neighbourhood); trinaryBmp.Save(trinaryOpPath.FullName); Log.WriteLine("#################################### WRITE THE SPR TEMPLATE ##################################"); double[,] matrix = ImageTools.GreyScaleImage2Matrix(bitmap); matrix = DataTools.MatrixRotate90Clockwise(matrix); //rows=time cols=freq. //ImageTools.DrawMatrix(matrix, @"C:\SensorNetworks\Output\FELT_LewinsRail1\SPR_output1.bmp"); //int smallLengthThreshold = 10; //var tuple = SPT.doSPT(matrix, templateThreshold, smallLengthThreshold); //matrix = tuple.Item1; //ImageTools.DrawMatrix(matrix, @"C:\SensorNetworks\Output\FELT_LewinsRail1\SPR_output2.bmp"); char[,] spr = SprTools.Target2SymbolicTracks(matrix, templateThreshold, lineLength); FileTools.WriteMatrix2File(spr, sprOpPath.FullName); var tuple1 = FindMatchingEvents.Execute_One_Spr_Match(spr, matrix, templateThreshold); double sprScore = tuple1.Item1; double dBScore = sprScore * maxTemplateIntensity; Log.WriteLine("#################################### WRITE THE OSCILATION TEMPLATE ##################################"); double[,] target = FileTools.ReadDoubles2Matrix(targetPath.FullName); // oscillations in time double[,] rotatedtarget = DataTools.MatrixRotate90Clockwise(target); var colSums = DataTools.GetColumnsAverages(rotatedtarget); double[] periods = Oscillations2010.PeriodicityAnalysis(colSums); // frame periodicity LoggedConsole.WriteLine("Periodicity (sec) = {0:f3}, {1:f3}, {2:f3}", periods[0] * FeltTemplates_Use.FeltFrameOffset, periods[1] * FeltTemplates_Use.FeltFrameOffset, periods[2] * FeltTemplates_Use.FeltFrameOffset); //double oscilFreq = indexOfMaxValue / dctDuration * 0.5; //Times 0.5 because index = Pi and not 2Pi // oscillations in freq i.e. harmonics colSums = DataTools.GetColumnsAverages(target); periods = Oscillations2010.PeriodicityAnalysis(colSums); LoggedConsole.WriteLine("Periodicity (Hz) = {0:f0}, {1:f0}, {2:f0}.", periods[0] * FeltTemplates_Use.FeltFreqBinWidth, periods[1] * FeltTemplates_Use.FeltFreqBinWidth, periods[2] * FeltTemplates_Use.FeltFreqBinWidth); //double oscilFreq = indexOfMaxValue / dctDuration * 0.5; //Times 0.5 because index = Pi and not 2Pi //FileTools.WriteMatrix2File(spr, sprOpPath); // ZIP THE OUTPUT Log.WriteLine("#################################### ZIP THE TEMPLATES ##################################"); if (ZipOutput == true) { var filenames = new[] { iniPath, targetImagePath, binaryOpPath, targetPath, targetNoNoisePath, noisePath }; string biOutZipFile = outputDir + targetName + "_binaryTemplate.zip"; //FileTools.ZipFiles(filenames, biOutZipFile); filenames = new[] { iniPath, targetImagePath, trinaryOpPath, targetPath, targetNoNoisePath, noisePath }; string triOutZipFile = outputDir + targetName + "_trinaryTemplate.zip"; //FileTools.ZipFiles(filenames, triOutZipFile); filenames = new[] { iniPath, targetImagePath, sprOpPath, targetPath, targetNoNoisePath, noisePath }; string sprOutZipFile = outputDir + targetName + "_syntacticTemplate.zip"; //FileTools.ZipFiles(filenames, sprOutZipFile); // Zipping files can be done by using standard .NET 4.6 System.IO.Compression // however, this code hasn't been used in years and I've opted to just comment out the lines above throw new NotImplementedException("Zipping template files intentionally broken"); } Log.WriteLine("\n\n#################################### TEST THE EXTRACTED EVENT ON SOURCE FILE ##################################"); //vi: TEST THE EVENT ON ANOTHER FILE //felt "C:\SensorNetworks\WavFiles\Canetoad\DM420010_128m_00s__130m_00s - Toads.mp3" C:\SensorNetworks\Output\FELT_CaneToad\FELT_CaneToad_Params.txt events.txt //string testRecording = @"C:\SensorNetworks\WavFiles\Gecko\Suburban_March2010\geckos_suburban_104.mp3"; //string testRecording = @"C:\SensorNetworks\WavFiles\Gecko\Suburban_March2010\geckos_suburban_18.mp3"; //string testRecording = @"C:\SensorNetworks\WavFiles\Currawongs\Currawong_JasonTagged\West_Knoll_Bees_20091102-170000.mp3"; //string testRecording = @"C:\SensorNetworks\WavFiles\Curlew\Curlew2\Top_Knoll_-_St_Bees_20090517-210000.wav"; string listOpDir = "C:\\SensorNetworks\\Output\\FELT_templateList\\"; string templateListPath = listOpDir + "templateTestList.txt"; var list = new List <string>(); list.Add("#" + outputDir + targetName + "_binaryTemplate.zip"); list.Add("#" + outputDir + targetName + "_trinaryTemplate.zip"); list.Add("#" + outputDir + targetName + "_syntacticTemplate.zip"); FileTools.Append2TextFile(templateListPath, list); //write the template.ZIP file //TEST THE TEMPLATE ON SOURCE FILE //string[] arguments = new string[3]; /* * var args = new FeltTemplates_Use.Arguments() * { * Source = "", * arguments[0] = sourceDir + "\\" + sourceFile; * arguments[1] = templateListPath; * arguments[2] = listOpDir; * * }*/ //FeltTemplates_Use.Dev(arguments); Log.WriteLine("# Finished everything!"); }
public static void Execute(Arguments arguments) { MainEntry.WarnIfDevleoperEntryUsed(); string date = "# DATE AND TIME: " + DateTime.Now; Log.WriteLine("# SEGMENTING A RECORDING"); Log.WriteLine(date); Log.Verbosity = 1; FileInfo recordingPath = arguments.Source; FileInfo iniPath = arguments.Config.ToFileInfo(); DirectoryInfo outputDir = arguments.Output; string opFName = "segment-output.txt"; FileInfo opPath = outputDir.CombineFile(opFName); Log.WriteIfVerbose("# Output folder =" + outputDir); //READ PARAMETER VALUES FROM INI FILE var config = new ConfigDictionary(iniPath); Dictionary <string, string> dict = config.GetTable(); Dictionary <string, string> .KeyCollection keys = dict.Keys; int minHz = int.Parse(dict[key_MIN_HZ]); int maxHz = int.Parse(dict[key_MAX_HZ]); double frameOverlap = double.Parse(dict[key_FRAME_OVERLAP]); double smoothWindow = double.Parse(dict[key_SMOOTH_WINDOW]); //smoothing window (seconds) before segmentation double thresholdSD = double.Parse(dict[key_THRESHOLD]); //segmentation threshold in noise SD double minDuration = double.Parse(dict[key_MIN_DURATION]); //min duration of segment & width of smoothing window in seconds double maxDuration = double.Parse(dict[key_MAX_DURATION]); //max duration of segment in seconds int DRAW_SONOGRAMS = int.Parse(dict[key_DRAW_SONOGRAMS]); //options to draw sonogram Log.WriteIfVerbose("# Freq band: {0} Hz - {1} Hz.)", minHz, maxHz); Log.WriteIfVerbose("# Smoothing Window: {0}s.", smoothWindow); Log.WriteIfVerbose("# Duration bounds: " + minDuration + " - " + maxDuration + " seconds"); //############################################################################################################################################# var results = Execute_Segmentation(recordingPath, minHz, maxHz, frameOverlap, smoothWindow, thresholdSD, minDuration, maxDuration); Log.WriteLine("# Finished detecting segments."); //############################################################################################################################################# var sonogram = results.Item1; var predictedEvents = results.Item2; //contain the segments detected var Q = results.Item3; var oneSD_dB = results.Item4; var dBThreshold = results.Item5; var intensity = results.Item6; Log.WriteLine("# Signal: Duration={0}, Sample Rate={1}", sonogram.Duration, sonogram.SampleRate); Log.WriteLine("# Frames: Size={0}, Count={1}, Duration={2:f1}ms, Overlap={5:f0}%, Offset={3:f1}ms, Frames/s={4:f1}", sonogram.Configuration.WindowSize, sonogram.FrameCount, sonogram.FrameDuration * 1000, sonogram.FrameStep * 1000, sonogram.FramesPerSecond, frameOverlap); int binCount = (int)(maxHz / sonogram.FBinWidth) - (int)(minHz / sonogram.FBinWidth) + 1; Log.WriteLine("# FreqBand: {0} Hz - {1} Hz. (Freq bin count = {2})", minHz, maxHz, binCount); Log.WriteLine("# Intensity array - noise removal: Q={0:f1}dB. 1SD={1:f3}dB. Threshold={2:f3}dB.", Q, oneSD_dB, dBThreshold); Log.WriteLine("# Events: Count={0}", predictedEvents.Count()); int pcHIF = 100; if (intensity != null) { int hifCount = intensity.Count(p => p > dBThreshold); //count of high intensity frames pcHIF = 100 * hifCount / sonogram.FrameCount; } //write event count to results file. double sigDuration = sonogram.Duration.TotalSeconds; string fname = recordingPath.Name; int count = predictedEvents.Count; //string str = String.Format("#RecordingName\tDuration(sec)\t#Ev\tCompT(ms)\t%hiFrames\n{0}\t{1}\t{2}\t{3}\t{4}\n", fname, sigDuration, count, analysisDuration.TotalMilliseconds, pcHIF); //StringBuilder sb = new StringBuilder(str); //StringBuilder sb = new StringBuilder(); string str = string.Format("{0}\t{1}\t{2}\t{3}", fname, sigDuration, count, pcHIF); StringBuilder sb = AcousticEvent.WriteEvents(predictedEvents, str); FileTools.WriteTextFile(opPath.FullName, sb.ToString()); //draw images of sonograms string imagePath = outputDir + Path.GetFileNameWithoutExtension(recordingPath.Name) + ".png"; double min, max; DataTools.MinMax(intensity, out min, out max); double threshold_norm = dBThreshold / max; //min = 0.0; intensity = DataTools.normalise(intensity); if (DRAW_SONOGRAMS == 2) { DrawSonogram(sonogram, imagePath, predictedEvents, threshold_norm, intensity); } else if (DRAW_SONOGRAMS == 1 && predictedEvents.Count > 0) { DrawSonogram(sonogram, imagePath, predictedEvents, threshold_norm, intensity); } Log.WriteLine("# Finished recording:- " + recordingPath.Name); }
public Tuple <DataTable, DataTable> ProcessCsvFile(FileInfo fiCsvFile, FileInfo fiConfigFile) { DataTable dt = CsvTools.ReadCSVToTable(fiCsvFile.FullName, true); //get original data table if ((dt == null) || (dt.Rows.Count == 0)) { return(null); } //get its column headers var dtHeaders = new List <string>(); var dtTypes = new List <Type>(); foreach (DataColumn col in dt.Columns) { dtHeaders.Add(col.ColumnName); dtTypes.Add(col.DataType); } List <string> displayHeaders = null; //check if config file contains list of display headers if (fiConfigFile != null) { var configuration = new ConfigDictionary(fiConfigFile.FullName); Dictionary <string, string> configDict = configuration.GetTable(); if (configDict.ContainsKey(AnalysisKeys.DisplayColumns)) { displayHeaders = configDict[AnalysisKeys.DisplayColumns].Split(',').ToList(); } } //if config file does not exist or does not contain display headers then use the original headers if (displayHeaders == null) { displayHeaders = dtHeaders; //use existing headers if user supplies none. } //now determine how to display tracks in display datatable Type[] displayTypes = new Type[displayHeaders.Count]; bool[] canDisplay = new bool[displayHeaders.Count]; for (int i = 0; i < displayTypes.Length; i++) { displayTypes[i] = typeof(double); canDisplay[i] = false; if (dtHeaders.Contains(displayHeaders[i])) { canDisplay[i] = true; } } DataTable table2Display = DataTableTools.CreateTable(displayHeaders.ToArray(), displayTypes); foreach (DataRow row in dt.Rows) { DataRow newRow = table2Display.NewRow(); for (int i = 0; i < canDisplay.Length; i++) { if (canDisplay[i]) { newRow[displayHeaders[i]] = row[displayHeaders[i]]; } else { newRow[displayHeaders[i]] = 0.0; } } table2Display.Rows.Add(newRow); } //order the table if possible if (dt.Columns.Contains(AnalysisKeys.EventStartAbs)) { dt = DataTableTools.SortTable(dt, AnalysisKeys.EventStartAbs + " ASC"); } else if (dt.Columns.Contains(AnalysisKeys.EventCount)) { dt = DataTableTools.SortTable(dt, AnalysisKeys.EventCount + " ASC"); } else if (dt.Columns.Contains(AnalysisKeys.KeyRankOrder)) { dt = DataTableTools.SortTable(dt, AnalysisKeys.KeyRankOrder + " ASC"); } else if (dt.Columns.Contains(AnalysisKeys.KeyStartMinute)) { dt = DataTableTools.SortTable(dt, AnalysisKeys.KeyStartMinute + " ASC"); } //this depracted now that use class indexProperties to do normalisation //table2Display = NormaliseColumnsOfDataTable(table2Display); //add in column of weighted indices //bool addColumnOfweightedIndices = true; //if (addColumnOfweightedIndices) //{ // double[] comboWts = IndexCalculate.CalculateComboWeights(); // double[] weightedIndices = IndexCalculate.GetArrayOfWeightedAcousticIndices(dt, comboWts); // string colName = "WeightedIndex"; // DataTableTools.AddColumnOfDoubles2Table(table2Display, colName, weightedIndices); //} return(Tuple.Create(dt, table2Display)); } // ProcessCsvFile()
public static void Execute(Arguments arguments) { if (arguments == null) { arguments = Dev(); } const string Title = "# EXTRACT AND SAVE ACOUSTIC EVENT."; string date = "# DATE AND TIME: " + DateTime.Now; Log.WriteLine(Title); Log.WriteLine(date); FileInfo recordingPath = arguments.Source; FileInfo iniPath = arguments.Config; // path of the ini or params file string targetName = arguments.Target; // prefix of name of created files DirectoryInfo outputDir = iniPath.Directory; FileInfo targetPath = outputDir.CombineFile(targetName + "_target.txt"); FileInfo targetNoNoisePath = outputDir.CombineFile(targetName + "_targetNoNoise.txt"); FileInfo noisePath = outputDir.CombineFile(targetName + "_noise.txt"); FileInfo targetImagePath = outputDir.CombineFile(targetName + "_target.png"); FileInfo paramsPath = outputDir.CombineFile(targetName + "_params.txt"); FileInfo sonogramImagePath = outputDir.CombineFile(Path.GetFileNameWithoutExtension(recordingPath.Name) + ".png"); Log.WriteIfVerbose("# Output folder =" + outputDir); //i: GET RECORDING AudioRecording recording = new AudioRecording(recordingPath.FullName); //if (recording.SampleRate != 22050) recording.ConvertSampleRate22kHz(); // THIS METHOD CALL IS OBSOLETE int sr = recording.SampleRate; //ii: READ PARAMETER VALUES FROM INI FILE var config = new ConfigDictionary(iniPath); Dictionary <string, string> dict = config.GetTable(); //Dictionary<string, string>.KeyCollection keys = dict.Keys; double frameOverlap = FeltTemplates_Use.FeltFrameOverlap; // Double.Parse(dict[key_FRAME_OVERLAP]); double eventStart = double.Parse(dict[key_EVENT_START]); double eventEnd = double.Parse(dict[key_EVENT_END]); int minHz = int.Parse(dict[key_MIN_HZ]); int maxHz = int.Parse(dict[key_MAX_HZ]); double dBThreshold = double.Parse(dict[key_DECIBEL_THRESHOLD]); //threshold to set MIN DECIBEL BOUND int DRAW_SONOGRAMS = int.Parse(dict[key_DRAW_SONOGRAMS]); //options to draw sonogram // iii: Extract the event as TEMPLATE // ############################################################################################################################################# Log.WriteLine("# Start extracting target event."); var results = Execute_Extraction(recording, eventStart, eventEnd, minHz, maxHz, frameOverlap, dBThreshold, TimeSpan.Zero); var sonogram = results.Item1; var extractedEvent = results.Item2; var template = results.Item3; // event's matrix of target values before noise removal var noiseSubband = results.Item4; // event's array of noise values var templateMinusNoise = results.Item5; // event's matrix of target values after noise removal Log.WriteLine("# Finished extracting target event."); // ############################################################################################################################################# // iv: SAVE extracted event as matrix of dB intensity values FileTools.WriteMatrix2File(template, targetPath.FullName); // write template values to file PRIOR to noise removal. FileTools.WriteMatrix2File(templateMinusNoise, targetNoNoisePath.FullName); // write template values to file AFTER to noise removal. FileTools.WriteArray2File(noiseSubband, noisePath.FullName); // v: SAVE image of extracted event in the original sonogram DrawSonogram(sonogram, sonogramImagePath.FullName, extractedEvent); // vi: SAVE extracted event as noise reduced image // alter matrix dynamic range so user can determine correct dynamic range from image // matrix = SNR.SetDynamicRange(matrix, 0.0, dynamicRange); // set event's dynamic range var results1 = BaseSonogram.Data2ImageData(templateMinusNoise); var targetImage = results1.Item1; var min = results1.Item2; var max = results1.Item3; ImageTools.DrawMatrix(targetImage, 1, 1, targetImagePath.FullName); // vii: SAVE parameters file dict.Add(key_SOURCE_DIRECTORY, arguments.Source.DirectoryName); dict.Add(key_SOURCE_RECORDING, arguments.Source.Name); dict.Add(key_TEMPLATE_MIN_INTENSITY, min.ToString()); dict.Add(key_TEMPLATE_MAX_INTENSITY, max.ToString()); WriteParamsFile(paramsPath.FullName, dict); Log.WriteLine("# Finished everything!"); }
public static void Execute(Arguments arguments) { if (arguments == null) { arguments = Dev(); } LoggedConsole.WriteLine("DATE AND TIME:" + DateTime.Now); LoggedConsole.WriteLine("Syntactic Pattern Recognition\n"); //StringBuilder sb = new StringBuilder("DATE AND TIME:" + DateTime.Now + "\n"); //sb.Append("SCAN ALL RECORDINGS IN A DIRECTORY USING HTK-RECOGNISER\n"); Log.Verbosity = 1; FileInfo recordingPath = arguments.Source; FileInfo iniPath = arguments.Config; DirectoryInfo outputDir = arguments.Output; string opFName = "SPR-output.txt"; string opPath = outputDir + opFName; Log.WriteIfVerbose("# Output folder =" + outputDir); // A: READ PARAMETER VALUES FROM INI FILE var config = new ConfigDictionary(iniPath); Dictionary <string, string> dict = config.GetTable(); Dictionary <string, string> .KeyCollection keys = dict.Keys; string callName = dict[key_CALL_NAME]; double frameOverlap = Convert.ToDouble(dict[key_FRAME_OVERLAP]); //SPT PARAMETERS double intensityThreshold = Convert.ToDouble(dict[key_SPT_INTENSITY_THRESHOLD]); int smallLengthThreshold = Convert.ToInt32(dict[key_SPT_SMALL_LENGTH_THRESHOLD]); //WHIPBIRD PARAMETERS int whistle_MinHz = int.Parse(dict[key_WHISTLE_MIN_HZ]); int whistle_MaxHz = int.Parse(dict[key_WHISTLE_MAX_HZ]); double optimumWhistleDuration = double.Parse(dict[key_WHISTLE_DURATION]); //optimum duration of whistle in seconds int whip_MinHz = (dict.ContainsKey(key_WHIP_MIN_HZ)) ? int.Parse(dict[key_WHIP_MIN_HZ]) : 0; int whip_MaxHz = (dict.ContainsKey(key_WHIP_MAX_HZ)) ? int.Parse(dict[key_WHIP_MAX_HZ]) : 0; double whipDuration = (dict.ContainsKey(key_WHIP_DURATION)) ? double.Parse(dict[key_WHIP_DURATION]) : 0.0; //duration of whip in seconds //CURLEW PARAMETERS double minDuration = (dict.ContainsKey(key_MIN_DURATION)) ? double.Parse(dict[key_MIN_DURATION]) : 0.0; //min duration of call in seconds double maxDuration = (dict.ContainsKey(key_MAX_DURATION)) ? double.Parse(dict[key_MAX_DURATION]) : 0.0; //duration of call in seconds double eventThreshold = double.Parse(dict[key_EVENT_THRESHOLD]); //min score for an acceptable event int DRAW_SONOGRAMS = Convert.ToInt16(dict[key_DRAW_SONOGRAMS]); // B: CHECK to see if conversion from .MP3 to .WAV is necessary var destinationAudioFile = recordingPath; //LOAD RECORDING AND MAKE SONOGRAM BaseSonogram sonogram = null; using (var recording = new AudioRecording(destinationAudioFile.FullName)) { // if (recording.SampleRate != 22050) recording.ConvertSampleRate22kHz(); // THIS METHOD CALL IS OBSOLETE var sonoConfig = new SonogramConfig { NoiseReductionType = NoiseReductionType.None, //NoiseReductionType = NoiseReductionType.STANDARD, WindowOverlap = frameOverlap, }; sonogram = new SpectrogramStandard(sonoConfig, recording.WavReader); } List <AcousticEvent> predictedEvents = null; double[,] hits = null; double[] scores = null; var audioFileName = Path.GetFileNameWithoutExtension(destinationAudioFile.FullName); if (callName.Equals("WHIPBIRD")) { //SPT var result1 = SPT.doSPT(sonogram, intensityThreshold, smallLengthThreshold); //SPR Log.WriteLine("SPR start: intensity threshold = " + intensityThreshold); int slope = 0; //degrees of the circle. i.e. 90 = vertical line. double sensitivity = 0.7; //lower value = more sensitive var mHori = MarkLine(result1.Item1, slope, smallLengthThreshold, intensityThreshold, sensitivity); slope = 87; //84 sensitivity = 0.8; //lower value = more sensitive var mVert = MarkLine(result1.Item1, slope, smallLengthThreshold - 4, intensityThreshold + 1, sensitivity); Log.WriteLine("SPR finished"); Log.WriteLine("Extract Whipbird calls - start"); int minBound_Whistle = (int)(whistle_MinHz / sonogram.FBinWidth); int maxBound_Whistle = (int)(whistle_MaxHz / sonogram.FBinWidth); int whistleFrames = (int)(sonogram.FramesPerSecond * optimumWhistleDuration); //86 = frames/sec. int minBound_Whip = (int)(whip_MinHz / sonogram.FBinWidth); int maxBound_Whip = (int)(whip_MaxHz / sonogram.FBinWidth); int whipFrames = (int)(sonogram.FramesPerSecond * whipDuration); //86 = frames/sec. var result3 = DetectWhipBird(mHori, mVert, minBound_Whistle, maxBound_Whistle, whistleFrames, minBound_Whip, maxBound_Whip, whipFrames, smallLengthThreshold); scores = result3.Item1; hits = DataTools.AddMatrices(mHori, mVert); predictedEvents = AcousticEvent.ConvertScoreArray2Events( scores, whip_MinHz, whip_MaxHz, sonogram.FramesPerSecond, sonogram.FBinWidth, eventThreshold, minDuration, maxDuration, TimeSpan.Zero); foreach (AcousticEvent ev in predictedEvents) { ev.FileName = audioFileName; ev.Name = callName; } sonogram.Data = result1.Item1; Log.WriteLine("Extract Whipbird calls - finished"); } else if (callName.Equals("CURLEW")) { //SPT double backgroundThreshold = 4.0; var result1 = SNR.NoiseReduce(sonogram.Data, NoiseReductionType.Standard, backgroundThreshold); //var result1 = SPT.doSPT(sonogram, intensityThreshold, smallLengthThreshold); //var result1 = doNoiseRemoval(sonogram, intensityThreshold, smallLengthThreshold); //SPR Log.WriteLine("SPR start: intensity threshold = " + intensityThreshold); int slope = 20; //degrees of the circle. i.e. 90 = vertical line. double sensitivity = 0.8; //lower value = more sensitive var mHori = MarkLine(result1.Item1, slope, smallLengthThreshold, intensityThreshold, sensitivity); slope = 160; sensitivity = 0.8; //lower value = more sensitive var mVert = MarkLine(result1.Item1, slope, smallLengthThreshold - 3, intensityThreshold + 1, sensitivity); Log.WriteLine("SPR finished"); //detect curlew calls int minBound_Whistle = (int)(whistle_MinHz / sonogram.FBinWidth); int maxBound_Whistle = (int)(whistle_MaxHz / sonogram.FBinWidth); int whistleFrames = (int)(sonogram.FramesPerSecond * optimumWhistleDuration); var result3 = DetectCurlew(mHori, mVert, minBound_Whistle, maxBound_Whistle, whistleFrames, smallLengthThreshold); //process curlew scores - look for curlew characteristic periodicity double minPeriod = 1.2; double maxPeriod = 1.8; int minPeriod_frames = (int)Math.Round(sonogram.FramesPerSecond * minPeriod); int maxPeriod_frames = (int)Math.Round(sonogram.FramesPerSecond * maxPeriod); scores = DataTools.filterMovingAverage(result3.Item1, 21); scores = DataTools.PeriodicityDetection(scores, minPeriod_frames, maxPeriod_frames); //extract events predictedEvents = AcousticEvent.ConvertScoreArray2Events( scores, whistle_MinHz, whistle_MaxHz, sonogram.FramesPerSecond, sonogram.FBinWidth, eventThreshold, minDuration, maxDuration, TimeSpan.Zero); foreach (AcousticEvent ev in predictedEvents) { ev.FileName = audioFileName; ev.Name = callName; } hits = DataTools.AddMatrices(mHori, mVert); sonogram.Data = result1.Item1; Log.WriteLine("Extract Curlew calls - finished"); } else if (callName.Equals("CURRAWONG")) { //SPT var result1 = SPT.doSPT(sonogram, intensityThreshold, smallLengthThreshold); //SPR Log.WriteLine("SPR start: intensity threshold = " + intensityThreshold); int slope = 70; //degrees of the circle. i.e. 90 = vertical line. //slope = 210; double sensitivity = 0.7; //lower value = more sensitive var mHori = MarkLine(result1.Item1, slope, smallLengthThreshold, intensityThreshold, sensitivity); slope = 110; //slope = 340; sensitivity = 0.7; //lower value = more sensitive var mVert = MarkLine(result1.Item1, slope, smallLengthThreshold - 3, intensityThreshold + 1, sensitivity); Log.WriteLine("SPR finished"); int minBound_Whistle = (int)(whistle_MinHz / sonogram.FBinWidth); int maxBound_Whistle = (int)(whistle_MaxHz / sonogram.FBinWidth); int whistleFrames = (int)(sonogram.FramesPerSecond * optimumWhistleDuration); //86 = frames/sec. var result3 = DetectCurlew(mHori, mVert, minBound_Whistle, maxBound_Whistle, whistleFrames + 10, smallLengthThreshold); scores = result3.Item1; hits = DataTools.AddMatrices(mHori, mVert); predictedEvents = AcousticEvent.ConvertIntensityArray2Events( scores, TimeSpan.Zero, whistle_MinHz, whistle_MaxHz, sonogram.FramesPerSecond, sonogram.FBinWidth, eventThreshold, 0.5, maxDuration); foreach (AcousticEvent ev in predictedEvents) { ev.FileName = audioFileName; //ev.Name = callName; } } //write event count to results file. double sigDuration = sonogram.Duration.TotalSeconds; //string fname = Path.GetFileName(recordingPath); int count = predictedEvents.Count; Log.WriteIfVerbose("Number of Events: " + count); string str = string.Format("{0}\t{1}\t{2}", callName, sigDuration, count); FileTools.WriteTextFile(opPath, AcousticEvent.WriteEvents(predictedEvents, str).ToString()); // SAVE IMAGE string imageName = outputDir + audioFileName; string imagePath = imageName + ".png"; if (File.Exists(imagePath)) { int suffix = 1; while (File.Exists(imageName + "." + suffix.ToString() + ".png")) { suffix++; } //{ // suffix = (suffix == string.Empty) ? "1" : (int.Parse(suffix) + 1).ToString(); //} //File.Delete(outputDir + audioFileName + "." + suffix.ToString() + ".png"); File.Move(imagePath, imageName + "." + suffix.ToString() + ".png"); } //string newPath = imagePath + suffix + ".png"; if (DRAW_SONOGRAMS == 2) { DrawSonogram(sonogram, imagePath, hits, scores, predictedEvents, eventThreshold); } else if ((DRAW_SONOGRAMS == 1) && (predictedEvents.Count > 0)) { DrawSonogram(sonogram, imagePath, hits, scores, predictedEvents, eventThreshold); } Log.WriteIfVerbose("Image saved to: " + imagePath); //string savePath = outputDir + Path.GetFileNameWithoutExtension(recordingPath); //string suffix = string.Empty; //Image im = sonogram.GetImage(false, false); //string newPath = savePath + suffix + ".jpg"; //im.Save(newPath); LoggedConsole.WriteLine("\nFINISHED RECORDING!"); Console.ReadLine(); }
public static void Execute(Arguments arguments) { if (arguments == null) { arguments = Dev(); } string title = "# FIND OTHER ACOUSTIC EVENTS LIKE THIS"; string date = "# DATE AND TIME: " + DateTime.Now; Log.WriteLine(title); Log.WriteLine(date); Log.Verbosity = 1; Log.WriteIfVerbose("# Recording =" + arguments.Source); //the recording to be scanned Log.WriteIfVerbose("# Template list =" + arguments.Config); //the path to a file containing the paths to template locations, one template per line Log.WriteIfVerbose("# Output folder =" + arguments.Output); //name of output dir var allEvents = new List <AcousticEvent>(); var scoresList = new List <double[]>(); var thresholdList = new List <double>(); //i: GET RECORDING AudioRecording recording = new AudioRecording(arguments.Source.FullName); //if (recording.SampleRate != 22050) recording.ConvertSampleRate22kHz(); // THIS METHOD CALL IS OBSOLETE int sr = recording.SampleRate; //ii: MAKE SONOGRAM Log.WriteLine("Start sonogram."); SonogramConfig sonoConfig = new SonogramConfig(); //default values config sonoConfig.SourceFName = recording.BaseName; sonoConfig.WindowOverlap = FeltFrameOverlap; // set default value sonoConfig.DoMelScale = false; sonoConfig.NoiseReductionType = NoiseReductionType.Standard; AmplitudeSonogram basegram = new AmplitudeSonogram(sonoConfig, recording.WavReader); SpectrogramStandard sonogram = new SpectrogramStandard(basegram); //spectrogram has dim[N,257] Log.WriteLine("Signal: Duration={0}, Sample Rate={1}", sonogram.Duration, sr); Log.WriteLine("Frames: Size={0}, Count={1}, Duration={2:f1}ms, Overlap={5:f0}%, Offset={3:f1}ms, Frames/s={4:f1}", sonogram.Configuration.WindowSize, sonogram.FrameCount, (sonogram.FrameDuration * 1000), (sonogram.FrameStep * 1000), sonogram.FramesPerSecond, FeltFrameOverlap * 100); //iii: Get zip paths and the results Tuple List <string> zipList = FileTools.ReadTextFile(arguments.Config.FullName); Tuple <SpectrogramStandard, List <AcousticEvent>, double[]> results = null; //set up the results Tuple foreach (string zipPath in zipList) { if (zipPath.StartsWith("#")) { continue; // commented line } if (zipPath.Length < 2) { continue; // empty line } //i: get params file ZipFile.ExtractToDirectory(arguments.Output.FullName, zipPath); string zipName = Path.GetFileNameWithoutExtension(zipPath); string[] parts = zipName.Split('_'); string paramsPath = Path.Combine(arguments.Output.FullName, parts[0] + "_" + parts[1] + "_Params.txt"); string id = parts[0] + "_" + parts[1]; Log.WriteIfVerbose("################################################### " + id + " ########################################################"); //ii: READ PARAMETER VALUES FROM INI FILE var config = new ConfigDictionary(paramsPath); Dictionary <string, string> dict = config.GetTable(); //Dictionary<string, string>.KeyCollection keys = dict.Keys; //int DRAW_SONOGRAMS = Int32.Parse(dict[FeltTemplate_Create.key_DRAW_SONOGRAMS]); //options to draw sonogram dict[FeltTemplate_Create.key_DECIBEL_THRESHOLD] = "4.0"; dict[FeltTemplate_Create.key_MIN_DURATION] = "0.02"; if (zipName.EndsWith("binaryTemplate")) { string templatePath = Path.Combine(arguments.Output.FullName, id + "_binary.bmp"); double[,] templateMatrix = FindMatchingEvents.ReadImage2BinaryMatrixDouble(templatePath); results = FELTWithBinaryTemplate(sonogram, dict, templateMatrix, TimeSpan.Zero); } else if (zipName.EndsWith("trinaryTemplate")) { string templatePath = Path.Combine(arguments.Output.FullName, id + "_trinary.bmp"); double[,] templateMatrix = FindMatchingEvents.ReadImage2TrinaryMatrix(templatePath); results = FELTWithBinaryTemplate(sonogram, dict, templateMatrix, TimeSpan.Zero); } else if (zipName.EndsWith("syntacticTemplate")) { string templatePath = Path.Combine(arguments.Output.FullName, id + "_spr.txt"); char[,] templateMatrix = FindMatchingEvents.ReadTextFile2CharMatrix(templatePath); results = FELTWithSprTemplate(sonogram, dict, templateMatrix, TimeSpan.Zero); } else { Log.WriteLine("ERROR! UNKNOWN TEMPLATE: Zip file has unrecognised suffix:" + zipName); continue; } //get results sonogram = results.Item1; var matchingEvents = results.Item2; var scores = results.Item3; double matchThreshold = double.Parse(dict[FeltTemplate_Create.key_DECIBEL_THRESHOLD]); Log.WriteLine("# Finished detecting events like target: " + id); Log.WriteLine("# Matching Event Count = " + matchingEvents.Count); Log.WriteLine(" @ threshold = {0:f2}", matchThreshold); // accumulate results allEvents.AddRange(matchingEvents); scoresList.Add(scores); thresholdList.Add(matchThreshold); //v: write events count to results info file. double sigDuration = sonogram.Duration.TotalSeconds; string fname = arguments.Source.Name; string str = string.Format("{0}\t{1}\t{2}", fname, sigDuration, matchingEvents.Count); StringBuilder sb = AcousticEvent.WriteEvents(matchingEvents, str); FileTools.WriteTextFile("opPath", sb.ToString()); } // foreach (string zipPath in zipList) Log.WriteLine("\n\n\n##########################################################"); Log.WriteLine("# Finished detecting events"); Log.WriteLine("# Event Count = " + allEvents.Count); foreach (AcousticEvent ae in allEvents) { Log.WriteLine("# Event name = {0} ############################", ae.Name); Log.WriteLine("# Event time = {0:f2} to {1:f2} (frames {2}-{3}).", ae.TimeStart, ae.TimeEnd, ae.Oblong.RowTop, ae.Oblong.RowBottom); Log.WriteLine("# Event score= {0:f2}.", ae.Score); } int percentOverlap = 50; allEvents = PruneOverlappingEvents(allEvents, percentOverlap); Log.WriteLine("\n##########################################################"); Log.WriteLine("# Finished pruning events"); Log.WriteLine("# Event Count = " + allEvents.Count); WriteEventNames(allEvents); //WriteScoreAverages2Console(scoresList); //draw images of sonograms int DRAW_SONOGRAMS = 2; FileInfo opImagePath = arguments.Output.CombineFile(Path.GetFileNameWithoutExtension(arguments.Source.Name) + "_matchingEvents.png"); if (DRAW_SONOGRAMS == 2) { DrawSonogram(sonogram, opImagePath, allEvents, thresholdList, scoresList); } else if ((DRAW_SONOGRAMS == 1) && (allEvents.Count > 0)) { DrawSonogram(sonogram, opImagePath, allEvents, thresholdList, scoresList); } Log.WriteLine("# FINISHED passing all templates over recording:- " + arguments.Source.Name); }