gpt4 book ai didi

c# - 如何读取 IMediaSample 24 位 PCM 数据

转载 作者:行者123 更新时间:2023-12-03 00:50:39 29 4
gpt4 key购买 nike

我有以下方法将 PCM 数据从 IMediaSample 收集到 FFT 的浮点数中:

    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 非浮点数,但我只能在位为 24 时读取垃圾。

我怎样才能使它适应进入缓冲区的 24 位 PCM?

缓冲区来自 IMediaSample。

我想知道的另一件事是,我用来通过将所有 channel 相加并除以 channel 数的方法是否可以...

最佳答案

我想到了:

byte[] buffer24 = new byte[numSamples * 3];
Marshal.Copy(Buffer, buffer24, 0, numSamples * 3);
var window = (float)(255 << 16 | 255 << 8 | 255);

for (int j = 0; j < buffer24.Length; j+=3)
{
samples[j / 3] = (buffer24[j] << 16 | buffer24[j + 1] << 8 | buffer24[j + 2]) / window;
}

从三个字节创建一个整数,然后通过除以三个字节的最大值将其缩放到 1/-1 范围内。

关于c# - 如何读取 IMediaSample 24 位 PCM 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21681269/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com