VoiceEngine中与录音和播放相关的头文件有五个,如下表所示:
头文件 | 包含的类 |
说明 |
voe_base.h |
VoiceEngineObserver VoiceEngine VoEBase |
1.默认使用G.711通过RTP进行全双工的VoIP会话 2.初始化和终止 3.通过文件和回调函数跟踪信息 4.多通道支持(比如混合,发送到多个目的端) 5.如果想支持G.711外的编码,需要VoECodec |
voe_errors.h |
无 |
一些VoiceEngine相关错误的定义 |
voe_file.h |
VoEFile |
1.音频播放 2.音频录制 3.音频转换 |
voe_hardware.h |
VoEHardware |
1.管理音频设备 2.获取设备信息 3.采样率设置 |
voe_volume_control.h |
VoEVolumeControl |
1.扬声器音量控制 2.麦克风音量控制 3.非线性语音电平控制 4.静音 5.音量放大 |
WebRTC版本:2016.6.22,详见 WebRTC学习之二:编译
Qt版本:Qt5.7.0 VS2015
需要安装Microsoft DirectX SDK (June 2010),否则链接的时候会报:
LNK2019:无法解析的外部符号_MoInitMediaType@8,该符号在......
LNK2019:无法解析的外部符号_MoFreeMediaType@8,该符号在......
LNK2019:无法解析的外部符号_IID_IMediaBuffer
LNK2019:无法解析的外部符号_IID_IMediaObject
LNK2019:无法解析的外部符号_CLSID_CWMAudioAEC
如下图所示:
二.实现
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include "myobserver.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_errors.h"
#include "webrtc/voice_engine/include/voe_file.h"
#include "webrtc/voice_engine/include/voe_hardware.h"
#include "webrtc/voice_engine/include/voe_volume_control.h"
using namespace webrtc;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
void creatVoiceEngine();
int initialVoiceEngine();
int setDevice();
void setChannel();
int getMicrophoneVolumeValue();
int getSpeakerVolumeValue();
int unInitialVoiceEngine();
private:
Ui::MainWindow *ui;
MyObserver myObserver;
int error;
int audioChannel;
VoiceEngine* ptrVoEngine;
VoEBase* ptrVoEBase;
VoEVolumeControl* ptrVoEVolumeControl;
VoEFile* ptrVoEFile;
VoEHardware* ptrVoEHardware;
private slots:
void on_pushButtonRecording_clicked();
void on_pushButtonPlayout_clicked();
void slotSetMicrophoneVolumeValue(int value);
void slotSetSpeakerVolumeValue(int value);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
error(0),
audioChannel(0),
ptrVoEngine(NULL),
ptrVoEBase(NULL),
ptrVoEVolumeControl(NULL),
ptrVoEFile(NULL),
ptrVoEHardware(NULL)
{
ui->setupUi(this);
creatVoiceEngine();
initialVoiceEngine();
setDevice();
setChannel();
connect(ui->horizontalSliderMicrophoneVolume,SIGNAL(valueChanged(int)),this,SLOT(slotSetMicrophoneVolumeValue(int)));
connect(ui->horizontalSliderSpeakerVolume,SIGNAL(valueChanged(int)),this,SLOT(slotSetSpeakerVolumeValue(int)));
int vol=getMicrophoneVolumeValue();
ui->horizontalSliderMicrophoneVolume->setValue(vol);
ui->lineEditMicrophoneVolumeValue->setText(QString::number(vol));
vol=getSpeakerVolumeValue();
ui->horizontalSliderSpeakerVolume->setValue(vol);
ui->lineEditSpeakerVolumeValue->setText(QString::number(vol));
}
MainWindow::~MainWindow()
{
delete ui;
unInitialVoiceEngine();
}
void MainWindow::creatVoiceEngine()
{
ptrVoEngine = VoiceEngine::Create();
ptrVoEBase = VoEBase::GetInterface(ptrVoEngine);
ptrVoEVolumeControl = VoEVolumeControl::GetInterface(ptrVoEngine);
ptrVoEFile = VoEFile::GetInterface(ptrVoEngine);
ptrVoEHardware = VoEHardware::GetInterface(ptrVoEngine);
}
int MainWindow::initialVoiceEngine()
{
error = ptrVoEBase->Init();
if (error != 0)
{
qDebug()<<"ERROR in VoEBase::Init";
return error;
}
error = ptrVoEBase->RegisterVoiceEngineObserver(myObserver);
if (error != 0)
{
qDebug()<<"ERROR in VoEBase:;RegisterVoiceEngineObserver";
return error;
}
char temp[1024];
error = ptrVoEBase->GetVersion(temp);
if (error != 0)
{
qDebug()<<"ERROR in VoEBase::GetVersion";
return error;
}
ui->lineEditVersion->setText(QString(temp));
return 100;
}
int MainWindow::unInitialVoiceEngine()
{
//Stop Playout
error = ptrVoEBase->StopPlayout(audioChannel);
if (error != 0)
{
qDebug()<<"ERROR in VoEBase::StopPlayout";
return error;
}
error = ptrVoEFile->StopPlayingFileLocally(audioChannel);
if (error != 0)
{
qDebug()<<"ERROR in VoEFile::StopPlayingFileLocally";
return error;
}
//Stop Record
error = ptrVoEFile->StopRecordingMicrophone();
if (error != 0)
{
qDebug()<<"ERROR in VoEFile::StopRecordingMicrophone";
return error;
}
//Delete Channel
error = ptrVoEBase->DeleteChannel(audioChannel);
if (error != 0)
{
qDebug()<<"ERROR in VoEBase::DeleteChannel";
return error;
}
//DeRegister observer
ptrVoEBase->DeRegisterVoiceEngineObserver();
error = ptrVoEBase->Terminate();
if (error != 0)
{
qDebug()<<"ERROR in VoEBase::Terminate";
return error;
}
if(ptrVoEBase)
{
ptrVoEBase->Release();
}
if(ptrVoEVolumeControl)
{
ptrVoEVolumeControl->Release();
}
if(ptrVoEFile)
{
ptrVoEFile->Release();
}
if(ptrVoEHardware)
{
ptrVoEHardware->Release();
}
bool flag = VoiceEngine::Delete(ptrVoEngine);
if (!flag)
{
qDebug()<<"ERROR in VoiceEngine::Delete";
return -1;
}
return 100;
}
int MainWindow::setDevice()
{
int rNum(-1), pNum(-1);
error = ptrVoEHardware->GetNumOfRecordingDevices(rNum);
if (error != 0)
{
qDebug()<<"ERROR in VoEHardware::GetNumOfRecordingDevices";
return error;
}
error = ptrVoEHardware->GetNumOfPlayoutDevices(pNum);
if (error != 0)
{
qDebug()<<"ERROR in VoEHardware::GetNumOfPlayoutDevices";
return error;
}
char name[128] = { 0 };
char guid[128] = { 0 };
for (int j = 0; j < rNum; ++j)
{
error = ptrVoEHardware->GetRecordingDeviceName(j, name, guid);
if (error != 0)
{
qDebug()<<"ERROR in VoEHardware::GetRecordingDeviceName";
return error;
}
ui->comboBoxRecordingDevice->addItem(QString(name));
}
for (int j = 0; j < pNum; ++j)
{
error = ptrVoEHardware->GetPlayoutDeviceName(j, name, guid);
if (error != 0)
{
qDebug()<<"ERROR in VoEHardware::GetPlayoutDeviceName";
return error;
}
ui->comboBoxPlayoutDevice->addItem(QString(name));
}
error = ptrVoEHardware->SetRecordingDevice(ui->comboBoxRecordingDevice->currentIndex());
if (error != 0)
{
qDebug()<<"ERROR in VoEHardware::SetRecordingDevice";
return error;
}
error = ptrVoEHardware->SetPlayoutDevice(ui->comboBoxPlayoutDevice->currentIndex());
if (error != 0)
{
qDebug()<<"ERROR in VoEHardware::SetPlayoutDevice";
return error;
}
return 100;
}
void MainWindow::setChannel()
{
audioChannel = ptrVoEBase->CreateChannel();
if (audioChannel < 0)
{
qDebug()<<"ERROR in VoEBase::CreateChannel";
}
error = ptrVoEBase->StartPlayout(audioChannel);
if(error != 0)
{
qDebug()<<"ERROR in VoEBase::StartPlayout";
}
}
int MainWindow::getMicrophoneVolumeValue()
{
unsigned int vol = 999;
error = ptrVoEVolumeControl->GetMicVolume(vol);
if (error != 0)
{
qDebug()<<"ERROR in VoEVolume::GetMicVolume";
return 0;
}
if ((vol > 255) || (vol < 0))
{
qDebug()<<"ERROR in GetMicVolume";
return 0;
}
return vol;
}
int MainWindow::getSpeakerVolumeValue()
{
unsigned int vol = 999;
error = ptrVoEVolumeControl->GetSpeakerVolume(vol);
if (error != 0)
{
qDebug()<<"ERROR in VoEVolume::GetSpeakerVolume";
return 0;
}
if ((vol > 255) || (vol < 0))
{
qDebug()<<"ERROR in GetSpeakerVolume";
return 0;
}
return vol;
}
void MainWindow::on_pushButtonRecording_clicked()
{
static bool flag=true;
if(flag)
{
//录制麦克风的音频,默认采样率是8000HZ
error = ptrVoEFile->StartRecordingMicrophone("RecordingMicrophone.pcm");
if (error != 0)
{
qDebug()<<"ERROR in VoEFile::StartRecordingMicrophone";
}
else
{
ui->pushButtonRecording->setText(QStringLiteral("停止录音"));
}
}
else
{
error = ptrVoEFile->StopRecordingMicrophone();
if (error != 0)
{
qDebug()<<"ERROR in VoEFile::StopRecordingMicrophone";
}
else
{
ui->pushButtonRecording->setText(QStringLiteral("开始录音"));
}
}
flag=!flag;
}
void MainWindow::on_pushButtonPlayout_clicked()
{
static bool flag=true;
if(flag)
{
error = ptrVoEFile->StartPlayingFileLocally(audioChannel,"RecordingMicrophone.pcm");
if (error != 0)
{
qDebug()<<"ERROR in VoEFile::StartPlayingFileLocally";
}
else
{
ui->pushButtonPlayout->setText(QStringLiteral("停止播放"));
}
}
else
{
error = ptrVoEFile->StopPlayingFileLocally(audioChannel);
if (error != 0)
{
qDebug()<<"ERROR in VoEFile::StopPlayingFileLocally";
}
else
{
ui->pushButtonPlayout->setText(QStringLiteral("开始播放"));
}
}
flag=!flag;
}
void MainWindow::slotSetMicrophoneVolumeValue(int value)
{
error = ptrVoEVolumeControl->SetMicVolume(value);
if (error != 0)
{
qDebug()<<"ERROR in VoEVolume::SetMicVolume";
}
else
{
ui->lineEditMicrophoneVolumeValue->setText(QString::number(value));
}
}
void MainWindow::slotSetSpeakerVolumeValue(int value)
{
error = ptrVoEVolumeControl->SetSpeakerVolume(value);
if (error != 0)
{
qDebug()<<"ERROR in VoEVolume::SetSpeakerVolume";
}
else
{
ui->lineEditSpeakerVolumeValue->setText(QString::number(value));
}
}
三.效果
通过“录音音量”滑块可以实时调节录音的音量大小(0—255)。
通过“播放音量”滑块可以调节播放的音量大小(0—255),类似音乐播放器的音量调节,这里只是调节本软件的音量,而不是调节音频设备的音量。
源码链接:见http://blog.csdn.net/caoshangpa/article/details/53446916的评论