将32位音频单元Canonical立体声PCM采样编码为mp3并保持跛脚

时间:2014-05-23 13:53:42

标签: ios audio encoding audiotoolbox lame

我正在使用Mickey Blue microphone addon直接将来自iOS设备上的数字线路的32位立体声样本转换为带有lame的mp3。

问题是跛脚似乎只接受16位样本。试图直接转换样本只会让我产生很多噪音,而且没有可识别的音频。 我用来在iOS上录制音频的设置如下

AudioStreamBasicDescription stereoStreamFormat;
stereoStreamFormat.mSampleRate          = 44100.00;
stereoStreamFormat.mFormatID            = kAudioFormatLinearPCM;
stereoStreamFormat.mFormatFlags         = kAudioFormatFlagsAudioUnitCanonical;
stereoStreamFormat.mBytesPerPacket      = 4;
stereoStreamFormat.mBytesPerFrame       = 4;
stereoStreamFormat.mFramesPerPacket     = 1;
stereoStreamFormat.mChannelsPerFrame    = 2;
stereoStreamFormat.mBitsPerChannel      = 32;//changing this to 16bit does not work

然后,我将来自2个单独缓冲区的样本转换为lame:

-(void) encodeMicrophoneWithLeft :(NSData*) left andRight : (NSData *) right
{
    void *mp3 = malloc(MP3_SIZE_MIC);
    int write = lame_encode_buffer(microphoneLame, left.bytes, right.bytes, left.length/2, mp3, MP3_SIZE_MIC);
    [self.microphoneBuffer appendBytes:mp3 length:write];
}

使用以下设置:

lame_set_brate(microphoneLame, 128);// current streaming speed kbps
lame_set_in_samplerate(microphoneLame, 44100);
lame_set_VBR(microphoneLame, vbr_off);//set variable bitrate off
lame_set_num_channels(microphoneLame,2);

有没有什么方法可以将32位样本转换为16位或使用32位样本进行蹩脚的工作?对于立体声,录音机不能以32bit以外的设置工作,但是如果还有另一种用16bit初始化的方式,对我来说也是一种解决方案。

2 个答案:

答案 0 :(得分:0)

删除16位不起作用,因为kAudioFormatFlagsAudioUnitCanonical使你的流浮点数为:AudioUnit流是32位浮点数。

不要将kAudioFormatFlagsAudioUnitCanonical用于格式标记。阅读标题,看看LAME需要什么。 16 kAudioFormatFlagsAreAllClearmBitsPerChannel应该可以工作(也可以比照所有每帧字节数等)。这将给你16位小端整数样本。

答案 1 :(得分:0)

似乎kAudioFormatFlagsAudioUnitCanonical确实不仅仅是32位,而是以浮点表示法存储的固定点24位样本。可以丢弃最高有效7位,只有前8个最高有效位的最低有效位用于对该值进行签名。

       sign    actual sample data
      /       /
|--8--|------24------|
     |----16----| <- part you need

这意味着我可以将样本9向右移位,然后直接将它们转换为短路,留下16位签名样本。

像这样:

NSData *left =[[NSData alloc]initWithBytes:tempBufferLeft.mData length:tempBufferLeft.mDataByteSize ];
NSData *right =[[NSData alloc]initWithBytes:tempBufferRight.mData length:tempBufferRight.mDataByteSize ];

convertedArrayLeft = [[NSMutableData alloc]init];
convertedArrayRight = [[NSMutableData alloc]init];
for (int i = 0; i < left.length; i+=4)//steps of 4 bytes
{
    int tmpValueL, tmpValueR;
    [left getBytes:&tmpValueL range:NSMakeRange(i, 4)];//extract float samples into int for easier manipulation
    [right getBytes:&tmpValueR range:NSMakeRange(i, 4)];

    short endValueL = tmpValueL>>9, endValueR = tmpValueR>>9;//bitshift 9 to the right and save as short to lose most significant 16 bits that are now useless

    [convertedArrayLeft appendBytes:&endValueL length:sizeof(short)];
    [convertedArrayRight appendBytes:&endValueR length:sizeof(short)];
}

我无法找出为什么它不接受立体声录音中的其他格式,但这也有点开销。