带Opus lib的Qt音频输入/输出

问题描述

我想制作低延迟的流音频。为此,我使用带有opus API的QAudioInput和QAudioOutput作为压缩库。现在,我通过写入输出驱动程序进行简单测试。

问题是我听到杂音,不知道问题出在哪里。我对Opus使用了很多测试。

我受到这个项目的启发:https://github.com/antonypro/AudioStreaming

main.cpp

int main(int argc,char *argv[])
{
QCoreApplication a(argc,argv);

qiodevice* device { nullptr };
QBuffer buffer;

EncodeManager* encode = new EncodeManager(&a);

QAudioFormat format;
format.setSampleRate(48000);
format.setChannelCount(2);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);

QAudioDeviceInfo infoIn(QAudioDeviceInfo::defaultInputDevice());
qDebug() << infoIn.deviceName();
if (!infoIn.isFormatSupported(format)) {
    qWarning() << "Raw audio format not supported by backend,cannot play audio.";
    a.quit();
}

QAudioDeviceInfo infoOut(QAudioDeviceInfo::defaultOutputDevice());
qDebug() << infoOut.deviceName();
if (!infoOut.isFormatSupported(format)) {
    qWarning() << "Raw audio format not supported by backend,cannot play audio.";
    a.quit();
}

QAudioInput* audio_in = new QAudioInput(infoIn,format,&a);
QAudioOutput* audio_out = new QAudioOutput(infoOut,&a);

audio_in->setBufferSize(3000);
audio_out->setBufferSize(3000);

audio_in->setNotifyInterval(40);
audio_out->setNotifyInterval(40);

audio_in->start(&buffer);
device = audio_out->start();

device->open(qiodevice::ReadWrite);
buffer.open(qiodevice::writeonly);

auto consumAudio = [&](){
    auto len = buffer.buffer().size();

    qInfo()<< "Len: " << len;

    qmutex mutex;
    mutex.lock();

    if(len > 0) {
        QByteArray data_encoded = encode->encodeAudio(buffer.buffer());
        QByteArray  data_decoded =  encode->decodeAudio(data_encoded);

        device->write(data_decoded);

        buffer.buffer().clear();
        buffer.reset();
    }

    mutex.unlock();
};

QObject::connect(audio_in,&QAudioInput::notify,[&]() {consumAudio();});

return a.exec();
}

EncodeManager.h

class EncodeManager : public QObject
{
Q_OBJECT

public:
explicit EncodeManager(QObject *parent = nullptr);
~EncodeManager();

QByteArray encodeAudio(const QByteArray &pcm);
QByteArray decodeAudio(const QByteArray &data);

private:
int const m_buffer_size {480};
int const m_max_packet {1276};
int const m_channel {2};

OpusEncoder* m_encoder = nullptr;
OpusDecoder* m_decoder = nullptr;
};

EncodeManager.cpp

EncodeManager::EncodeManager(QObject *parent) : QObject(parent)
{
int error_encode {0};
int error_decode {0};

m_encoder = opus_encoder_create(48000,m_channel,OPUS_APPLICATION_AUdio,&error_encode);
m_decoder = opus_decoder_create(48000,&error_decode);
}

QByteArray EncodeManager::encodeAudio(const QByteArray &pcm)
{
QByteArray compressed_frame { m_max_packet,char(0) };

int compressed_size = opus_encode(m_encoder,reinterpret_cast<const opus_int16 *>(pcm.constData()),m_buffer_size,reinterpret_cast<unsigned char*> (compressed_frame.data()),m_max_packet);

compressed_frame.resize(compressed_size);

return compressed_frame;
}

QByteArray EncodeManager::decodeAudio(const QByteArray &data)
{
QByteArray decompressed_frame { int(sizeof(opus_int16)) * m_channel * m_buffer_size,char(0) };

opus_int32  decompressed_size = opus_decode(m_decoder,reinterpret_cast<const unsigned char*> (data.constData()),reinterpret_cast<opus_int16 *>(decompressed_frame.data()),m_max_packet,0);

int size = int(sizeof(opus_int16)) * m_channel * decompressed_size;

decompressed_frame.resize(size);

return decompressed_frame;
}

谢谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)