如何手动将8.24位解交织的lpcm转换为16位lpcm?

Ale*_*xey 6 core-audio

我有一个数据块(void*),它是2 ch,44100 Hz,'lpcm'8.24位little-endian有符号整数,deinterleaved.我需要将该块记录为2 ch,44100 Hz,'lpcm'16位little-endian有符号整数.

我如何转换数据?我可以想象我需要做这样的事情:

uint dataByteSize = sizeof(UInt32) * samplesCount;
UInt32* source = ...;
UInt32* dest = (UInt32*)malloc(dataByteSize);
for (int i = 0; i < samplesCount; ++i) {
    UInt32 sourceSample = source[i];
    UInt32 destSample = sourceSample>>24;
    dest[i] = destSample;
}
Run Code Online (Sandbox Code Playgroud)

但是如何将deinterleaved转换为interleaved?

Ale*_*xey 11

好吧,我花了一些时间调查这个问题,并意识到这个问题包含的信息太少而无法回答=)所以继续这样的交易:

首先,关于非交错:我最初认为它看起来像这样:l1 l2 l3 l4 ... ln r1 r2 r3 r4 ...但事实证明,在我的数据中,右通道刚刚丢失.事实证明,它不是一个非交错数据,它只是一个普通的单声道数据.是的,如果数据实际上是非交错的,它应该总是多个缓冲区.如果它是交错的,它应该是l1 r1 l2 r2 l3 r3 l4 r4 ......

其次,关于实际转型:这一切都取决于样品的范围.在我的情况下(在任何情况下,如果我是正确的,涉及核心音频)定点8.24值应该在(-1,1)之间,而16位有符号值应该在(-32768,32767)之间.因此,8.24值将始终将其前8位设置为0(如果是正数)或1(如果它是负数).应删除前8位(保留符号ofc).你也可以根据需要删除任意数量的尾随位 - 它只会降低声音的质量,但它不会破坏声音.在转换为16位有符号格式的情况下,位8-22(即15位)实际上将包含我们需要用于SInt16的数据.位7可用作符号位.因此,要将8.24转换为SInt16,您只需要向右移9位(9因为您需要保留符号)并转换为SInt16

11111111 10110110 11101110 10000011 - > 11111111 11111111(11011011 01110111)
00000000 01101111 00000000 11000001 - > 00000000 00000000(00110111 10000000)

而已.没有什么比通过数组迭代和正确移位.希望能节省几个小时.