Я хочу отобразить частотный спектр WAV-файла. Я не знаю, как сделать это правильно. Я использую C# с naudio nuget
для обработки аудиоданных. Когда я вставляю все точки spec_data, у меня только один столбец, заполненный данными. (Рисунок 1) как это выглядит сейчас (Изображение 1) как это должно выглядеть в конце
Как получить все точки спектра аудиофайла ?
var buffer = new byte[fft_size];
int bytes_read = fileStream.Read(buffer, 0, buffer.Length);
int BYTES_PER_POINT = fileStream.WaveFormat.BitsPerSample / 8; //8Bit = 1Byte
short[] values = new short[buffer.Length / BYTES_PER_POINT];
for (int n = 0; n < BYTES_PER_POINT; n++)
{
for (int i = 0; i < bytes_read; i += BYTES_PER_POINT)
{
values[i / BYTES_PER_POINT] = (short)((buffer[i + 1] << 8) | buffer[i + 0]);
}
}
neanalizir_values.AddRange(values);
short[] data = new short[fft_size];
data = neanalizir_values.GetRange(0, fft_size).ToArray();
spec_data.RemoveAt(0);
List<double> new_data = new List<double>();
Complex[] fft_buffer = new Complex[fft_size];
for (int i = 0; i < fft_size; i++)
{
fft_buffer[i].X = (float)(neanalizir_values[i] * FastFourierTransform.HammingWindow(i, fft_size));
fft_buffer[i].Y = 0;
}
FastFourierTransform.FFT(true, (int)Math.Log(fft_size, 2.0), fft_buffer);
for (int i = 0; i < spec_data[spec_data.Count - 1].Count; i++)
{
double val;
val = (double)fft_buffer[i].X + (double)fft_buffer[i].Y;
val = Math.Abs(val);
new_data.Add(val);
}
new_data.Reverse();
spec_data.Insert(spec_data.Count, new_data);
neanalizir_values.RemoveRange(0, fft_size / pixelsPerBuffer);
Bitmap bitmap = new Bitmap(spec_data.Count, spec_data[0].Count, PixelFormat.Format8bppIndexed);
ColorPalette pal = bitmap.Palette;
for (int i = 0; i < 256; i++)
pal.Entries[i] = Color.FromArgb(255, i, i, i);
bitmap.Palette = pal;
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
byte[] pixels = new byte[bitmapData.Stride * bitmap.Height];
for (int col = 0; col < spec_data.Count; col++)
{
double scaleFactor = 40;
for (int row = 0; row < spec_data[col].Count; row++)
{
int bytePosition = row * bitmapData.Stride + col;
double pixelVal = spec_data[col][row] * scaleFactor;
pixelVal = Math.Max(0, pixelVal);
pixelVal = Math.Min(255, pixelVal);
pixels[bytePosition] = (byte)(pixelVal);
}
}
Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
bitmap.UnlockBits(bitmapData);
pictureBox1.Image = bitmap;