2014-10-16 87 views
2

我目前正在开发一个VOIP应用程序。为了实现这一点,我使用PortAudio库来检索和播放声音,并使用Opus库对声音数据包进行编码和解码。Portaudio + Opus:糟糕的音质

现在,我成功设法使用了PortAudio。我的程序简单地做:

  1. 从麦克风
  2. 获取声音播放声音

的音质绝对好。

我现在试图对声音数据包进行编码和解码。我已经编码的EncodeManagerClass做到这一点,我的程序现在做的事:

  1. 从麦克风
  2. 编码声音
  3. 解码它
  4. 回放

获取声音,但现在,音质是绝对可怕的(在VOIP应用中这显然有问题)。

这里是我EncodeManager类:

class EncodeManager { 

    // ctor - dtor 
    public: 
     EncodeManager(void); 
     ~EncodeManager(void); 

    // coplien form 
    private: 
     EncodeManager(const EncodeManager &) {} 
     const EncodeManager &operator=(const EncodeManager &) { return *this; } 

    // encode - decode 
    public: 
     Sound::Encoded encode(const Sound::Decoded &sound); 
     Sound::Decoded decode(const Sound::Encoded &sound); 

    // attributes 
    private: 
     OpusEncoder *mEncoder; 
     OpusDecoder *mDecoder; 

}; 

这里是源文件:

EncodeManager::EncodeManager(void) { 
    int error; 

    mEncoder = opus_encoder_create(Sound::SAMPLE_RATE, Sound::NB_CHANNELS, OPUS_APPLICATION_VOIP, &error); 
    if (error != OPUS_OK) 
     throw new SoundException("fail opus_encoder_create"); 

    mDecoder = opus_decoder_create(Sound::SAMPLE_RATE, Sound::NB_CHANNELS, &error); 
    if (error != OPUS_OK) 
     throw new SoundException("fail opus_decoder_create"); 
} 

EncodeManager::~EncodeManager(void) { 
    if (mEncoder) 
     opus_encoder_destroy(mEncoder); 

    if (mDecoder) 
     opus_decoder_destroy(mDecoder); 
} 

Sound::Encoded EncodeManager::encode(const Sound::Decoded &sound) { 
    Sound::Encoded encoded; 

    encoded.buffer = new unsigned char[sound.size]; 
    encoded.size = opus_encode_float(mEncoder, sound.buffer, Sound::FRAMES_PER_BUFFER, encoded.buffer, sound.size); 

    if (encoded.size < 0) 
     throw new SoundException("fail opus_encode_float"); 

    return encoded; 
} 

Sound::Decoded EncodeManager::decode(const Sound::Encoded &sound) { 
    Sound::Decoded decoded; 

    decoded.buffer = new float[Sound::FRAMES_PER_BUFFER * Sound::NB_CHANNELS]; 
    decoded.size = opus_decode_float(mDecoder, sound.buffer, sound.size, decoded.buffer, Sound::FRAMES_PER_BUFFER, 0); 

    if (decoded.size < 0) 
     throw new SoundException("fail opus_decode_float"); 

    return decoded; 
} 

这里是我的主:

int main(void) { 
    SoundInputDevice input; 
    SoundOutputDevice output; 
    EncodeManager encodeManager; 

    input.startStream(); 
    output.startStream(); 

    while (true) { 
     Sound::Decoded *sound; 

     input >> sound; 
     if (sound) { 
      Sound::Encoded encodedSound = encodeManager.encode(*sound); 
      Sound::Decoded decodedSound = encodeManager.decode(encodedSound); 
      output << &decodedSound; 
     } 
    } 

    return 0; 
} 

附加信息:

const int SAMPLE_RATE = 48000; 
const int NB_CHANNELS = 2; 
const int FRAMES_PER_BUFFER = 480; 

我试图配置oppus编码器opus_encode_ctl(带宽,比特率,VBR),但它根本不起作用:音质仍然很糟糕。

即使我改变SAMPLE_RATE或FRAME_PER_BUFFER,声音质量没有改善......

我错过了有关PortAudio /作品的东西吗?

回答

3

我终于找到了解决办法。

的问题并非来自主业,但是从主...

if (sound) { 
    Sound::Encoded encodedSound = encodeManager.encode(*sound); 
    Sound::Decoded decodedSound = encodeManager.decode(encodedSound); 
    output << &decodedSound; 
} 

在这里,我通过一个局部变量,以我的输出流。但输出流是异步工作的:所以我的变量在声音打包之前被破坏。

使用指针是解决问题的最简单方法。我personnaly决定重新创建一点我的代码。