iOS音频单元+Speex编码失真



我正在进行一个iOS项目,该项目需要使用远程IO音频单元作为输入/输出对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 的采样率进行处理

在为此疯狂了几天后,我终于明白了。Speex的诀窍是,您必须初始化SpeexBit和编码器void*,并在整个会话中使用它们。因为我为每一段编码都重新创建了它们,所以会产生奇怪的结果。

一旦我搬家:

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

突然间,一切都很顺利。

最新更新