Skip to content

Commit 8fa9232

Browse files
committed
create tools module
1 parent 43c84ed commit 8fa9232

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

src/Spectrogram/Tools.cs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Spectrogram
7+
{
8+
public static class Tools
9+
{
10+
/// <summary>
11+
/// Collapse the 2D spectrogram into a 1D array (mean power of each frequency)
12+
/// </summary>
13+
public static double[] SffMeanFFT(SFF sff, bool dB = false)
14+
{
15+
double[] mean = new double[sff.Ffts[0].Length];
16+
17+
foreach (var fft in sff.Ffts)
18+
for (int y = 0; y < fft.Length; y++)
19+
mean[y] += fft[y];
20+
21+
for (int i = 0; i < mean.Length; i++)
22+
mean[i] /= sff.Ffts.Count();
23+
24+
if (dB)
25+
for (int i = 0; i < mean.Length; i++)
26+
mean[i] = 20 * Math.Log10(mean[i]);
27+
28+
if (mean[mean.Length - 1] <= 0)
29+
mean[mean.Length - 1] = mean[mean.Length - 2];
30+
31+
return mean;
32+
}
33+
34+
/// <summary>
35+
/// Collapse the 2D spectrogram into a 1D array (mean power of each time point)
36+
/// </summary>
37+
public static double[] SffMeanPower(SFF sff, bool dB = false)
38+
{
39+
double[] power = new double[sff.Ffts.Count];
40+
41+
for (int i = 0; i < sff.Ffts.Count; i++)
42+
power[i] = (double)sff.Ffts[i].Sum() / sff.Ffts[i].Length;
43+
44+
if (dB)
45+
for (int i = 0; i < power.Length; i++)
46+
power[i] = 20 * Math.Log10(power[i]);
47+
48+
return power;
49+
}
50+
51+
public static double GetPeakFrequency(SFF sff, bool firstFftOnly = false)
52+
{
53+
double[] freqs = firstFftOnly ? sff.Ffts[0] : SffMeanFFT(sff, false);
54+
55+
int peakIndex = 0;
56+
double peakPower = 0;
57+
for (int i = 0; i < freqs.Length; i++)
58+
{
59+
if (freqs[i] > peakPower)
60+
{
61+
peakPower = freqs[i];
62+
peakIndex = i;
63+
}
64+
}
65+
66+
double maxFreq = sff.SampleRate / 2;
67+
double frac = peakIndex / (double)sff.FftHeight;
68+
69+
if (sff.MelBinCount > 0)
70+
{
71+
double maxMel = FftSharp.Transform.MelFromFreq(maxFreq);
72+
return FftSharp.Transform.MelToFreq(frac * maxMel);
73+
}
74+
else
75+
{
76+
return frac * maxFreq;
77+
}
78+
}
79+
80+
public static int GetPianoKey(double frequencyHz)
81+
{
82+
double pianoKey = (39.86 * Math.Log10(frequencyHz / 440)) + 49;
83+
return (int)Math.Round(pianoKey);
84+
}
85+
86+
public static int GetMidiNote(int frequencyHz)
87+
{
88+
return GetPianoKey(frequencyHz) + 20;
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)