У меня есть следующий метод, который собирает данные PCM из IMediaSample в поплавки для БПФ:
public int PCMDataCB(IntPtr Buffer, int Length, ref TDSStream Stream, out float[] singleChannel)
{
int numSamples = Length / (Stream.Bits / 8);
int samplesPerChannel = numSamples / Stream.Channels;
float[] samples = new float[numSamples];
if (Stream.Bits == 32 && Stream.Float) {
// this seems to work for 32 bit floating point
byte[] buffer32f = new byte[numSamples * 4];
Marshal.Copy(Buffer, buffer32f, 0, numSamples);
for (int j = 0; j < buffer32f.Length; j+=4)
{
samples[j / 4] = System.BitConverter.ToSingle(new byte[] { buffer32f[j + 0], buffer32f[j + 1], buffer32f[j + 2], buffer32f[j + 3]}, 0);
}
}
else if (Stream.Bits == 24)
{
// I need this code
}
// compress result into one mono channel
float[] result = new float[samplesPerChannel];
for (int i = 0; i < numSamples; i += Stream.Channels)
{
float tmp = 0;
for (int j = 0; j < Stream.Channels; j++)
tmp += samples[i + j] / Stream.Channels;
result[i / Stream.Channels] = tmp;
}
// mono output to be used for visualizations
singleChannel = result;
return 0;
}
Кажется, работает для 32b с плавающей запятой, потому что я получаю разумные данные в анализаторе спектра (хотя они кажутся слишком сдвинутыми (или сжатыми?) к более низким частотам).
Кажется, мне также удалось заставить его работать для 8, 16 и 32 non float, но я могу читать мусор только тогда, когда биты равны 24.
Как я могу адаптировать это для работы с 24-битным PCM, поступающим в буфер?
Буфер поступает из IMediaSample.
Еще мне интересно, подходит ли метод, который я использую для добавления всех каналов в один путем суммирования и деления на количество каналов...