【发布时间】: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