iOS Core Audio:在kAudioFormatFlagsCanonical和kAudioFormatFlagsAudioUnitCanonical之间转换

lpp*_*ier 3 macos core-audio ios

我需要在这种格式之间转换:

        format.mSampleRate  = 44100.0; 
        format.mFormatID = kAudioFormatLinearPCM;
        format.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved;
        format.mBytesPerPacket = sizeof(AudioUnitSampleType);
        format.mFramesPerPacket = 1;
        format.mBytesPerFrame = sizeof(AudioUnitSampleType);
        format.mChannelsPerFrame = 2 ;
        format.mBitsPerChannel = sizeof(AudioUnitSampleType)*8;
Run Code Online (Sandbox Code Playgroud)

和这种格式

format.mSampleRate  = 44100.0; 
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
format.mBytesPerPacket = sizeof(AudioUnitSampleType);
format.mFramesPerPacket = 1;
format.mBytesPerFrame = sizeof(AudioUnitSampleType);
format.mChannelsPerFrame = 2; 
format.mBitsPerChannel = sizeof(AudioUnitSampleType)*8;
Run Code Online (Sandbox Code Playgroud)

在音频渲染回调的范围内,其中有以下代码,buffer []是第二种格式,array []需要第一种格式.

for (k = 0; k < channels; k++){
    buffer = (AudioUnitSampleType *) ioData->mBuffers[k].mData;
    for(j=0; j < samples; j++){
        array[j] = buffer[j];
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道你可以使用Apple转换器单元,但我不能在我的情况下使用Apple Converter音频单元(这是有原因的).

基本上2格式之间的唯一区别是format.mFormatFlags的以下标志(kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift).

如何将buffer [](包含第二种格式的数据)转换为array [](包含第一种格式的数据),反之亦然?

谢谢.

Mar*_*0ux 6

好吧,如果您参考文档kAudioFormatFlagsAudioUnitCanonical,您会看到:

kAudioFormatFlagsAudioUnitCanonical The flags for the canonical audio unit sample 
type. This matches AudioUnitSampleType.
Run Code Online (Sandbox Code Playgroud)

The canonical audio sample type for audio units and other audio processing in 
iPhone OS is noninterleaved linear PCM with 8.24-bit fixed-point samples.
Run Code Online (Sandbox Code Playgroud)

因此,buffer[]数组中的样本采用8.24位定点格式.这是什么意思?

8.24位定点格式用于表示具有固定精度的浮点数 - 一个32位整数,其中前8位代表整个部分,后24位代表小数部分(小数后面的数字).(进一步阅读)

在iOS音频单元中,有一个小的差异 - 这个浮点数(通常)的范围是[-1,1)(确切地说是[-1.000000000000,+ 0.999969482421875]).转换为16位PCM时,只会剪切此范围之外的值.在大多数情况下,您可以验证前8位是0x00还是0xff(在2的补码中为-1).

要将此表示形式转换为16位数字,请使用以下命令:

SIGN((SInt8)(val >> 24)) * 32768 * (val & 0xFFFFFF)/(float)(1<<24)
Run Code Online (Sandbox Code Playgroud)

即:从8 MSB中提取符号,从24 LSB中提取小数值并除以24位整数(2 ^ 24)的范围,得到0到1之间的浮点数,最后将其乘以32768得到一个值在期望的范围内.

我自己也没试过 - 你可能需要在这里和那里调整一些东西.