Skip to content

Commit

Permalink
Create spectrogram from standardizedfeaturesextraction
Browse files Browse the repository at this point in the history
-Created configuration file for SFE
-Fixed bug for empty/null configfile
-Create spectrogram within SFE
  • Loading branch information
aroelo committed Dec 12, 2017
1 parent ac02141 commit ab03d95
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 90 deletions.
5 changes: 5 additions & 0 deletions Acoustics/Acoustics.Shared/ConfigFile/ConfigFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ public static FileInfo ResolveConfigFile(FileInfo file, params DirectoryInfo[] s

public static FileInfo ResolveConfigFile(string file, params DirectoryInfo[] searchPaths)
{
if (file.IsNullOrEmpty())
{
throw new ArgumentException("Try to resolve config failed, because supplied file argument was null or empty.", nameof(file));
}

var success = TryResolveConfigFile(file, searchPaths.Select(x => x.ToDirectoryEntry()), out FileEntry configFile);

if (success)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
# Summary: Calculates standardized features for machine learning tasks

AnalysisName: Ecosounds.StandardizedFeatures
#SegmentDuration: units=minutes;
SegmentDuration: 1
#SegmentOverlap: units=seconds;
SegmentOverlap: 0

# BgNoiseNeighbourhood: units=seconds (default IndexCalculationDuration = 60 seconds)
# BG noise for any location is calculated by extending the region of index calculation from 5 seconds before start to 5 sec after end of current index interval.
# Ten seconds is considered a minimum interval to obtain a reliable estimate of BG noise.
# The BG noise interval is not extended beyond start or end of recording segment.
# Consequently for a 60sec Index calculation duration, the BG noise is calculated form the 60sec segment only.
BgNoiseNeighbourhood: 5

# Resample rate must be 2 X the desired Nyquist
ResampleRate: 22050

# FRAME LENGTH. units=samples
# FrameWidth is used without overlap to calculate the spectral indices. Typical value=512
FrameLength: 512


#Default values in code are LowFreqBound=1000Hz & MidFreqBound=8000
LowFreqBound: 1000
MidFreqBound: 8000
HighFreqBound: 11000

# FrequencyScale options are currently only Linear and Octave
# Octave scale is to be used only for Jasco Marine recordings @ sample rate = 64000
FrequencyScale: Linear

# SAVE INTERMEDIARY FILES
# Available options (case-sensitive): [False/Never | True/Always | WhenEventsDetected]
SaveIntermediateWavFiles: Never
SaveIntermediateCsvFiles: false
# One-minute spectrograms can be saved in any analysis task.
# Available options (case-sensitive): [False/Never | True/Always | WhenEventsDetected]
SaveSonogramImages: Never

# if true, an unambiguous date time must be provided in the source file's name.
# if true, an exception will be thrown if no such date is found
# if false, and a valid date is still found in file name, it will still be parsed
# supports formats like:
# prefix_20140101T235959+1000.mp3
# prefix_20140101T235959+Z.mp3
# prefix_20140101-235959+1000.mp3
# prefix_20140101-235959+Z.mp3
RequireDateInFilename: false

IndexPropertiesConfig: './IndexPropertiesConfig.yml'
...

3 changes: 2 additions & 1 deletion AudioAnalysis/AnalysisPrograms/AnalysisPrograms.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@
<Compile Include="SourcePreparers\RemoteSourcePreparer.cs" />
<Compile Include="SourcePreparers\LocalSourcePreparer.cs" />
<Compile Include="SourcePreparers\RemoteSourcePreparerException.cs" />
<Compile Include="StandardizedFeatureExtraction.cs" />
<Compile Include="StandardizedFeatures\StandardizedFeatureExtraction.cs" />
<Compile Include="SURFAnalysis.cs" />
<Compile Include="OscillationsGeneric.cs" />
<Compile Include="DifferenceSpectrogram.cs" />
Expand Down Expand Up @@ -415,6 +415,7 @@
<Analyzer Include="..\packages\StyleCop.Analyzers.1.1.0-beta004\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll" />
<Analyzer Include="..\packages\StyleCop.Analyzers.1.1.0-beta004\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
4 changes: 2 additions & 2 deletions AudioAnalysis/AnalysisPrograms/Production/Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace AnalysisPrograms.Production
using EventStatistics;
using PowerArgs;
using Recognizers.Base;
using StandardizedFeatureExtraction;
using StandardizedFeatures;

/// <summary>
/// Defines the various actions (sub programs) that we can run.
Expand Down Expand Up @@ -227,7 +227,7 @@ public static Action<object> TruskingerFelt()
public StandardizedFeatureExtraction.Arguments StandardizedFeatureExtractionArgs { get; set; }
public static Action<StandardizedFeatureExtraction.Arguments> StandardizedFeatureExtraction()
{
return AnalysisPrograms.StandardizedFeatureExtraction.StandardizedFeatureExtraction.Execute;
return StandardizedFeatures.StandardizedFeatureExtraction.Execute;
}

[ArgDescription("Calls SnrAnalysis.Execute(): Calculates signal to noise ratio.")]
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// <copyright file="StandardizedFeatureExtraction.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 AnalysisPrograms.StandardizedFeatures
{
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Security.Policy;
using Acoustics.Shared;
using Acoustics.Shared.ConfigFile;
using AnalysisBase;
using AnalysisBase.ResultBases;
using AudioAnalysisTools;
using AudioAnalysisTools.DSP;
using AudioAnalysisTools.Indices;
using AudioAnalysisTools.WavTools;
using log4net.Repository.Hierarchy;
using PowerArgs;
using TowseyLibrary;

public class StandardizedFeatureExtraction : AbstractStrongAnalyser
{
private const string Sentence = "Hello World";

// Input is a class object of Arguments, class is made below
public static void Execute(Arguments arguments)
{
for (int i = 0; i < arguments.Multiplication; i++)
{
Console.WriteLine(Sentence);
}
}

// Creates a class that constructs arguments, the description is shown in help StandardizedFeatureExtraction
// The variable Multiplication can later be used
public class Arguments
{
[ArgDescription("How many times hello world")]
public int Multiplication { get; set; }
}

// Implemented from AbstractStrongAnalyser
public override string DisplayName
{
get { return "Standardized Feature Extraction"; }
}

public override string Identifier
{
get { return "Ecosounds.StandardizedFeatures"; }
}

public virtual string Description
{
get { return "Performs a standardized feature extraction."; }
}

public override AnalysisResult2 Analyze<T>(AnalysisSettings analysisSettings, SegmentSettings<T> segmentSettings)
{
var audioFile = segmentSettings.SegmentAudioFile;
var recording = new AudioRecording(audioFile.FullName);
var outputDirectory = segmentSettings.SegmentOutputDirectory;
//int sampleRate = recording.WavReader.SampleRate;

var analysisResults = new AnalysisResult2(analysisSettings, segmentSettings, recording.Duration);

// Convert the dynamic config to IndexCalculateConfig class and merge in the unnecesary parameters.
IndexCalculateConfig config = IndexCalculateConfig.GetConfig(analysisSettings.Configuration, false);

int frameSize = config.FrameLength;
int frameStep = frameSize;
//var indexCalculationDuration = config.IndexCalculationDuration;

//// get duration in seconds and sample count and frame count
//double subsegmentDurationInSeconds = indexCalculationDuration.TotalSeconds;
//int subsegmentSampleCount = (int)(subsegmentDurationInSeconds * sampleRate);
//double subsegmentFrameCount = subsegmentSampleCount / (double)frameStep;
//subsegmentFrameCount = (int)Math.Ceiling(subsegmentFrameCount);

//// In order not to lose the last fractional frame, round up the frame number
//// and get the exact number of samples in the integer number of frames.
//// Do this because when IndexCalculationDuration = 100ms, the number of frames is only 8.
//subsegmentSampleCount = (int)(subsegmentFrameCount * frameStep);

//// get start and end samples of the subsegment and noise segment
//double localOffsetInSeconds = segmentSettings.SegmentStartOffset.TotalSeconds;
//int startSample = (int)(localOffsetInSeconds * sampleRate);
//int endSample = startSample + subsegmentSampleCount - 1;

// Default behaviour: set SUBSEGMENT = total recording
AudioRecording subsegmentRecording = recording;

//double[] subsamples = DataTools.Subarray(recording.WavReader.Samples, startSample, subsegmentSampleCount);
//var wr = new Acoustics.Tools.Wav.WavReader(subsamples, 1, 16, sampleRate);
//subsegmentRecording = new AudioRecording(wr);

// EXTRACT ENVELOPE and SPECTROGRAM FROM SUBSEGMENT
var dspOutput1 = DSP_Frames.ExtractEnvelopeAndFfts(subsegmentRecording, frameSize, frameStep);

analysisSettings.AnalysisImageSaveBehavior = SaveBehavior.Always;

if (analysisSettings.AnalysisImageSaveBehavior.ShouldSave())
{
string imagePath = Path.Combine(outputDirectory.FullName, segmentSettings.SegmentImageFile.Name);

//prepare amplitude spectrogram
double[,] amplitudeSpectrogramData = dspOutput1.AmplitudeSpectrogram; // get amplitude spectrogram.
var image = ImageTools.DrawReversedMatrix(MatrixTools.MatrixRotate90Anticlockwise(amplitudeSpectrogramData));
image.Save(imagePath, ImageFormat.Png);
analysisResults.ImageFile = new FileInfo(imagePath);
}
//image.Save(@"C:\Work\Output\testimage.png", ImageFormat.Png);

return analysisResults;
}

public override void WriteEventsFile(FileInfo destination, IEnumerable<EventBase> results)
{
throw new NotImplementedException();
}

public override void WriteSummaryIndicesFile(FileInfo destination, IEnumerable<SummaryIndexBase> results)
{
throw new NotImplementedException();
}

public override List<FileInfo> WriteSpectrumIndicesFiles(DirectoryInfo destination, string fileNameBase, IEnumerable<SpectralIndexBase> results)
{
throw new NotImplementedException();
}

public override void SummariseResults(
AnalysisSettings settings,
FileSegment inputFileSegment,
EventBase[] events,
SummaryIndexBase[] indices,
SpectralIndexBase[] spectralIndices,
AnalysisResult2[] results)
{
// no op
}
}
}

0 comments on commit ab03d95

Please sign in to comment.