Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue332 create new spectrogram types #353

Merged
merged 39 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d9688f9
Set up structure for two new spectrograms
towsey Jul 30, 2020
68a0ba2
Fix bug concerning assigning colour codes to spectrogram types
towsey Jul 30, 2020
57cdec6
Produce Mel frequency scale spectorgrams
towsey Jul 30, 2020
a7ca52f
Work on Octave Spectrograms
towsey Jul 31, 2020
c20e4ca
More work on Octave scales
towsey Aug 2, 2020
ea1e55f
Start setting up more detailed tests for octave frequency scales
towsey Aug 3, 2020
e847cb7
Change Scale Type names
towsey Aug 4, 2020
52556ac
Shift methods to do with Mel scale
towsey Aug 4, 2020
1598a40
Make Octave Scale methods more efficient
towsey Aug 4, 2020
c16ab0d
Add tests and rework existing tests for frequency scales
towsey Aug 4, 2020
0347e3f
Create new unit test for spectral data reduction
towsey Aug 5, 2020
b62e20e
Work on Mel scale spectrograms
towsey Aug 6, 2020
743fda8
Work on Octave scale spectrograms
towsey Aug 6, 2020
3efb633
Work on Unit tests for mel and octave scale spectrograms.
towsey Aug 6, 2020
277a0de
Mostly remove unused code and tidy comments.
towsey Aug 11, 2020
9f2904f
Change Hamming to Hanning Window
towsey Aug 11, 2020
a3778e3
Update BaseSonogram.cs
towsey Aug 11, 2020
834fa95
Fix production of Octave spectrogram
towsey Aug 11, 2020
7ed5281
Remove unused code
towsey Aug 11, 2020
f3eb3ed
Fix production of Octave scale spectrogram
towsey Aug 11, 2020
0a643f1
Automate calculation of Octave scale bounds and its gridlines.
towsey Aug 12, 2020
5908e27
More work on Octave Frequency scales
towsey Aug 13, 2020
28832b5
New tests and revise tests for Octave scale
towsey Aug 13, 2020
b423044
Rework Ocatve scale when calculating acoustic indices
towsey Aug 13, 2020
6dbe9ba
Incorporate epsilon in to log transform
towsey Aug 17, 2020
2a8c3e2
More epsilon/log of zero fixes.
towsey Aug 17, 2020
adcab04
Fix generation of additional spectrogram types.
towsey Aug 17, 2020
ec48abd
Merge branch 'master' into Issue332_Create_new_spectrogram_types
towsey Aug 17, 2020
0e429f7
Update FrequencyScaleTests.cs
towsey Aug 17, 2020
5031e9a
Remove unnecssary code, change method names
towsey Aug 18, 2020
5f26e3f
Work on Octave frequency scale
towsey Aug 18, 2020
5fa1979
Add in new spectrogram image.
towsey Aug 19, 2020
f10ea68
New methods for rescaling linear spectrograms
towsey Aug 19, 2020
01aa9be
Fix errors in octave frequency scale
towsey Aug 19, 2020
93c2703
Update FrequencyScaleTests.cs
towsey Aug 19, 2020
6acfa88
Shift methods to better locations
towsey Aug 20, 2020
13968a3
Fix up octave data reduction
towsey Aug 20, 2020
2b6821f
Fixing Unit tests
towsey Aug 20, 2020
4fd5f38
Fixes unit tests
atruskie Aug 21, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AudioAnalysis.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=dedupe/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=DTMF/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ecosounds/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=enumerables/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ffmpeg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ffprobe/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=flac/@EntryIndexedValue">True</s:Boolean>
Expand Down
3 changes: 2 additions & 1 deletion src/Acoustics.Shared/Acoustics.Shared.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyTitle>Acoustics.Shared</AssemblyTitle>
Expand Down Expand Up @@ -28,6 +28,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.6" />
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="morelinq" Version="3.3.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ObjectCloner" Version="2.2.2" />
<PackageReference Include="ObjectCloner.Extensions" Version="2.0.1" />
Expand Down
2 changes: 1 addition & 1 deletion src/Acoustics.Shared/ColorScales/Palette.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ public class Palette

public List<Color[]> Colors { get; internal set; }

public Color[] ForClassCount(int classCount) => this.Colors.FirstOrDefault(x => x.Length == classCount);
public Color[] ForClassCount(int classCount) => this.Colors.FirstOrDefault(x => x.Length >= classCount);
}
}
42 changes: 42 additions & 0 deletions src/Acoustics.Shared/Extensions/ArrayExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
// ReSharper disable once CheckNamespace
namespace System
{
//using MoreLinq;
using static MoreLinq.Extensions.RepeatExtension;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Acoustics.Shared.Extensions;

public static class ArrayExtensions
{
Expand Down Expand Up @@ -105,6 +110,43 @@ public static T[] Print<T>(this T[] array)
return array;
}

/// <summary>
/// Prints a multi-dimensional matrix as a C# literal.
/// </summary>
/// <remarks>Assumes all ranks have a lower bound of zero.</remarks>
/// <typeparam name="T">Cast element items to T before toString is called.</typeparam>
/// <param name="array">The source array to print.</param>
public static string PrintAsLiteral<T>(this Array array)
{
var dimensions = Enumerable.Range(0, array.Rank);
var sizes = dimensions.Select(array.GetLength).ToArray();
//var dimensionsWithSize = dimensions.Zip(sizes);

var last = Enumerable.Range(0, sizes[^1]).ToArray();

// the last dimension we iterate across to generate the literal values
var result = sizes[..^1]
.Select(s => Enumerable.Range(0, s))
.MultiCartesian(FormatValue)
.Join(", ")
.WordWrap(leftPadding: 4, splitOn: "},", keepSplit: true);

return @$"{{
{result}
}}";

string FormatValue(IEnumerable<int> indices)
{
var depth = sizes.Length;
var lineDepth = depth - 1;
var start = "{ ".Repeat(lineDepth).Join();
var end = " }".Repeat(lineDepth).Join();
var value = last.Select(x => (T)array.GetValue(indices.Append(x).ToArray())).Join(", ");

return start + value + end;
}
}

/// <summary>
/// Compares two arrays, matching each element in order using the default Equals method for the array type T.
/// </summary>
Expand Down
77 changes: 77 additions & 0 deletions src/Acoustics.Shared/Extensions/CartesianExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// <copyright file="CartesianExtension.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 Acoustics.Shared.Extensions
{
using System;
using System.Collections.Generic;
using System.Linq;
using MoreLinq.Extensions;

/// <summary>
/// Extensions to the MoreLinq.Cartesian function.
/// </summary>
public static class CartesianExtension
{
/// <summary>
/// Returns the Cartesian product of multiple sequences by combining each element of every set with every other element
/// and applying the user-defined projection to the pair.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="enumerables"/>.</typeparam>
/// <typeparam name="TResult">The type of the elements of the result sequence.</typeparam>
/// <param name="enumerables">The sequence of sequences of element.s</param>
/// <param name="resultSelector">A projection function that combines elements from both sequences.</param>
/// <returns>A sequence representing the Cartesian product of the source sequences.</returns>
public static IEnumerable<TResult> MultiCartesian<TSource, TResult>(
this IEnumerable<IEnumerable<TSource>> enumerables,
Func<IEnumerable<TSource>, TResult> resultSelector)
{
if (enumerables == null)
{
throw new ArgumentNullException(nameof(enumerables));
}

if (resultSelector == null)
{
throw new ArgumentNullException(nameof(resultSelector));
}

var enumerators = enumerables
.Select(e => e?.GetEnumerator() ?? throw new ArgumentException("One of the enumerables is null"))
.Pipe(e => e.MoveNext())
.ToArray();

do
{
yield return resultSelector(enumerators.Select(e => e.Current));
} while (MoveNext());

foreach (var enumerator in enumerators)
{
enumerator.Dispose();
}

bool MoveNext()
{
for (var i = enumerators.Length - 1; i >= 0; i--)
{
if (enumerators[i].MoveNext())
{
return true;
}

if (i == 0)
{
continue;
}

enumerators[i].Reset();
enumerators[i].MoveNext();
}

return false;
}
}
}
}
10 changes: 6 additions & 4 deletions src/Acoustics.Shared/Extensions/ExtensionsString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,15 @@ public static string Truncate(this string text, int length, string ellipsis, boo
return text + ellipsis;
}

public static string WordWrap(this string text, int wrapThreshold = 120, int leftPadding = 0)
public static string WordWrap(this string text, int wrapThreshold = 120, int leftPadding = 0, string splitOn = " ", bool keepSplit = false)
{
if (string.IsNullOrEmpty(text))
{
return text;
}

int splitLength = splitOn.Length;

string leftPad = string.Empty.PadRight(leftPadding);

// wrap lines
Expand All @@ -229,16 +231,16 @@ public static string WordWrap(this string text, int wrapThreshold = 120, int lef

while (currentLine.Length > wrapThreshold)
{
int splitPoint = currentLine.Substring(0, wrapThreshold).LastIndexOf(' ');
int splitPoint = currentLine.Substring(0, wrapThreshold).LastIndexOf(splitOn);

if (splitPoint < 0)
{
splitPoint = wrapThreshold; // cuts through a word
}

result.AppendLine(leftPad + currentLine.Substring(0, splitPoint));
result.AppendLine(leftPad + currentLine.Substring(0, splitPoint + (keepSplit ? splitLength : 0)));

currentLine = currentLine.Substring(splitPoint + 1);
currentLine = currentLine.Substring(splitPoint + splitLength);
}

if (currentLine.IsNotWhitespace())
Expand Down
3 changes: 3 additions & 0 deletions src/AnalysisConfigFiles/Towsey.SpectrogramGenerator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ Images:
- DecibelSpectrogramNoiseReduced
- Experimental
- DifferenceSpectrogram
- MelScaleSpectrogram
- CepstralSpectrogram
- OctaveScaleSpectrogram
- RibbonSpectrogram
- AmplitudeSpectrogramLocalContrastNormalization


Expand Down
35 changes: 20 additions & 15 deletions src/AnalysisPrograms/PlanesTrainsAndAutomobiles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,18 +185,23 @@ public static Tuple<BaseSonogram, double[,], double[], List<AcousticEvent>> Dete
TimeSpan duration = recording.Duration;
NoiseReductionType nrt = SNR.KeyToNoiseReductionType("STANDARD");

var sonogram = (BaseSonogram)SpectrogramStandard.GetSpectralSonogram(
recording.BaseName,
windowSize,
windowOverlap,
bitsPerSample,
windowPower,
sr,
duration,
nrt,
matrix);

sonogram.DecibelsNormalised = new double[rowCount];
//Set the default values config
SonogramConfig sonoConfig = new SonogramConfig
{
SourceFName = recording.BaseName,
WindowSize = windowSize,
WindowOverlap = windowOverlap,
NoiseReductionType = nrt,
epsilon = Math.Pow(0.5, bitsPerSample - 1),
WindowPower = windowPower,
SampleRate = sr,
Duration = duration,
};

var sonogram = new SpectrogramStandard(sonoConfig, matrix)
{
DecibelsNormalised = new double[rowCount],
};

//foreach frame or time step
for (int i = 0; i < rowCount; i++)
Expand All @@ -205,7 +210,7 @@ public static Tuple<BaseSonogram, double[,], double[], List<AcousticEvent>> Dete
}

sonogram.DecibelsNormalised = DataTools.normalise(sonogram.DecibelsNormalised);
return Tuple.Create(sonogram, hits, scoreArray, predictedEvents);
} //end Execute_HDDetect
return Tuple.Create((BaseSonogram)sonogram, hits, scoreArray, predictedEvents);
}
}
} //end class PlanesTrainsAndAutomobiles
}
Loading