【问题标题】:Converting IntPtr to Audio Data Array将 IntPtr 转换为音频数据数组
【发布时间】:2018-07-24 19:04:47
【问题描述】:

我一直在尝试在 Unity 上实现WebRTC 音频/视频通信。到目前为止,在this blog post(和谷歌翻译)和互联网上极少数例子的帮助下,我已经使用WebRTCUnity Plugin在Unity上做了很多工作。

但现在我被困住了。 mhama 的伟大 Unity 示例项目遗憾的是没有示例说明如何将我从本机代码获得的数据转换为可在 Unity 中用作音频数据的内容。


我从回调中得到的信息是这样的

(IntPtr data, int bitsPerSample, int sampleRate, int numberOfChannels, int numberOfFrames)

本机代码中的数据声明为

const void* audio_data

我知道要创建 Unity 可以用来播放声音的音频剪辑,我需要一个 float 数组,其中包含来自 -1 to 1 的样本值。我如何从 IntPtr 数据和所有额外信息到 float 数组,我不知道该怎么做。

Here's the sample I'm using as a base

【问题讨论】:

    标签: c# pointers unity3d audio webrtc


    【解决方案1】:

    我不确定您是否可以在没有不安全代码的情况下执行此操作。您需要确保您的项目允许使用不安全代码。

    // allocate the float arrays for the output. 
    // numberOfChannels x numberOfFrames
    float[][] output = new float[numberOfChannels][];
    for (int ch = 0 ; ch < numberOfChannels; ++ch)
        output[ch] = new float[numberOfFrames];
    
    // scaling factor for converting signed PCM into float (-1.0 to 1.0)
    const double scaleIntToFloat = 1.0/0x7fffffff;
    
    unsafe 
    { 
        // obtain a pointer to the raw PCM audio data.
        byte *ptr = (byte *)data.ToPointer();
    
        for (int frame = 0 ; frame < numberOfFrames; ++frame)
        {
            for (int ch = 0 ; ch < numberOfChannels; ++ch)
            {
                switch (bitsPerSample)
                {
                    case 32:
                       // shift 4 bytes into the integer value
                       int intValue = *ptr++ << 24 & *ptr++ << 16 &
                                      *ptr++ << 8 & *ptr++;
                       // scale the int to float and store.
                       output[ch][frame] = scaleIntToFloat * intValue;
                       break;
                    case 16: 
                       // shift 2 bytes into the integer value. Note:
                       // shifting into the upper 16 bits to simplify things,
                       // e.g. multiply by the same scaling factor.
                       int intValue = *ptr++ << 24 & *ptr++ << 16; 
                       output[ch][frame] = scaleIntToFloat * intValue;
                       break;
                    case 24:
                       ...
                    case 8:
                       // not 8-bit is typically unsigned. Google it if
                       // you need to.
                }
            }
        }
    }
    

    您可以通过在此网站上搜索 PCM 到浮动的转换来找到其他转换。此外,根据您的情况,您可能需要不同的字节序。如果是这样,请以不同的字节顺序转移到intValue。

    【讨论】:

    • 它工作得非常好(除了音频似乎低于应有的水平,但我认为我可以使用它)。非常感谢。
    猜你喜欢
    • 2015-09-29
    • 2022-10-25
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    相关资源
    最近更新 更多