首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Port音频+ Opus:可怕的声音质量

Port音频+ Opus:可怕的声音质量
EN

Stack Overflow用户
提问于 2014-10-16 10:14:24
回答 1查看 2.2K关注 0票数 4

我目前正在开发一个VOIP应用程序。为此,我使用PortAudio库检索和播放声音,使用Opus库对声音数据包进行编码和解码。

目前,我成功地使用了PortAudio。我的程序很简单:

  1. 从麦克风中获得声音
  2. 回放声音

音质绝对好。

我现在正试图对声音包进行编码和解码。我已经编写了一个EncodeManagerClass来完成它,我的程序现在这样做了:

  1. 从麦克风中获得声音
  2. 编码声音
  3. 破译
  4. 回放

但是现在,声音质量是绝对可怕的(而且在一个VOIP应用程序中显然是有问题的)。

这是我的EncodeManager课程:

代码语言:javascript
复制
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;

};

以下是源文件:

代码语言:javascript
复制
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;
}

这是我的主要:

代码语言:javascript
复制
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;
}

补充资料:

代码语言:javascript
复制
const int   SAMPLE_RATE = 48000;
const int   NB_CHANNELS = 2;
const int   FRAMES_PER_BUFFER = 480;

我试着用opus_encode_ctl (带宽、比特率、VBR)来配置opus编码器,但是它根本不起作用:声音质量仍然很差。

即使我改变了SAMPLE_RATE或FRAME_PER_BUFFER,音质也不会提高.

我是不是错过了一些关于波特奥/奥珀斯的东西?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-19 14:21:32

我终于找到解决办法了。

问题不是来自Opus,而是来自主要的..。

代码语言:javascript
复制
if (sound) {
  Sound::Encoded encodedSound = encodeManager.encode(*sound);
  Sound::Decoded decodedSound = encodeManager.decode(encodedSound);
  output << &decodedSound;
 }

在这里,我向输出流传递一个局部变量。但是输出流异步工作:所以在播放声音打包之前,我的变量就被销毁了。

使用指针是解决问题的最简单方法。我个人决定重新整理一下我的代码。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26401807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档