【问题标题】:How to read IMediaSample 24 bit PCM data如何读取 IMediaSample 24 位 PCM 数据
【发布时间】:2014-02-10 15:30:42
【问题描述】:

我有以下方法将 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 时读取垃圾。

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

缓冲区来自 IMediaSample。

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

【问题讨论】:

    标签: c# audio directshow pcm audio-processing


    【解决方案1】:

    我想通了:

    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 范围内。

    【讨论】:

      【解决方案2】:

      你试过了吗

      byte[] buffer24f = new byte[numSamples * 3];
      Marshal.Copy(Buffer, buffer24f, 0, numSamples);
      
      for (int j = 0; j < buffer24f.Length; j+=3)
      {
          samples[j / 3] = System.BitConverter.ToSingle(
                  new byte[] { 
                      0, 
                      buffer24f[j + 0], 
                      buffer24f[j + 1], 
                      buffer24f[j + 2]
                  }, 0);
      }
      

      【讨论】:

      • 24 位不是浮点数。它是整数音频。如果需要做的是弄清楚如何从字节缓冲区中组合一个整数,然后将其转换为浮点数以放入样本数组中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2020-08-08
      相关资源
      最近更新 更多