音频传输过程中,我们可以对采集到的音频数据进行前处理和后处理,获取想要的播放效果。
对于有自行处理音频数据需求的场景,声网提供原始数据功能,你可以在将数据发送给编码器前进行前处理,对捕捉到的语音信号进行修改;也可以在将数据发送给解码器后进行后处理,对接收到的语音信号进行修改。
Native SDK 通过提供 IAudioFrameObserver
类,实现采集、修改原始音频数据功能。
我们在 GitHub 上提供一个开源的示例项目,你可以前往下载,或查看其中的源代码。
在使用原始数据功能前,请确保你已在项目中完成基本的实时音频功能,详见一对一通话或互动直播。
参考如下步骤,在你的项目中实现原始音频数据功能:
registerAudioFrameObserver
方法注册语音观测器。onRecordAudioFrame
、onPlaybackAudioFrame
、onPlaybackAudioFrameBeforeMixing
或 onMixedAudioFrame
回调发送采集到的原始音频数据。onRecordAudioFrame
、onPlaybackAudioFrame
、onPlaybackAudioFrameBeforeMixing
或 onMixedAudioFrame
回调发送给 SDK。下图展示使用原始音频数据的 API 调用时序:
下图展示了原始音频数据的流转:
你可以通过 onRecordAudioFrame
、onPlaybackAudioFrame
、onPlaybackAudioFrameBeforeMixing
或 onMixedAudioFrame
回调:
AudioFrame
获取原始音频数据。AudioFrame
的原始音频数据进行处理并返回到 SDK。registerAudioFrameObserver
注册音频观测器。// 注册或取消注册音频观测器
BOOL CAgoraOriginalAudioDlg::RegisterAudioFrameObserver(BOOL bEnable, IAudioFrameObserver *audioFrameObserver)
{
// 创建使用 IMediaEngine 类为 template 的 AutoPtr 实例。
agora::util::AutoPtr<agora::media::IMediaEngine> mediaEngine;
// 关于 AutoPtr 类的实现参考 SDK 中的 AgoraBase.h 文件。
// AutoPtr 实例调用 queryInterface 方法,通过 IID 获取 IMediaEngine 实例的指针。
// AutoPtr 实例会通过箭头操作符访问 IMediaEngine 实例的指针并通过 IMediaEngine 实例调用 registerAudioFrameObserver
mediaEngine.queryInterface(m_rtcEngine, agora::AGORA_IID_MEDIA_ENGINE);
int nRet = 0;
if (mediaEngine.get() == NULL)
return FALSE;
if (bEnable)
// 注册音频观测器
nRet = mediaEngine->registerAudioFrameObserver(audioFrameObserver);
else
// 取消注册音频观测器
nRet = mediaEngine->registerAudioFrameObserver(NULL);
return nRet == 0 ? TRUE : FALSE;
}
获得录制的原始音频数据
// 获得录制的原始音频数据,进行音量放大处理并发送给 SDK
bool COriginalAudioProcFrameObserver::onRecordAudioFrame(AudioFrame& audioFrame)
{
SIZE_T nSize = audioFrame.channels * audioFrame.samples * 2;
unsigned int readByte = 0;
int timestamp = GetTickCount();
short *pBuffer = (short *)audioFrame.buffer;
for (SIZE_T i = 0; i < nSize / 2; i++)
{
if (pBuffer[i] * 2 > 32767) {
pBuffer[i] = 32767;
}
else if (pBuffer[i] * 2 < -32768) {
pBuffer[i] = -32768;
}
else {
pBuffer[i] *= 2;
}
}
return true;
}
获得播放的原始音频数据
// 获得播放的原始音频数据
bool COriginalAudioProcFrameObserver::onPlaybackAudioFrame(AudioFrame& audioFrame)
{
return true;
}
获取录制和播放语音混音后的原始音频数据
// 获取录制和播放语音混音后的原始音频数据
bool COriginalAudioProcFrameObserver::onMixedAudioFrame(AudioFrame& audioFrame)
{
return true;
}
获得混音前的指定用户的声音
// 获得混音前的指定用户的声音
bool COriginalAudioProcFrameObserver::onPlaybackAudioFrameBeforeMixing(unsigned int uid, AudioFrame& audioFrame)
{
return true;
}
如果想要修改上述回调中的音频采样率,可以根据场景需求,调用如下方法进行设置: