2012-07-16 102 views
0

我正在研究一個需要使用remoteIO音頻單元作爲輸入/輸出對Speex音頻進行編碼和解碼的iOS項目。iOS音頻單元+ Speex編碼失真

我遇到的問題是雖然Speex不會打印任何錯誤,但我得到的音頻有點可識別爲聲音,但非常失真,有點聽起來像增益只是以機器人的方式打開。

這裏是編碼和解碼功能(輸入到編碼是從音頻單元320個字節帶符號的整數的渲染功能,輸入到解碼是62個字節的壓縮的數據):

#define AUDIO_QUALITY 10 
#define FRAME_SIZE 160 
#define COMP_FRAME_SIZE 62 

char *encodeSpeexWithBuffer(spx_int16_t *buffer, int *insize) { 
    SpeexBits bits; 
    void *enc_state; 



    char *outputBuffer = (char *)malloc(200); 

    speex_bits_init(&bits); 
    enc_state = speex_encoder_init(&speex_nb_mode); 

    int quality = AUDIO_QUALITY; 

    speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &quality); 


    speex_bits_reset(&bits); 

    speex_encode_int(enc_state, buffer, &bits); 



    *insize = speex_bits_write(&bits, outputBuffer, 200); 


    speex_bits_destroy(&bits); 
    speex_encoder_destroy(enc_state); 


    return outputBuffer; 
} 

short *decodeSpeexWithBuffer(char *buffer) { 
    SpeexBits bits; 
    void *dec_state; 

    speex_bits_init(&bits); 

    dec_state = speex_decoder_init(&speex_nb_mode); 

    short *outTemp = (short *)malloc(FRAME_SIZE * 2); 

    speex_bits_read_from(&bits, buffer, COMP_FRAME_SIZE); 
    speex_decode_int(dec_state, &bits, outTemp); 

    speex_decoder_destroy(dec_state); 
    speex_bits_destroy(&bits); 


    return outTemp; 
} 

和音頻單元格式:

// Describe format 
audioFormat.mSampleRate   = 8000.00; 
audioFormat.mFormatID   = kAudioFormatLinearPCM; 
audioFormat.mFormatFlags  = kAudioFormatFlagIsSignedInteger | 
kAudioFormatFlagsNativeEndian | 
kAudioFormatFlagIsPacked; 
audioFormat.mFramesPerPacket = 1; 
audioFormat.mChannelsPerFrame = 1; 
audioFormat.mBitsPerChannel  = 16; 
audioFormat.mBytesPerPacket  = 2; 
audioFormat.mBytesPerFrame  = 2; 

沒有錯誤報道的任何地方。我已經證實,音頻單元爲處理在8000

+0

你好我AudioUnit.i工作不能從Audiounit得到像(160字節)所需的字節,它總是給2的力量。是否有可能從Audiounit錄音回調得到320字節?如果是的話請給點意見 – 2012-07-27 06:50:28

+0

這是正確的。音頻單元只給你2個樣本的權力。您必須緩衝音頻數據,然後以320字節塊的形式從緩衝區提取數據(如果可用) – 2012-08-11 06:31:41

回答

0

的採樣率幾d後對這個瘋狂的我終於明白了。 Speex的竅門是您必須初始化SpeexBit和編碼器void *,並在整個會話中使用它們。因爲我正在爲它的每一個編碼重新創建它們,導致了奇怪的聲音效果。

一旦我感動:

speex_bits_init(&bits); 
enc_state = speex_encoder_init(&speex_nb_mode); 

跳出while循環的一切偉大的工作。