【问题标题】:Split UInt32 (audio frame) into two SInt16s (left and right)?将 UInt32(音频帧)拆分为两个 SInt16(左右)?
【发布时间】:2010-03-08 22:28:46
【问题描述】:

对任何比 Java 更低级别的东西都一无所知,深入研究 iPhone 音频,并从所有强制转换/指针/原始内存访问中实现。

我正在使用some example code,它从光盘读取 WAV 文件并将立体声样本作为单个 UInt32 值返回。如果我理解正确,这只是返回创建两个 16 位样本所需的 32 位内存的便捷方式。最终,这些数据被写入缓冲区,然后一个音频单元将其拾取。即使数据是以 UInt32 大小的块写入的,它最终也会被解释为 16 位样本对。

我需要帮助的是将这些 UInt32 帧拆分为左右样本。我假设我想将每个 UInt32 转换为 SInt16,因为音频样本是有符号值。在我看来,为了效率,我应该能够简单地指向内存中的相同块,并避免任何复制。

所以,在伪代码中,它会是这样的:

UInt32 myStereoFrame = getFramefromFilePlayer;

SInt16* leftChannel = getFirst16Bits(myStereoFrame);
SInt16* rightChannel = getSecond16Bits(myStereoFrame);

谁能帮我把我的伪代码变成真正的代码?

编辑:

非常感谢 zneak 的回答,效果很好:

SInt16* left = (SInt16*)&myUInt32Chunk;
SInt16* right = left + 1;

现在,要将我的 SInt16 重新组装成 UInt32(假设我不想只使用我的原始变量 myStereoFrame),我需要或多或少地反向执行相同的操作:将我的两个 SInt16 连续排列内存插槽,然后将该内存转换为 UInt32。

所以我做了一个数组:

SInt16 newFrameInMemory[2] = {*left, *right}

然后将该数组的整个长度复制到 UInt32 中

UInt32 newFrame32 = newFrameInMemory

虽然这行不通,但如果我做这点丑陋的事情——将数组转换为指针,然后取消引用指针,它确实有效。

UInt32 newFrame32 = *((UInt32*)&newFrameInMemory)

有没有更漂亮的方法来做到这一点?

【问题讨论】:

    标签: iphone pointers audio casting


    【解决方案1】:

    很简单:

    SInt16* left = (SInt16*)&myUInt32Chunk;
    SInt16* right = left + 1;
    

    除非 iPhone 是 little-endian,在这种情况下,您必须反转 rightleft

    由于int 可以被视为两个连续的shorts,因此您只需获取它的地址,然后就好像它确实是两个shorts 一样。

    【讨论】:

      【解决方案2】:

      iPhone 是小端 :-)

      【讨论】:

        猜你喜欢
        • 2011-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-09
        • 1970-01-01
        • 2013-03-24
        相关资源
        最近更新 更多