Skip to content

Commit

Permalink
Move method ConvertOscillationScores2Events()
Browse files Browse the repository at this point in the history
Issue #500 Move the ConvertOscillationScores2Events() method because it is used by both the Oscillations2012 and 2019 algorithms.
  • Loading branch information
towsey committed Jun 29, 2021
1 parent 9521508 commit 86fb4f9
Showing 1 changed file with 111 additions and 0 deletions.
111 changes: 111 additions & 0 deletions src/AudioAnalysisTools/Events/Types/OscillationEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,117 @@ public override void Draw(IImageProcessingContext graphics, EventRenderingOption
this.DrawEventLabel(graphics, options);
}

/// <summary>
/// Converts the Oscillation Detector score array to a list of Oscillation Events.
/// </summary>
/// <param name="minDurationThreshold">min threshold.</param>
/// <param name="maxDurationThreshold">max threshold.</param>
/// <param name="minHz">lower freq bound of the acoustic event.</param>
/// <param name="maxHz">upper freq bound of the acoustic event.</param>
/// <param name="minOscilFrequency">the minimum oscillations per second.</param>
/// <param name="maxOscilFrequency">the maximum oscillations per second.</param>
/// <param name="oscilScores">the array of OD scores.</param>
/// <param name="scoreThreshold">threshold.</param>
/// <param name="segmentStartOffset">time offset.</param>
public static List<OscillationEvent> ConvertOscillationScores2Events(
SpectrogramStandard spectrogram,
double minDurationThreshold,
double maxDurationThreshold,
int minHz,
int maxHz,
double? minOscilFrequency,
double? maxOscilFrequency,
double[] oscilScores,
double scoreThreshold,
TimeSpan segmentStartOffset)
{
// The name of source file
string fileName = spectrogram.Configuration.SourceFName;
double framesPerSec = spectrogram.FramesPerSecond;
double freqBinWidth = spectrogram.FBinWidth;
int count = oscilScores.Length;

// get the bin bounds of the frequency band of interest.
int minBin = (int)(minHz / freqBinWidth);
int maxBin = (int)(maxHz / freqBinWidth);

// get the oeriodicity bounds for the frequency band of interest.
double? minPeriodicity = 1 / maxOscilFrequency;
double? maxPeriodicity = 1 / minOscilFrequency;

var events = new List<OscillationEvent>();
bool isHit = false;
double frameOffset = 1 / framesPerSec;
int startFrame = 0;

//pass over all frames
for (int i = 0; i < count; i++)
{
if (isHit == false && oscilScores[i] >= scoreThreshold)
{
//start of an event
isHit = true;
startFrame = i;
}
else //check for the end of an event
if (isHit && (oscilScores[i] < scoreThreshold || i == count - 1))
{
isHit = false;
double duration = (i - startFrame + 1) * frameOffset;
if (duration < minDurationThreshold || duration > maxDurationThreshold)
{
//skip events with duration outside the required bounds
continue;
}

// This is end of an event, so initialise it
// First trim the event because oscillation events spill over the edges of the true event due to use of the DCT.
(int trueStartFrame, int trueEndFrame, double framePeriodicity) = OscillationEvent.TrimEvent(spectrogram, startFrame, minBin, i, maxBin);
double trueStartTime = trueStartFrame * frameOffset;
double trueEndTime = trueEndFrame * frameOffset;
int trueFrameLength = trueEndFrame - trueStartFrame + 1;

// Determine if the periodicity is within the required bounds.
var periodicity = framePeriodicity * frameOffset;
if (periodicity < minPeriodicity || periodicity > maxPeriodicity)
{
//skip events with periodicity outside the required bounds
continue;
}

//obtain average score.
double sum = 0.0;
for (int n = trueStartFrame; n <= trueEndFrame; n++)
{
sum += oscilScores[n];
}

double score = sum / trueFrameLength;

var ev = new OscillationEvent()
{
Name = "Oscillation",
SegmentStartSeconds = segmentStartOffset.TotalSeconds,
ResultStartSeconds = segmentStartOffset.TotalSeconds + trueStartTime,
EventStartSeconds = segmentStartOffset.TotalSeconds + trueStartTime,
EventEndSeconds = segmentStartOffset.TotalSeconds + trueEndTime,
LowFrequencyHertz = minHz,
HighFrequencyHertz = maxHz,
Periodicity = framePeriodicity * frameOffset,
Score = score,
FileName = fileName,
};

//##########################################################################################
//ev.Score2 = av / (i - startFrame + 1);
//ev.Intensity = (int)ev.Score2; // store this info for later inclusion in csv file as Event Intensity
events.Add(ev);
}
}

return events;
}

/// <summary>
/// Extracts an event from a spectrogram given its bounds.
/// Then trims the event because oscillation events do not typically start where the DCT places them.
Expand Down

0 comments on commit 86fb4f9

Please sign in to comment.