将UInt32(音频帧)分割成两个SInt16(左和右)? [英] Split UInt32 (audio frame) into two SInt16s (left and right)?

查看:1206
本文介绍了将UInt32(音频帧)分割成两个SInt16(左和右)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总计noob到比Java更低的任何水平,潜入到iPhone音频,并从所有的投射/指针/原始内存访问。



使用从磁盘读取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;

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



我创建一个数组:

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

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

  UInt32 newFrame32 = newFrameInMemory 

但是如果我做这个丑陋的 - 把数组转换为指针,然后解引用指针,它的工作。

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

有更漂亮的方法?

解决方案

很容易:

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

除非iPhone是little-endian,否则你必须反转 right left



可以看作是两个连续的 short ,你只需要得到它的地址,然后做完全一样,两个


Total noob to anything lower-level than Java, diving into iPhone audio, and realing from all of the casting/pointers/raw memory access.

I'm working with some example code wich reads a WAV file from disc and returns stereo samples as single UInt32 values. If I understand correctly, this is just a convenient way to return the 32 bits of memory required to create two 16 bit samples. Eventually this data gets written to a buffer, and an audio unit picks it up down the road. Even though the data is written in UInt32-sized chunks, it eventually is interpreted as pairs of 16-bit samples.

What I need help with is splitting these UInt32 frames into left and right samples. I'm assuming I'll want to convert each UInt32 into an SInt16, since an audio sample is a signed value. It seems to me that for efficiency's sake, I ought to be able to simply point to the same blocks in memory, and avoid any copying.

So, in pseudo-code, it would be something like this:

UInt32 myStereoFrame = getFramefromFilePlayer;

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

Can anyone help me turn my pseudo into real code?

Edit:

Much thanks to zneak for this answer, which works great:

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

Now, to reassemble my SInt16s into a UInt32 (assuming I don't want to just use my original variable, myStereoFrame), I'll need to do more or less the same in reverse: line up my two SInt16s in contiguous memory slots and then cast that memory to a UInt32.

So I make an array:

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

And then copy the entire length of that array into a UInt32

UInt32 newFrame32 = newFrameInMemory

That doesn't work though, but if I do this bit of ugliness -- cast the array to a pointer, then dereference the pointer, it does work.

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

Is there a prettier way to do this?

解决方案

It's quite easy:

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

Unless the iPhone is little-endian, in which case you'll have to invert right and left.

Since an int can be seen as two contiguous shorts, you just have to get the address to it, and then do exactly as if it was, indeed, two shorts.

这篇关于将UInt32(音频帧)分割成两个SInt16(左和右)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆