在声音物理学中,音量的变化是对数关系,在代码里,暂时我没有这样处理,简单的用线性关系表示,在主进程进行设置,解码时设置进pcm数据,再用声卡播放。
这段代码的实现也是参考了别人的,代码如下:
/*
* @Func : SetVolume
* @brief : 音量调节
* @author : linghuzhangmen
* @[in] : buf 为需要调节音量的音频数据块首地址指针
* @[in] : size为长度
* @[in] : uRepeat为重复次数,通常设为1
* @[in] : vol为增益倍数,可以小于1
*/
void MyFFmpeg::SetVolume(char* buf, UINT32 size, UINT32 uRepeat, double vol)
{
if (!size)
{
return;
}
for (int i = 0; i < size; i += 2)
{
short wData;
wData = MAKEWORD(buf[i], buf[i + 1]);
long dwData = wData;
for (int j = 0; j < uRepeat; j++)
{
dwData = dwData * vol;
if (dwData < -0x8000)
{
dwData = -0x8000;
}
else if (dwData > 0x7FFF)
{
dwData = 0x7FFF;
}
}
wData = LOWORD(dwData);
buf[i] = LOBYTE(wData);
buf[i + 1] = HIBYTE(wData);
}
}
在转成pcm数据时,加上音量的调节
int MyFFmpeg::ToPCM(char *out)
{
m_mutex.lock();
if (!m_afc || !m_pcm || !out)
{
m_mutex.unlock();
return 0;
}
AVCodecContext *ctx = m_afc->streams[m_audioStream]->codec;
if (m_aCtx == NULL)
{
m_aCtx = swr_alloc();
//可能会出问题, 16位音频
swr_alloc_set_opts(m_aCtx, ctx->channel_layout,
AV_SAMPLE_FMT_S16,
ctx->sample_rate,
ctx->channels,
ctx->sample_fmt,
ctx->sample_rate,
0, 0);
swr_init(m_aCtx); //初始化样本转换
}
uint8_t *data[1];
data[0] = (uint8_t *)out;
int len = swr_convert(m_aCtx, data, 10000, (const uint8_t **)m_pcm->data, m_pcm->nb_samples);
if (len <= 0)
{
m_mutex.unlock();
return 0;
}
int outsize = av_samples_get_buffer_size(NULL, ctx->channels, m_pcm->nb_samples, AV_SAMPLE_FMT_S16, 0);
//音量调节
SetVolume(out, outsize, 1, m_VolumeRatio);
m_mutex.unlock();
return outsize;
}
播放时,拖动slider就能调节声音的变化
//调节音量
void FFVideoPlayer::volumeAdjust()
{
MyFFmpeg::Get()->m_VolumeRatio = (ui.sliderVolume->value()) * 1.00 / 100;
}
静音的设置就直接把增益参数设为0,即可,同时把图标也换掉,代码如下:
//静音设置
void FFVideoPlayer::setMute()
{
m_isMute = !m_isMute;
if (m_isMute)
{
MyFFmpeg::Get()->m_VolumeRatio = 0;
setButtonBackImage(ui.btnSetVolume, "./Resources/mute.png");
}
else
{
MyFFmpeg::Get()->m_VolumeRatio = 0.5;
setButtonBackImage(ui.btnSetVolume, "./Resources/volume.png");
}
}
其实这种设置有问题,目前我没想到更好的办法,以后解决了再更新。
本教程专栏地址:https://blog.csdn.net/yao_hou/category_9275800.html
源码链接在第五篇。