Skip to content

Commit

Permalink
Set up Content Description as IAnalyzer2.
Browse files Browse the repository at this point in the history
Issue #252
  • Loading branch information
towsey committed Oct 8, 2019
1 parent 17a56e3 commit 42b429a
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 8 deletions.
118 changes: 118 additions & 0 deletions src/AnalysisConfigFiles/Towsey.ContentDescription.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
# Summary: Calculates an acoustic signature for each minute of recording.
# An acoustic signature is a vector, ecah element of which is derived from a ContentDescription template.
#
#SegmentDuration: units=seconds;
# Long duration recordings are cut into short segments for more efficient processing. Default segment length = 60 seconds.
# WARNING: You should not change this property!!
SegmentDuration: 60

#SegmentOverlap: units=seconds;
# WARNING: You should not change this property!!
SegmentOverlap: 0

# IndexCalculationDuration: units=seconds (default=60 seconds)
# The Timespan (in seconds) over which summary and spectral indices are calculated
# This value MUST not exceed value of SegmentDuration.
# This Default value should not be changed.
IndexCalculationDuration: 60.0

# BgNoiseNeighborhood: units=seconds
# By default, when IndexCalculationDuration = 60 seconds, background (stationary) noise is calculated from the full 60 second recording.
BgNoiseNeighborhood: 5

# By default, all recordings are down-sampled or up-sampled to 22050 Hz.
# If you have a recording sampled at a higher rate, AND you wish to retain it, then set the correct value here.
# Resample rate must be 2 X the desired Nyquist
ResampleRate: 22050

# FRAME LENGTH. units=samples
# Typical value=512 where resample rate = 22050.
# Frame Overlap is NEVER used when calculating acoustic indices.
# This value should not be changed in order to retain consistency over multiple recordings.
FrameLength: 512

# Defining three frequency bands.
# It is often useful to define three frequency bands, low, middle and high.
# Six of the summary indices are calculated for the mid-band only.
# This is useful to avoid low frequency anthropogenic noise and to target bird species which mostly sing in the 1-8 khz band.
# The lower and upper bound of the mid-frequency band are set by LowFreqBound and HighFreqBound respectively.
# Default values in code are LowFreqBound=1000Hz & MidFreqBound=8000
LowFreqBound: 1000
MidFreqBound: 8000
HighFreqBound: 11000

# The only FrequencyScale option currently available is only Linear
FrequencyScale: Linear

# SAVE INTERMEDIARY FILES
# Available options (case-sensitive): [false/Never | true/Always | WhenEventsDetected]
SaveIntermediateWavFiles: Never
# If `true` saves a data into a seperate file every `SegmentDuration` seconds. Accepts a boolean value: [false|true]
# If `true` saves a data into a seperate file every `SegmentDuration` seconds. Accepts a boolean value: [false|true]
SaveIntermediateCsvFiles: false

# SAVE INTERMEDIARY ONE-MINUTE (standard scale) SPECTROGRAMS
# One-minute spectrograms can be saved in any analysis task.
# Available options (case-sensitive): [False/Never | True/Always | WhenEventsDetected]
SaveSonogramImages: Never

# SAVE SONOGRAM DATA FILES FOR SUBSEQUENT ZOOMING SPECTROGRAMS
# Next two parameters are used only when creating images for zooming spectrograms.
# Warning: IndexCalculationDuration must be set = 0.2 when SaveSonogramData = true
SaveSonogramData: false

# TileImageOutput
# if true an additional set of images will be produced that are tiles
# if true, RequireDateInFilename must be set
TileOutput: false

# RequireDateInFilename:
# If true, an unambiguous date-time must be provided in the source file's name.
# If true, an exception will be thrown if no such date is found
# If false, and a valid date is still found in file name, it will still be parsed
# supports formats like:
# prefix_20140101T235959+1000.wav, where +1000 is the time-zone offset for Brisbane.
# prefix_20140101T235959+Z.wav, where +Z is the zero time-zone offset.
# prefix_20140101-235959+1000.wav
# prefix_20140101-235959+Z.wav
# For more info on dates, see <dates.md> at https://github.com/QutEcoacoustics/audio-analysis/tree/master/docs
RequireDateInFilename: false

# Do NOT change following path. It is required for drawing false-colour spectrograms
IndexPropertiesConfig: './IndexPropertiesConfig.yml'

# EventThreshold: min value=0.0; max value=1.0.
# This value can sometimes be used to manage the FP/FN trade-off performance of a call recogniser.
# Not always used however.
EventThreshold: 0.2

# #############################################################################################################
# The below parameters are used to configure drawing of the false-colour spectrograms
# IMPORTANT NOTE: FC spectrograms are produced only IF the above IndexCalculationDuration := 60.0
# Explanation of the FC configuration parameters is included below.
LdSpectrogramConfig:
ColorMap1: "ACI-ENT-EVN"
ColorMap2: "BGN-PMN-EVN"

#EXPLANATION OF LDFC CONFIG PARAMETERS
# The ColourFilter parameter determines how much the low index values are emphasized or de-emphasized.
# The purpose is to make low intensity features stand out (emphasis) or become even less obvious (de-emphasis).
# This parameter applies a function that lies between y=x^-2 and y=x^2, i.e. between the square-root and the square.
# For an acoustic index value of X, newX = [(1/c - 1) * X^2 + X] * c, where c = the supplied filterCoeff.
# When filterCoeff = 1.0, small values are maximally emphasized, i.e. y=sqrt(x).
# When filterCoeff = 0.0, the matrix remains unchanged, that is, y=x.
# When filterCoeff =-1.0, small values are maximally de-emphasized, i.e. y=x^2.
# Generally usage suggests that a value of -0.25 is suitable. i.e. a slight de-emphasis.
ColourFilter: -0.25

# minutes x-axis scale
XAxisTicIntervalSeconds: 3600

# Hertz y-axis scale
# Only three option work now: "Linear", "Mel"' "Linear125Octaves7Tones28Nyquist32000" work at present
# Future options will be: Linear62Octaves31Nyquist11025, Linear125Octaves30Nyquist11025, Octaves24Nyquist32000
FreqScale: "Linear"
YAxisTicInterval: 1000
...

1 change: 1 addition & 0 deletions src/AnalysisPrograms/AnalysisPrograms.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@
<Compile Include="..\AssemblyMetadata.cs">
<Link>AssemblyMetadata.cs</Link>
</Compile>
<Compile Include="ContentDescription.cs" />
<Compile Include="AcousticWorkbench.Orchestration\EventMetadataResolver.cs" />
<Compile Include="AcousticWorkbench.Orchestration\RemoteSegment.cs" />
<Compile Include="AED.cs" />
Expand Down
159 changes: 159 additions & 0 deletions src/AnalysisPrograms/ContentDescription.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// <copyright file="ContentDescription.cs" company="QutEcoacoustics">
// All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group).
// </copyright>

namespace AnalysisPrograms
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Acoustics.Shared;
using AnalysisBase;
using AnalysisBase.ResultBases;
using AudioAnalysisTools.Indices;
using AudioAnalysisTools.WavTools;
using log4net;

public class ContentDescription : AbstractStrongAnalyser
{
public const string AnalysisName = "ContentDescription";

// TASK IDENTIFIERS
//public const string TaskAnalyse = AnalysisName;
//public const string TaskLoadCsv = "loadCsv";
public const string TowseyAcoustic = "Towsey." + AnalysisName;

private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

public const int ResampleRate = 17640;

public override string DisplayName => "Content Description";

public override string Identifier => TowseyAcoustic;

public override string Description => "[BETA] Generates six spectral indices for Content Description.";

public override AnalysisSettings DefaultSettings => new AnalysisSettings
{
AnalysisMaxSegmentDuration = TimeSpan.FromMinutes(1),
AnalysisMinSegmentDuration = TimeSpan.FromSeconds(30),
SegmentMediaType = MediaTypes.MediaTypeWav,
SegmentOverlapDuration = TimeSpan.Zero,
AnalysisTargetSampleRate = ResampleRate,
};

//public override void BeforeAnalyze(AnalysisSettings analysisSettings)
//{
// var configuration = (AcousticIndices.AcousticIndicesConfig)analysisSettings.Configuration;

// configuration.Validate(analysisSettings.AnalysisMaxSegmentDuration.Value);

// analysisSettings.AnalysisAnalyzerSpecificConfiguration = configuration;
//}

//public static DescriptionResult Analysis(FileInfo segmentOfSourceFile, IDictionary<string, string> configDict, TimeSpan segmentStartOffset)
//{
// var results = new DescriptionResult((int)Math.Floor(segmentStartOffset.TotalMinutes));
// return results;
//}

/// <summary>
/// THis method calls others to do the work!.
/// TODO: SIMPLIFY THIS METHOD.
/// </summary>
public override AnalysisResult2 Analyze<T>(AnalysisSettings analysisSettings, SegmentSettings<T> segmentSettings)
{
//var acousticIndicesConfiguration = (AcousticIndices.AcousticIndicesConfig)analysisSettings.AnalysisAnalyzerSpecificConfiguration;
//var indexCalculationDuration = acousticIndicesConfiguration.IndexCalculationDuration.Seconds();

var config = new IndexCalculateConfig();
var indexCalculationDuration = TimeSpan.FromSeconds(60);

var audioFile = segmentSettings.SegmentAudioFile;
var recording = new AudioRecording(audioFile.FullName);
//var outputDirectory = segmentSettings.SegmentOutputDirectory;

// calculate indices for each one minute recording segment
IndexCalculateResult segmentResults = CalculateIndicesInOneMinuteSegmentOfRecording(
recording,
segmentSettings.SegmentStartOffset,
//segmentSettings.AnalysisIdealSegmentDuration,
indexCalculationDuration,
//acousticIndicesConfiguration.IndexProperties,
segmentSettings.Segment.SourceMetadata.SampleRate,
config);

//var trackScores = new List<Plot>(segmentResults.Length);
//var tracks = new List<SpectralTrack>(segmentResults.Length);

var analysisResults = new AnalysisResult2(analysisSettings, segmentSettings, recording.Duration)
{
AnalysisIdentifier = this.Identifier,
SpectralIndices = new SpectralIndexBase[1],
};
segmentResults.SpectralIndexValues.FileName = segmentSettings.Segment.SourceMetadata.Identifier;
analysisResults.SpectralIndices[0] = segmentResults.SpectralIndexValues;

/*
for (int i = 0; i < subsegmentResults.Length; i++)
{
var indexCalculateResult = segmentResults[i];
indexCalculateResult.SpectralIndexValues.FileName = segmentSettings.Segment.SourceMetadata.Identifier;
//analysisResults.SummaryIndices[i] = indexCalculateResult.SummaryIndexValues;
analysisResults.SpectralIndices[i] = indexCalculateResult.SpectralIndexValues;
//trackScores.AddRange(indexCalculateResult.TrackScores);
//if (indexCalculateResult.Tracks != null)
//{
// tracks.AddRange(indexCalculateResult.Tracks);
//}
}
*/

return analysisResults;
}

/// <summary>
/// TODO: REWRITE THIS METHOD.
/// </summary>
public static IndexCalculateResult CalculateIndicesInOneMinuteSegmentOfRecording(
AudioRecording recording,
TimeSpan segmentStartOffset,
TimeSpan indexCalculationDuration,
//Dictionary<string, IndexProperties> indexProperties,
int sampleRateOfOriginalAudioFile,
IndexCalculateConfig config)
{
//TODO: SET UP NEW class CalculateSizIndices.cs.
var resultsForSixIndices = IndexCalculate.Analysis(
recording,
segmentStartOffset,
null, //indexProperties,
sampleRateOfOriginalAudioFile,
segmentStartOffset,
config);

return resultsForSixIndices;
}

public override void WriteEventsFile(FileInfo destination, IEnumerable<EventBase> results)
{
}

public override void WriteSummaryIndicesFile(FileInfo destination, IEnumerable<SummaryIndexBase> results)
{
}

public override List<FileInfo> WriteSpectrumIndicesFiles(DirectoryInfo destination, string fileNameBase, IEnumerable<SpectralIndexBase> results)
{
var list = new List<FileInfo>();
return list;
}

public override void SummariseResults(AnalysisSettings settings, FileSegment inputFileSegment,
EventBase[] events, SummaryIndexBase[] indices, SpectralIndexBase[] spectralIndices, AnalysisResult2[] results)
{
}
}
}
22 changes: 14 additions & 8 deletions src/AnalysisPrograms/Sandpit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ public override Task<int> Execute(CommandLineApplication app)
Log.WriteLine("# Start Time = " + tStart.ToString(CultureInfo.InvariantCulture));

// CONTENT DESCRIPTION
ContentDescriptionCreateTemplates();
ContentDescriptionApplyTemplates();
//ContentDescriptionCreateTemplates();
//ContentDescriptionApplyTemplates();

//AnalyseFrogDataSet();
//Audio2CsvOverOneFile();
Audio2CsvOverOneFile();
//Audio2CsvOverMultipleFiles();

// used to get files from availae for Black rail and Least Bittern papers.
Expand Down Expand Up @@ -134,7 +134,7 @@ public static void ContentDescriptionApplyTemplates()

var templatesFile = new FileInfo(@"C:\Ecoacoustics\ContentDescription\TemplateDefinitions.json");
var listOfIndexFiles = new FileInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMezIndexFiles.txt");
var contentPlots = ContentDescription.ContentDescriptionOfMultipleRecordingFiles(listOfIndexFiles, templatesFile);
var contentPlots = AudioAnalysisTools.ContentDescriptionTools.ContentDescription.ContentDescriptionOfMultipleRecordingFiles(listOfIndexFiles, templatesFile);

var images = GraphsAndCharts.DrawPlotDistributions(contentPlots);
var plotsImage = ImageTools.CombineImagesVertically(images);
Expand Down Expand Up @@ -362,10 +362,16 @@ public static void Audio2CsvOverOneFile()
//string configPath = @"C:\Work\GitHub\audio-analysis\AudioAnalysis\AnalysisConfigFiles\Towsey.Acoustic.yml";

// Test on STANDARD 24-HOUR RECORDING
string recordingPath = @"C:\Ecoacoustics\WavFiles\LizZnidersic\TasmanIsland2015_Unit2_Mez\SM304256_0+1_20151114_131652.wav";
//string recordingPath = @"C:\Ecoacoustics\WavFiles\LizZnidersic\TasmanIsland2015_Unit2_Mez\SM304256_0+1_20151114_131652+1000.wav";
//string outputPath = @"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\14";
string outputPath = @"C:\Ecoacoustics\Output\Test\Test24HourRecording\Delete";
string configPath = @"C:\Work\GitHub\audio-analysis\src\AnalysisConfigFiles\Towsey.Acoustic.yml";
//string outputPath = @"C:\Ecoacoustics\Output\Test\Test24HourRecording\Delete";
//string configPath = @"C:\Work\GitHub\audio-analysis\src\AnalysisConfigFiles\Towsey.Acoustic.yml";

// Test on Content Description
string recordingPath = @"C:\Ecoacoustics\WavFiles\LizZnidersic\TasmanIsland2015_Unit2_Mez\SM304256_0+1_20151114_131652+1000.wav";
//string outputPath = @"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\14";
string outputPath = @"C:\Ecoacoustics\ContentDescription\TestOfSixIndices";
string configPath = @"C:\Work\GitHub\audio-analysis\src\AnalysisConfigFiles\Towsey.ContentDescription.yml";

// Ivan Campos recordings
//string recordingPath = @"G:\SensorNetworks\WavFiles\Ivancampos\INCIPO01_20161031_024006_898.wav";
Expand Down Expand Up @@ -428,7 +434,7 @@ public static void Audio2CsvOverOneFile()
//string outputPath = @"C:\Ecoacoustics\Output\SERF\SERFIndicesNew_2013June19";
//string configPath = @"C:\Work\GitHub\audio-analysis\src\AnalysisConfigFiles\Towsey.Acoustic.yml";

// USE 24-hour data or parts of from MEZ, TASMAn ISLAND, liz Znidersic
// USE 24-hour data or parts of from MEZ, TASMAn ISLAND, liz Znidersic
// these are six hour recordings
//string recordingPath = @"C:\Ecoacoustics\WavFiles\LizZnidersic\TasmanIsland2015_Unit2_Mez\SM304256_0+1_20151114_031652.wav";
//string outputPath = @"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\04";
Expand Down

0 comments on commit 42b429a

Please sign in to comment.