Skip to content

Commit

Permalink
Enable Harmonic recognizer to utilize an array of decibel trhsholds.
Browse files Browse the repository at this point in the history
Issue #370
  • Loading branch information
towsey authored and atruskie committed Oct 14, 2020
1 parent cc951ab commit 24cdc16
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 30 deletions.
33 changes: 10 additions & 23 deletions src/AnalysisPrograms/Recognizers/GenericRecognizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,27 +244,14 @@ public override RecognizerResults Recognize(
}
else if (profileConfig is HarmonicParameters hp)
{
var thresholdArray = hp.DecibelThresholds;
var threshold = thresholdArray[0];

double[] decibelMaxArray;
double[] harmonicIntensityScores;
(spectralEvents, decibelMaxArray, harmonicIntensityScores) = HarmonicParameters.GetComponentsWithHarmonics(
List<Plot> decibelPlots;
(spectralEvents, decibelPlots) = HarmonicParameters.GetComponentsWithHarmonics(
spectrogram,
hp.MinHertz.Value,
hp.MaxHertz.Value,
spectrogram.NyquistFrequency,
threshold.Value,
hp.DctThreshold.Value,
hp.MinDuration.Value,
hp.MaxDuration.Value,
hp.MinFormantGap.Value,
hp.MaxFormantGap.Value,
segmentStartOffset);
hp,
segmentStartOffset,
profileName);

// prepare plot of resultant Harmonics decibel array.
var plot = Plot.PreparePlot(decibelMaxArray, $"{profileName} (Harmonics:{threshold:d0}db)", threshold.Value);
plots.Add(plot);
plots.AddRange(decibelPlots);
}
else if (profileConfig is OscillationParameters op)
{
Expand Down Expand Up @@ -377,21 +364,21 @@ public override RecognizerResults Recognize(
{
// filter on number of components
var maxComponentCount = sequenceConfig.SyllableMaxCount;
allResults.NewEvents = EventExtentions.FilterEventsOnCompositeContent(allResults.NewEvents, maxComponentCount);
allResults.NewEvents = EventFilters.FilterEventsOnCompositeContent(allResults.NewEvents, maxComponentCount);
Log.Info($"Event count after filtering on component count = {allResults.NewEvents.Count}");

// filter on syllable periodicity
var period = sequenceConfig.ExpectedPeriod;
var periodSd = sequenceConfig.PeriodStdDev;
allResults.NewEvents = EventExtentions.FilterEventsOnSyllablePeriodicity(allResults.NewEvents, period, periodSd);
allResults.NewEvents = EventFilters.FilterEventsOnSyllablePeriodicity(allResults.NewEvents, period, periodSd);
Log.Info($"Event count after filtering on component count = {allResults.NewEvents.Count}");
}
}

// 3: Filter the events for bandwidth in Hertz
var expectedEventBandwidth = configuration.ExpectedBandwidth;
var sd = configuration.BandwidthStandardDeviation;
allResults.NewEvents = EventExtentions.FilterOnBandwidth(allResults.NewEvents, expectedEventBandwidth, sd, sigmaThreshold: 3.0);
allResults.NewEvents = EventFilters.FilterOnBandwidth(allResults.NewEvents, expectedEventBandwidth, sd, sigmaThreshold: 3.0);
Log.Info($"Event count after filtering on bandwidth = {allResults.NewEvents.Count}");

// 4: Filter events on the amount of acoustic activity in their upper and lower neighbourhoods - their buffer zone.
Expand All @@ -400,7 +387,7 @@ public override RecognizerResults Recognize(
if (configuration.NeighbourhoodUpperHertzBuffer > 0 || configuration.NeighbourhoodLowerHertzBuffer > 0)
{
var spectralEvents2 = allResults.NewEvents.Cast<SpectralEvent>().ToList();
allResults.NewEvents = EventExtentions.FilterEventsOnNeighbourhood(
allResults.NewEvents = EventFilters.FilterEventsOnNeighbourhood(
spectralEvents2,
allResults.Sonogram,
configuration.NeighbourhoodLowerHertzBuffer,
Expand Down
47 changes: 40 additions & 7 deletions src/AudioAnalysisTools/HarmonicParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace AnalysisPrograms.Recognizers.Base

/// <summary>
/// Parameters needed from a config file to detect the stacked harmonic components of a soundscape.
/// This can also be used for recognizing the harmonics of non-biological sounds such as from turbines, motor-bikes, compressors and other hi-revving motors.
/// This can also be used for recognizing the harmonics of non-biological sounds such as from turbines, motor-bikes, compressors, hi-revving motors, etc.
/// </summary>
[YamlTypeTag(typeof(HarmonicParameters))]
public class HarmonicParameters : CommonParameters
Expand All @@ -35,6 +35,44 @@ public class HarmonicParameters : CommonParameters
/// </summary>
public int? MaxFormantGap { get; set; }

public static (List<EventCommon> SpectralEvents, List<Plot> DecibelPlots) GetComponentsWithHarmonics(
SpectrogramStandard spectrogram,
HarmonicParameters hp,
TimeSpan segmentStartOffset,
string profileName)
{
// get the array of decibel thresholds
var thresholdArray = hp.DecibelThresholds;

var spectralEvents = new List<EventCommon>();
var plots = new List<Plot>();

// loop through the array of decibel thresholds
foreach (var threshold in thresholdArray)
{
double[] decibelMaxArray;
double[] harmonicIntensityScores;
(spectralEvents, decibelMaxArray, harmonicIntensityScores) = HarmonicParameters.GetComponentsWithHarmonics(
spectrogram,
hp.MinHertz.Value,
hp.MaxHertz.Value,
spectrogram.NyquistFrequency,
threshold.Value,
hp.DctThreshold.Value,
hp.MinDuration.Value,
hp.MaxDuration.Value,
hp.MinFormantGap.Value,
hp.MaxFormantGap.Value,
segmentStartOffset);

// prepare plot of resultant Harmonics decibel array.
var plot = Plot.PreparePlot(decibelMaxArray, $"{profileName} (Harmonics:{threshold:d0}db)", threshold.Value);
plots.Add(plot);
}

return (spectralEvents, plots);
}

public static (List<EventCommon> SpectralEvents, double[] AmplitudeArray, double[] HarmonicIntensityScores) GetComponentsWithHarmonics(
SpectrogramStandard spectrogram,
int minHz,
Expand All @@ -48,9 +86,6 @@ public static (List<EventCommon> SpectralEvents, double[] AmplitudeArray, double
int maxFormantGap,
TimeSpan segmentStartOffset)
{
// Event threshold - Determines FP / FN trade-off for events.
//double eventThreshold = 0.2;

var sonogramData = spectrogram.Data;
int frameCount = sonogramData.GetLength(0);
int binCount = sonogramData.GetLength(1);
Expand Down Expand Up @@ -107,14 +142,12 @@ public static (List<EventCommon> SpectralEvents, double[] AmplitudeArray, double

var spectralEvents = new List<EventCommon>();

// add in temporary names to the events
// These can be altered later.
// add in temporary names to the events. These can be altered later.
foreach (var he in harmonicEvents)
{
var se = EventConverters.ConvertAcousticEventToSpectralEvent(he);
spectralEvents.Add(se);
se.Name = "Harmonics";
//se.ComponentName = "Harmonics";
}

return (spectralEvents, dBArray, harmonicIntensityScores);
Expand Down

0 comments on commit 24cdc16

Please sign in to comment.