iOS版的Core Audio:kAudioFormatFlagsCanonical和kAudioF

2019-09-02 11:20发布

我需要这个格式之间进行转换:

        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;

而这种格式

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;

一音频的范围内作出回叫,其中有以下代码和缓冲器[]是在第二格式和阵列[]需要第一格式。

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

我知道你可以使用苹果的转换器单元,但我不能在我的情况下使用苹果的转换音频单元(有一个原因)。

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

我怎样才能转换缓冲液[](在第一格式包含数据)(在第二格式包含数据),以阵列[],反之亦然?

谢谢。

Answer 1:

好吧,如果你是指在文档kAudioFormatFlagsAudioUnitCanonical ,你看:

kAudioFormatFlagsAudioUnitCanonical The flags for the canonical audio unit sample 
type. This matches AudioUnitSampleType.

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.

因此,在样品buffer[]数组是8.24位定点格式。 这是什么意思?

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

在IOS音频单元,有一个微小的差别-在[-1这种浮点数(通常)的范围内,1)( [-1.000000000000,0.999969482421875]确切地说 )。 在该范围之外的值转换为16位PCM时被简单地削波。 您可以验证的前8位是(在-1二进制补码)为0x00或0xFF的大多数组成部分。

该表示转换为16位数字,使用:

SIGN((SInt8)(val >> 24)) * 32768 * (val & 0xFFFFFF)/(float)(1<<24)

这就是:提取从8 MSB的符号,由24位的整数(2 ^ 24)的范围从24 LSB和除法提取分数值导致0和1之间的浮动,最后由32768乘以这个得到的值在期望的范围。

我没有尝试这样做我自己,但 - 你可能要在这里和那里调整几件事情。



Answer 2:

也许一晚的答案,但由于移位方法并没有为我工作,出于某种原因,我发现这种替代它工作很好,在audiograph https://github.com/tkzic/audiograph

我适应了一下方法从那里,瞧:

void ConvertInputToInt16(AudioStreamBasicDescription inFormat, void *buf, void *outputBuf, size_t capacity)
 {  
   AudioConverterRef converter;
    OSStatus err;

    size_t bytesPerSample = sizeof(SInt16);
    AudioStreamBasicDescription outFormat = {0};
    outFormat.mFormatID = kAudioFormatLinearPCM;
    outFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    outFormat.mBitsPerChannel = 8 * bytesPerSample;
    outFormat.mFramesPerPacket = 1;
    outFormat.mChannelsPerFrame = 1;
    outFormat.mBytesPerPacket = bytesPerSample * outFormat.mFramesPerPacket;
    outFormat.mBytesPerFrame = bytesPerSample * outFormat.mChannelsPerFrame;
    outFormat.mSampleRate = inFormat.mSampleRate;

    NSLog(@"description for in format: %@", descriptionForAudioFormat(inFormat));
    NSLog(@"description for out format: %@", descriptionForAudioFormat(outFormat));

    UInt32 inSize = capacity*sizeof(SInt32);
    UInt32 outSize = capacity*sizeof(SInt16);

    // this is the famed audio converter

    err = AudioConverterNew(&inFormat, &outFormat, &converter);
    if(noErr != err) {
        NSLog(@"error in audioConverterNew: %d", (int)err);
    }


    err = AudioConverterConvertBuffer(converter, inSize, buf, &outSize, outputBuf);
    if(noErr != err) {
        NSLog(@"error in audioConverterConvertBuffer: %d", err);
    }

}


文章来源: iOS Core Audio : Converting between kAudioFormatFlagsCanonical and kAudioFormatFlagsAudioUnitCanonical