【问题标题】:iOS Audio Unit + Speex encoding is distortediOS Audio Unit + Speex 编码失真
【发布时间】:2012-07-16 07:38:06
【问题描述】:

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

【问题讨论】:

  • :嗨,我正在研究 AudioUnit。我无法从 Audiounit 获得所需的字节,如(160 字节),它总是给出 2 的幂。是否可以从 Audiounit 录制回调中获得 320 字节?如果所以请给出一些想法
  • 没错。音频单元只为您提供 2 个样本的功率。您必须缓冲音频数据,然后在可用时以 320 字节块的形式从缓冲区中提取数据

标签: iphone ios core-audio audiounit speex


【解决方案1】:

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

我搬家后:

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

在 while 循环之外一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多