diff --git a/src/AnalysisConfigFiles/IndexPropertiesConfig.yml b/src/AnalysisConfigFiles/IndexPropertiesConfig.yml index 87ce5705d..4f268587a 100644 --- a/src/AnalysisConfigFiles/IndexPropertiesConfig.yml +++ b/src/AnalysisConfigFiles/IndexPropertiesConfig.yml @@ -156,6 +156,16 @@ AvgEventDuration: NormMax: 1000 ProjectID: Acoustic Indices Units: "ms" +SpectralCentroid: + Name: SpectralCentroid + Comment: "Av of all frame spectral-centroid values in audio segment." + DataType: double + DefaultValue: 0.0 + DoDisplay: true + NormMin: 0.0 + NormMax: 1.0 + ProjectID: Acoustic Indices + Units: "" #EventsTotal: # Name: Event Count # Comment: "The total count of acoustic events per minute of recording." diff --git a/src/AudioAnalysisTools/Indices/IndexCalculate.cs b/src/AudioAnalysisTools/Indices/IndexCalculate.cs index c2b7e01d8..5e0fcdd88 100644 --- a/src/AudioAnalysisTools/Indices/IndexCalculate.cs +++ b/src/AudioAnalysisTools/Indices/IndexCalculate.cs @@ -383,6 +383,10 @@ public static IndexCalculateResult Analysis( double entropyOfPeaksSpectrum = AcousticEntropy.CalculateEntropyOfSpectralPeaks(amplitudeSpectrogram, lowerBinBound, middleBinBound); summaryIndices.EntropyOfPeaksSpectrum = 1 - entropyOfPeaksSpectrum; + // vii Calculate SPECTRAL CENTROID for the recording segment. This is obtained by averaging over all frame spectral centroids in segment. + var centroidArray = SpectralCentroid.CalculateSpectralCentroids(amplitudeSpectrogram, nyquist); + summaryIndices.SpectralCentroid = centroidArray.Average(); + // ###################################################################################################################################################### // (C) ################################## EXTRACT SPECTRAL INDICES FROM THE DECIBEL SPECTROGRAM ################################## diff --git a/src/AudioAnalysisTools/Indices/InitialiseIndexProperties.cs b/src/AudioAnalysisTools/Indices/InitialiseIndexProperties.cs index b0dd2280a..ded1b8350 100644 --- a/src/AudioAnalysisTools/Indices/InitialiseIndexProperties.cs +++ b/src/AudioAnalysisTools/Indices/InitialiseIndexProperties.cs @@ -20,11 +20,11 @@ namespace AudioAnalysisTools.Indices /// TO CREATE AND IMPLEMENT A NEW ACOUSTIC INDEX (BOTH SUMMARY AND SPECTRAL INDICES), DO THE FOLLOWING: /// 1) Create a KEY or IDENTIFIER for the index in the list below. Always use this key when referencing the index. /// 2) Declare the properties of the new index in the YAML file: C:\Work\GitHub\audio-analysis\src\AnalysisConfigFiles\IndexPropertiesConfig.yml - /// 3) Modify the method SpectralIndexValues.CreateImageOfSpectralIndices(SpectralIndexValues spectralIndices) to incorporate the new index + /// 3) if necessary, modify the method SpectralIndexValues.CreateImageOfSpectralIndices(SpectralIndexValues spectralIndices) to incorporate the new index /// 4) Calculate the INDEX some where. In the case of Acoustic Indices, they are calculated in the class IndicesCalculate.cs. - /// 5) Store the value of the index in the class IndexValues - /// 5a) e.g. for spectral index: indexValues.AddSpectrum(InitialiseIndexProperties.KEYspectralENT, spectrumOfENTvalues); - /// 5b) e.g. for summary index: indexValues.StoreIndex(InitialiseIndexProperties.KEYindexName, indexValue); + /// 5) Store the value of the index in the class SummaryIndexValues or class SpectralIndexValues, as appropriate. + /// 5a) e.g. for spectral index: indexValues.AddSpectrum(InitialiseIndexProperties.KEYspectralENT, spectrumOfENTvalues); + /// 5b) e.g. for summary index: indexValues.StoreIndex(InitialiseIndexProperties.KEYindexName, indexValue); /// 6) Add lines into IndexCalculateTest.TestOfSpectralIndices() to set up testing for the new index /// ============== */ @@ -54,6 +54,7 @@ public static class InitialiseIndexProperties public const string KeyActivity = "Activity"; public const string KeyEventsPerSec = "EventsPerSec"; public const string KeyAvEventDuration = "AvEventDuration"; + public const string SpectralCentroid = "SpectralCentroid"; public const string KeyHfCvr = "HF_CVR"; public const string KeyMfCvr = "MF_CVR"; public const string KeyLfCvr = "LF_CVR"; @@ -68,22 +69,6 @@ public static class InitialiseIndexProperties public const string KeySptPerSec = "SPTPerSec"; public const string KeySptDur = "AvSPTDuration"; - //KEYS FOR SPECTRAL INDICES - // Initially thought that these would be useful but as of February 2019 none used, so commented. - - //public const string KeYspectralAci = "ACI"; - //public const string KeySpectralBgn = "BGN"; - //public const string KeYspectralCvr = "CVR"; - //public const string KeYspectralEnt = "ENT"; - //public const string KeYspectralEvn = "EVN"; - //public const string KeySpectralOsc = "OSC"; - //public const string KeySpectralPmn = "PMN"; - //public const string KeySpectralRhz = "RHZ"; - //public const string KeySpectralRng = "RNG"; - //public const string KeySpectralRps = "RPS"; - //public const string KeySpectralRvt = "RVT"; - //public const string KeySpectralSpt = "SPT"; - public static double ClippingThreshold { get diff --git a/src/AudioAnalysisTools/Indices/SummaryIndexValues.cs b/src/AudioAnalysisTools/Indices/SummaryIndexValues.cs index 0e17f44d3..09d6699d4 100644 --- a/src/AudioAnalysisTools/Indices/SummaryIndexValues.cs +++ b/src/AudioAnalysisTools/Indices/SummaryIndexValues.cs @@ -135,6 +135,7 @@ public static Dictionary ConvertToDictionaryOfSummaryIndices(L { "AvgSnrOfActiveFrames", summaryIndices.Select(x => x.AvgSnrOfActiveFrames).ToArray() }, { "Activity", summaryIndices.Select(x => x.Activity).ToArray() }, { "EventsPerSecond", summaryIndices.Select(x => x.EventsPerSecond).ToArray() }, + { "SpectralCentroid", summaryIndices.Select(x => x.SpectralCentroid).ToArray() }, { "HighFreqCover", summaryIndices.Select(x => x.HighFreqCover).ToArray() }, { "MidFreqCover", summaryIndices.Select(x => x.MidFreqCover).ToArray() }, { "LowFreqCover", summaryIndices.Select(x => x.LowFreqCover).ToArray() }, @@ -174,6 +175,8 @@ public static Dictionary ConvertToDictionaryOfSummaryIndices(L public double EventsPerSecond { get; set; } + public double SpectralCentroid { get; set; } + public double HighFreqCover { get; set; } public double MidFreqCover { get; set; } diff --git a/tests/Acoustics.Test/AudioAnalysisTools/Indices/IndexCalculateTest.cs b/tests/Acoustics.Test/AudioAnalysisTools/Indices/IndexCalculateTest.cs index 65424cf75..f6e02e4ec 100644 --- a/tests/Acoustics.Test/AudioAnalysisTools/Indices/IndexCalculateTest.cs +++ b/tests/Acoustics.Test/AudioAnalysisTools/Indices/IndexCalculateTest.cs @@ -90,6 +90,7 @@ public void TestOfSummaryIndices() Assert.AreEqual(0.260999, summaryIndices.EntropyOfPeaksSpectrum, AllowedDelta); Assert.AreEqual(0.522080, summaryIndices.EntropyOfVarianceSpectrum, AllowedDelta); Assert.AreEqual(2.0, summaryIndices.EventsPerSecond, AllowedDelta); + Assert.AreEqual(0.467151, summaryIndices.SpectralCentroid, AllowedDelta); Assert.AreEqual(0.140306, summaryIndices.HighFreqCover, AllowedDelta); Assert.AreEqual(0.137873, summaryIndices.MidFreqCover, AllowedDelta); Assert.AreEqual(0.055341, summaryIndices.LowFreqCover, AllowedDelta);