Skip to content

Commit

Permalink
Update OscillationEvent.cs
Browse files Browse the repository at this point in the history
Issue #469
1: Added the Periodicity Property to the Oscillation Event class.
2: Fixed the Draw() method for Oscillation events. The events were not drawing.
3: Added a method to trim Oscillation events using the decibel values as a guide to where the true bounds should be.
  • Loading branch information
towsey committed Jun 14, 2021
1 parent 05e70dd commit b6e14d4
Showing 1 changed file with 70 additions and 7 deletions.
77 changes: 70 additions & 7 deletions src/AudioAnalysisTools/Events/Types/OscillationEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,90 @@ namespace AudioAnalysisTools
using System;
using AudioAnalysisTools.Events;
using AudioAnalysisTools.Events.Drawing;
using AudioAnalysisTools.StandardSpectrograms;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using TowseyLibrary;

public class OscillationEvent : SpectralEvent
{
public OscillationEvent()
{
}

/// <summary>
/// Gets or sets the period in seconds between consecutive oscillations.
/// </summary>
public double Periodicity { get; set; }

// TODO: add extra metadata!!!

/// <summary>
/// Draws a border around this oscillation event.
/// </summary>
public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
{
// foreach (var track in tracks) {
// track.Draw(...)
// }
if (options.DrawBorder)
{
var border = options.Converters.GetPixelRectangle(this);
graphics.NoAA().DrawBorderInset(options.Border, border);
}

this.DrawScoreIndicator(graphics, options);
this.DrawEventLabel(graphics, options);
}

/// <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.
/// </summary>
public static (int EventStart, int EventEnd, double FramePeriod) TrimEvent(SpectrogramStandard spectrogram, int startFrame, int minBin, int endFrame, int maxBin)
{
//obtain the oscillation event's periodicity.
//extract the relevant portion of the spectrogram.
var eventMatrix = MatrixTools.Submatrix<double>(spectrogram.Data, startFrame, minBin, endFrame, maxBin);
var frameAverages = MatrixTools.GetRowAverages(eventMatrix);
frameAverages = DataTools.normalise(frameAverages);
double threshold = 0.25;

// find the true start frame
int startFrameOffset = 0;
for (int frame = 1; frame < frameAverages.Length; frame++)
{
startFrameOffset++;
if (frameAverages[frame - 1] < threshold && frameAverages[frame] >= threshold)
{
break;
}
}

int endFrameOffset = 0;
for (int frame = frameAverages.Length - 1; frame >= 0; frame--)
{
endFrameOffset++;
if (frameAverages[frame - 1] >= threshold && frameAverages[frame] < threshold)
{
break;
}
}

int trueStartFrame = startFrame + startFrameOffset;
int trueEndFrame = endFrame - endFrameOffset;
int trueFrameLength = trueEndFrame - trueStartFrame + 1;

// determine the number of times the frame values step from below to above average.
int stepCount = 0;
for (int frame = 1; frame < frameAverages.Length; frame++)
{
if (frameAverages[frame - 1] < threshold && frameAverages[frame] >= threshold)
{
stepCount++;
}
}

//this.Track.Draw(graphics, options);
double framePeriod = trueFrameLength / (double)stepCount;

// base drawing (border)
// TODO: unless border is disabled
base.Draw(graphics, options);
return (trueStartFrame, trueEndFrame, framePeriod);
}
}
}

0 comments on commit b6e14d4

Please sign in to comment.