forked from swharden/Spectrogram
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMel.cs
More file actions
121 lines (105 loc) · 4.8 KB
/
Mel.cs
File metadata and controls
121 lines (105 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using NUnit.Framework;
using System;
using SkiaSharp;
namespace Spectrogram.Tests
{
class Mel
{
[Test]
public void Test_MelSpectrogram_MelScale()
{
(double[] audio, int sampleRate) = AudioFile.ReadWAV("../../../../../data/cant-do-that-44100.wav");
int fftSize = 4096;
var sg = new SpectrogramGenerator(sampleRate, fftSize, stepSize: 500);
sg.Add(audio);
// Ottieni l'immagine Mel-scaled come SKBitmap
SKBitmap bmpMel = sg.GetBitmapMel(250); // Presuppone che sg abbia un metodo GetSKBitmapMel
using (var image = SKImage.FromBitmap(bmpMel))
using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
{
// Salva l'immagine Mel-scaled
using (var stream = System.IO.File.OpenWrite("../../../../../dev/graphics/halMel-MelScale.png"))
{
data.SaveTo(stream);
}
}
// Ottieni l'immagine originale come SKBitmap
SKBitmap bmpRaw = sg.GetBitmap(); // Presuppone che sg abbia un metodo GetSKBitmap
SKBitmap bmpCropped = new SKBitmap(bmpRaw.Width, bmpMel.Height);
// Disegna bmpRaw su bmpCropped usando SKCanvas
using (var canvas = new SKCanvas(bmpCropped))
{
canvas.Clear(SKColors.Transparent);
canvas.DrawBitmap(bmpRaw, new SKRect(0, bmpMel.Height - bmpRaw.Height, bmpRaw.Width, bmpMel.Height));
}
using (var imageCropped = SKImage.FromBitmap(bmpCropped))
using (var dataCropped = imageCropped.Encode(SKEncodedImageFormat.Png, 100))
{
// Salva l'immagine croppata
using (var streamCropped = System.IO.File.OpenWrite("../../../../../dev/graphics/halMel-LinearCropped.png"))
{
dataCropped.SaveTo(streamCropped);
}
}
}
[Test]
public void Test_Mel_Graph()
{
int specPoints = 4096;
double maxFreq = 50_000;
double maxMel = 2595 * Math.Log10(1 + maxFreq / 700);
Random rand = new Random(1);
double[] freq = ScottPlot.Generate.Consecutive(specPoints, maxFreq / specPoints);
double[] power = ScottPlot.Generate.RandomWalk(specPoints, .02, .5);
var plt1 = new ScottPlot.Plot();
plt1.Add.ScatterLine(freq, power);
int filterSize = 25;
// generate scales
double[] pointsLinear = new double[filterSize + 1];
double[] pointsMel = new double[filterSize + 1];
for (int i = 0; i < filterSize + 1; i++)
{
double thisFreq = maxFreq * i / filterSize;
double thisMel = maxMel * i / filterSize;
pointsLinear[i] = thisFreq;
pointsMel[i] = 700 * (Math.Pow(10, thisMel / 2595d) - 1);
}
// draw rectangles
double[] binStartFreqs = pointsMel;
for (int binIndex = 0; binIndex < binStartFreqs.Length - 2; binIndex++)
{
double freqLow = binStartFreqs[binIndex];
double freqCenter = binStartFreqs[binIndex + 1];
double freqHigh = binStartFreqs[binIndex + 2];
double[] xs = [freqLow, freqCenter, freqHigh];
double[] ys = [0, 1, 0];
var sctr = plt1.Add.ScatterLine(xs, ys);
int indexLow = (int)(specPoints * freqLow / maxFreq);
int indexHigh = (int)(specPoints * freqHigh / maxFreq);
int indexSpan = indexHigh - indexLow;
Console.WriteLine($"bin {binIndex}: [{freqLow} Hz - {freqHigh} Hz] = [{indexLow}:{indexHigh}]");
double binValue = 0;
double binScaleSum = 0;
for (int i = 0; i < indexSpan; i++)
{
double frac = (double)i / indexSpan;
frac = (frac < .5) ? frac * 2 : 1 - frac;
binScaleSum += frac;
binValue += power[indexLow + i] * frac;
}
binValue /= binScaleSum;
plt1.Add.Marker(freqCenter, binValue, ScottPlot.MarkerShape.FilledCircle, 10, sctr.Color);
}
plt1.SavePng("mel1.png", 800, 300);
}
[Test]
public void Test_SaveEmpty_Throws()
{
(double[] audio, int sampleRate) = AudioFile.ReadWAV("../../../../../data/cant-do-that-44100.wav");
int fftSize = 4096;
var spec = new SpectrogramGenerator(sampleRate, fftSize, stepSize: 500);
//spec.Add(audio);
Assert.Throws<InvalidOperationException>(() => { spec.SaveImage("empty.png"); });
}
}
}