Skip to content

Commit

Permalink
Changes as part of code review.
Browse files Browse the repository at this point in the history
Issue #297
  • Loading branch information
towsey committed May 8, 2020
1 parent 8ec397c commit deee017
Show file tree
Hide file tree
Showing 15 changed files with 61 additions and 129 deletions.
3 changes: 3 additions & 0 deletions src/AudioAnalysisTools/AudioAnalysisTools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@
</PackageReference>
<PackageReference Include="Towel" Version="1.0.11-alpha" />
</ItemGroup>
<ItemGroup>
<Folder Include="Events\Tracks\" />
</ItemGroup>
</Project>
10 changes: 4 additions & 6 deletions src/AudioAnalysisTools/Events/Drawing/EventDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ public static void DrawScoreIndicator(this SpectralEvent @event, IImageProcessin
return;
}

// TODO: add a Interval<double> ScoreRange property to EventCommon
// so we can properly normalize this value to the unit value.
// For now, we just assume it is normalized to [0,1].
//var clampedScore = @event.Score.Clamp(0, 1);
var normalisedScore = @event.ScoreNormalised;
// Although an Interval<double> ScoreRange property has been added to EventCommon,
// this does not clamp values. For now, we clamp before drawing.
var normalisedScore = @event.ScoreNormalised.Clamp(0, 1);

if (normalisedScore == 0)
{
Expand All @@ -45,7 +43,7 @@ public static void DrawScoreIndicator(this SpectralEvent @event, IImageProcessin

graphics.NoAA().DrawLines(
options.Score,
new PointF(rect.Left, rect.Bottom - 1), // TODO minus one is a hack! just to make it work!
new PointF(rect.Left, rect.Bottom - 1), // minus one is to bring bottom of score line within event frame.
new PointF(rect.Left, rect.Bottom - scaledHeight));
}

Expand Down
2 changes: 1 addition & 1 deletion src/AudioAnalysisTools/Events/EventCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public abstract class EventCommon : EventBase, IDrawableEvent
/// Up to user to determine a suitable range maximum.
/// Minimum of range assumed to be zero.
/// </summary>
public double ScoreNormalised => Math.Min(1.0, this.Score / this.ScoreRange.Maximum);
public double ScoreNormalised => this.Score / this.ScoreRange.Maximum;

/// <summary>
/// Draw this event on an image.
Expand Down
43 changes: 0 additions & 43 deletions src/AudioAnalysisTools/Events/Tracks/PointData.cs

This file was deleted.

20 changes: 3 additions & 17 deletions src/AudioAnalysisTools/Events/Types/ChirpEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ namespace AudioAnalysisTools

public class ChirpEvent : SpectralEvent, ITracks<Track>
{
private readonly double maxScore;

/// <summary>
/// Initializes a new instance of the <see cref="ChirpEvent"/> class.
/// </summary>
Expand All @@ -27,11 +25,11 @@ public class ChirpEvent : SpectralEvent, ITracks<Track>
/// The normalised score is a linear conversion from 0 - maxScore to [0, 1].
/// </remarks>
/// <param name="chirp">A chirp track consisting of a sequence of spectral points.</param>
/// <param name="maxScore">A maximum score used to normalise the track score.</param>
public ChirpEvent(Track chirp, double maxScore)
/// <param name="interval">A min and maximum score used to normalise the track score.</param>
public ChirpEvent(Track chirp, Interval<double> interval)
{
this.Tracks.Add(chirp);
this.ScoreRange = new Interval<double>(0, maxScore);
this.ScoreRange = interval;
}

public List<Track> Tracks { get; private set; } = new List<Track>(1);
Expand Down Expand Up @@ -68,18 +66,6 @@ public override double Score
}
}

/// <summary>
/// Gets the normalised value for the event's track score.
/// NOTE: It is assumed that the minimum value of the score range = zero.
/// </summary>
public double ScoreNormalised
{
get
{
return this.Score / this.maxScore;
}
}

public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
{
this.Tracks.First().Draw(graphics, options);
Expand Down
7 changes: 0 additions & 7 deletions src/AudioAnalysisTools/Events/Types/ClickEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,7 @@ public override double Score

public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
{
// foreach (var track in tracks) {
// track.Draw(...)
// }

this.Tracks.First().Draw(graphics, options);

// base drawing (border)
// TODO: unless border is disabled
base.Draw(graphics, options);
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/AudioAnalysisTools/Events/Types/CompositeEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ public IEnumerable<ITrack> Tracks
}
}

public new double ScoreNormalised()
{
double sum = 0.0;
foreach (var @event in this.ComponentEvents)
{
sum += @event.Score;
}

var score = sum / this.ComponentEvents.Count;

return score / this.ScoreRange.Maximum;
}

public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
{
foreach (var @event in this.ComponentEvents)
Expand Down
4 changes: 2 additions & 2 deletions src/AudioAnalysisTools/Events/Types/WhipEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ namespace AudioAnalysisTools

public class WhipEvent : SpectralEvent, ITracks<Track>
{
public WhipEvent(Track whip, double maxScore)
public WhipEvent(Track whip, Interval<double> interval)
{
this.Tracks.Add(whip);
this.ScoreRange = new Interval<double>(0, maxScore);
this.ScoreRange = interval;
}

public List<Track> Tracks { get; private set; } = new List<Track>(1);
Expand Down
7 changes: 4 additions & 3 deletions src/AudioAnalysisTools/Events/Types/WhistleEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ namespace AudioAnalysisTools

public class WhistleEvent : SpectralEvent, ITracks<Track>
{
public WhistleEvent(Track whistle, double maxScore)
public WhistleEvent(Track whistle, Interval<double> interval)
{
this.Tracks.Add(whistle);
this.ScoreRange = new Interval<double>(0, maxScore);
this.ScoreRange = interval;
}

public List<Track> Tracks { get; private set; } = new List<Track>(1);
Expand Down Expand Up @@ -114,7 +114,8 @@ public static WhistleEvent MergeTwoWhistleEvents(WhistleEvent e1, WhistleEvent e
track1.Points.Add(point);
}

var newEvent = new WhistleEvent(track1, 1.0)
var scoreRange = new Interval<double>(0, 1.0);
var newEvent = new WhistleEvent(track1, scoreRange)
{
Name = e1.Name,
EventEndSeconds = Math.Max(e1.EventEndSeconds, e2.EventEndSeconds),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ namespace AudioAnalysisTools.LongDurationSpectrograms
/// It was written to deal with a set of recordings with protocol of Gianna Pavan (10 minutes every 30 minutes).
///
/// The following Powershell command was constructed by Anthony to do the analysis and join the sequence of images so derived:
/// Y:\Italy_GianniPavan\Sassofratino1day | % {"&" "C:\Work\GitHub\audio-analysis\AudioAnalysis\AnalysisPrograms\bin\Release\AnalysisPrograms.exe" audio2csv -so ($_.FullName) -o "Y:\Italy_GianniPavan\output" -c "C:\Work\GitHub\audio-analysis\AudioAnalysis\AnalysisConfigFiles\Towsey.Acoustic.Parallel.yml" }
/// Y:\Italy_GianniPavan\Sassofratino1day | % { &amp; "C:\Work\GitHub\audio-analysis\AudioAnalysis\AnalysisPrograms\bin\Release\AnalysisPrograms.exe" audio2csv -so ($_.FullName) -o "Y:\Italy_GianniPavan\output" -c "C:\Work\GitHub\audio-analysis\AudioAnalysis\AnalysisConfigFiles\Towsey.Acoustic.Parallel.yml" }
/// where:
/// Y:\Italy_GianniPavan\Sassofratino1day is the directory containing recordings
/// | = a pipe
/// % = foreach{} = perform the operation in curly brackets on each item piped from the directory.
/// "&" "C:\Work\GitHub\audio-analysis\AudioAnalysis\AnalysisPrograms\bin\Release\AnalysisPrograms.exe" = runs an executable
/// &amp; "C:\Work\GitHub\audio-analysis\AudioAnalysis\AnalysisPrograms\bin\Release\AnalysisPrograms.exe" = runs an executable
/// audio2csv = first command line argument which determines the "activity" performed
/// -so ($_.FullName) = the input file
/// -o "Y:\Italy_GianniPavan\output" = the output directory
/// -c "PATH\Towsey.Acoustic.Parallel.yml" is the config file
///
/// The following PowerShell command was used by Anthony to stitch together a sequence of spectrogam images without any gap between them.
/// It requires ImageMagick software to be installed: i.e. C:\Program Files\ImageMagick-6.8.9-Q16\montage.exe
/// Y:\Italy_GianniPavan\output\Towsey.Acoustic> "&" "C:\Program Files\ImageMagick-6.8.9-Q16\montage.exe" -mode concatenate -tile x1 *2MAP* "..\..\merge.png"
/// Y:\Italy_GianniPavan\output\Towsey.Acoustic> &amp; "C:\Program Files\ImageMagick-6.8.9-Q16\montage.exe" -mode concatenate -tile x1 *2MAP* "..\..\merge.png"
///
///
/// (2) ConcatenateSpectralIndexFiles()
Expand Down Expand Up @@ -203,12 +203,15 @@ public static void ExtractSOMClusters1()
// ###############################################################
// VERY IMPORTANT: MUST MAKE SURE THE BELOW ARE CONSISTENT WITH THE DATA !!!!!!!!!!!!!!!!!!!!
int sampleRate = 22050;
int frameWidth = 256;

//int frameWidth = 256;
int nyquist = sampleRate / 2;
int herzInterval = 1000;

//int herzInterval = 1000;
TimeSpan minuteOffset = TimeSpan.Zero; // assume recordings start at midnight
double backgroundFilterCoeff = SpectrogramConstants.BACKGROUND_FILTER_COEFF;
string colorMap = SpectrogramConstants.RGBMap_ACI_ENT_EVN;

//double backgroundFilterCoeff = SpectrogramConstants.BACKGROUND_FILTER_COEFF;
//string colorMap = SpectrogramConstants.RGBMap_ACI_ENT_EVN;
string title = $"SOM CLUSTERS of ACOUSTIC INDICES: recording {fileStem}";
TimeSpan indexCalculationDuration = TimeSpan.FromSeconds(60); // seconds
TimeSpan xTicInterval = TimeSpan.FromMinutes(60); // 60 minutes or one hour.
Expand Down Expand Up @@ -494,20 +497,20 @@ public static Image DrawTitleBarOfClusterSpectrogram(string title, int width)

bmp.Mutate(g =>
{
SizeF stringSize = new SizeF();
SizeF stringSize = default;

int X = 4;
g.DrawText(title, stringFont, Color.Wheat, new PointF(X, 3));
int x1 = 4;
g.DrawText(title, stringFont, Color.Wheat, new PointF(x1, 3));

stringSize = g.MeasureString(title, stringFont);
X += stringSize.ToSize().Width + 70;
x1 += stringSize.ToSize().Width + 70;

string text = Meta.OrganizationTag;
stringSize = g.MeasureString(text, stringFont);
int X2 = width - stringSize.ToSize().Width - 2;
if (X2 > X)
int x2 = width - stringSize.ToSize().Width - 2;
if (x2 > x1)
{
g.DrawText(text, stringFont, Color.Wheat, new PointF(X2, 3));
g.DrawText(text, stringFont, Color.Wheat, new PointF(x2, 3));
}

g.DrawLine(new Pen(Color.Gray, 1), 0, 0, width, 0); //draw upper boundary
Expand Down
25 changes: 0 additions & 25 deletions src/AudioAnalysisTools/Scales/LinearSecondsScale.cs

This file was deleted.

9 changes: 4 additions & 5 deletions src/AudioAnalysisTools/Tracks/ForwardTrackAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace AudioAnalysisTools.Tracks
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Acoustics.Shared;
using AnalysisPrograms.Recognizers.Base;
using AudioAnalysisTools.Events;
using AudioAnalysisTools.Events.Drawing;
Expand Down Expand Up @@ -82,10 +83,11 @@ public static (List<EventCommon> Events, double[] CombinedIntensity) GetForwardT
// Initialise events with tracks.
foreach (var track in tracks)
{
//Following line used only for debug purposes.
//Following line used only for debug purposes. Can save as image.
//spectrogram.Mutate(x => track.Draw(x, options));
var maxScore = decibelThreshold * 5;
var ae = new ChirpEvent(track, maxScore)
var scoreRange = new Interval<double>(0, maxScore);
var ae = new ChirpEvent(track, scoreRange)
{
SegmentStartSeconds = segmentStartOffset.TotalSeconds,
SegmentDurationSeconds = frameCount * converter.SecondsPerFrameStep,
Expand All @@ -103,9 +105,6 @@ public static (List<EventCommon> Events, double[] CombinedIntensity) GetForwardT
}
}

//Following line used only for debug purposes.
//spectrogram.Save("C:\\temp\\SpectrogramWithTracks.png");

List<EventCommon> returnEvents = events.Cast<EventCommon>().ToList();

// Combine coincident events that are stacked one above other.
Expand Down
6 changes: 4 additions & 2 deletions src/AudioAnalysisTools/Tracks/OnebinTrackAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace AudioAnalysisTools.Tracks
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Acoustics.Shared;
using AnalysisPrograms.Recognizers.Base;
using AudioAnalysisTools.Events;
using AudioAnalysisTools.Events.Tracks;
Expand Down Expand Up @@ -80,10 +81,11 @@ public static (List<EventCommon> ListOfevents, double[] CombinedIntensityArray)
// Initialise tracks as events and get the combined intensity array.
var events = new List<WhistleEvent>();
var combinedIntensityArray = new double[frameCount];
var maxScore = decibelThreshold * 5;
var scoreRange = new Interval<double>(0, decibelThreshold * 5);

foreach (var track in tracks)
{
var ae = new WhistleEvent(track, maxScore)
var ae = new WhistleEvent(track, scoreRange)
{
SegmentStartSeconds = segmentStartOffset.TotalSeconds,
SegmentDurationSeconds = frameCount * converter.SecondsPerFrameStep,
Expand Down
8 changes: 5 additions & 3 deletions src/AudioAnalysisTools/Tracks/UpwardTrackAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace AudioAnalysisTools.Tracks
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Acoustics.Shared;
using AudioAnalysisTools.Events;
using AudioAnalysisTools.Events.Tracks;
using AudioAnalysisTools.Events.Types;
Expand Down Expand Up @@ -76,14 +77,15 @@ public static (List<EventCommon> Events, double[] CombinedIntensity) GetUpwardTr
// initialise tracks as events and get the combined intensity array.
var events = new List<SpectralEvent>();
var temporalIntensityArray = new double[frameCount];
var maxScore = decibelThreshold * 5;
var scoreRange = new Interval<double>(0.0, decibelThreshold * 5);

foreach (var track in tracks)
{
var ae = new WhipEvent(track, maxScore)
var ae = new WhipEvent(track, scoreRange)
{
SegmentStartSeconds = segmentStartOffset.TotalSeconds,
SegmentDurationSeconds = frameCount * converter.SecondsPerFrameStep,
Name = "noName",
Name = "Whip",
};

events.Add(ae);
Expand Down
2 changes: 1 addition & 1 deletion src/AudioAnalysisTools/UnitConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public UnitConverters(double segmentStartOffset, int sampleRate, int frameSize,
/// <remarks>
/// Measured in seconds per spectrogram frame.
/// </remarks>
public LinearSecondsScale SecondsScale { get; }
//public LinearSecondsScale SecondsScale { get; }

/// <summary>
/// Gets the spectral scale.
Expand Down

0 comments on commit deee017

Please sign in to comment.