我需要这个格式之间进行转换:
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)以下标志。
我怎样才能转换缓冲液[](在第一格式包含数据)(在第二格式包含数据),以阵列[],反之亦然?
谢谢。
好吧,如果你是指在文档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乘以这个得到的值在期望的范围。
我没有尝试这样做我自己,但 - 你可能要在这里和那里调整几件事情。
也许一晚的答案,但由于移位方法并没有为我工作,出于某种原因,我发现这种替代它工作很好,在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