SDL_OpenAudioDevice 回调函数
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
{
VideoState *is = opaque;
int audio_size, len1 , len2;
len2 = len;
Uint8 * stream1 = stream;
audio_callback_time = av_gettime_relative();
while (len > 0) {
double sec = (double)is->audio_frame_nb_samples / is->audio_frame_sample_rate;
double clock = is->audio_clock - sec;
double mytime = clock + (sec * ((double)is->audio_buf_index) / (is->audio_buf_size));
double pausetime = (is->pts_int) / 25.0;
if (is->seek_audio_flag)
{
is->audio_buf_index = is->audio_buf_size;
}
else if (is->paused)
{
if (mytime >= pausetime)
{
memset(stream, 0, len);
break;
}
}
if (is->audio_buf_index >= is->audio_buf_size) {
audio_size = audio_decode_frame(is);
if (audio_size < 0) {
/* if error, just output silence */
is->audio_buf = NULL;
is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
}
else {
if (is->show_mode != SHOW_MODE_VIDEO)
update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
is->audio_buf_size = audio_size;
is->seek_audio_flag = 0;
}
is->audio_buf_index = 0;
}
len1 = is->audio_buf_size - is->audio_buf_index;
if (len1 > len)
len1 = len;
if (is->paused)//如果暂停了 就静音 针对跳转之后音频继续播放的问题
{
memset(stream, 0, len1);
if (!is->muted && is->audio_buf)
SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, 0);
}
else if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
{
memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
}
else {
memset(stream, 0, len1);
if (!is->muted && is->audio_buf)
SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
}
len -= len1;
stream += len1;
is->audio_buf_index += len1;
}
getPcmDB(stream1 , len2 , is);//分贝值计算
is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
/* Let's assume the audio driver that is used by SDL has two periods. */
if (!isnan(is->audio_clock)) {
set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
sync_clock_to_slave(&is->extclk, &is->audclk);
}
}
getPcmDB函数: 忘了从哪抄来的。。
int getPcmDB(const unsigned char * pcmdata, size_t size, VideoState* is)
{
int left_db = 0, right_db = 0,fc_db = 0, lfe_db = 0,bl_db = 0, br_db = 0,sl_db = 0, sr_db = 0,bc_db = 0;
double sum_right = 0, sum_left = 0, left_max = 0, right_max = 0;
double sum_fc_db = 0, fc_max_db = 0, sum_lfe_db = 0, lfe_max_db = 0;
double sum_bl_db = 0, bl_max_db = 0, sum_br_db = 0, br_max_db = 0;
double sum_sl_db = 0, sl_max_db = 0, sum_sr_db = 0, sr_max_db = 0;
double sum_bc_db = 0, bc_max_db = 0;
short int value = 0;
int channel = is->audio_src.channels;
if (channel <= 8 && channel >= 1)
{
for (int i = 0; i < size; i += 2)
{
memcpy(&value, pcmdata + i, 2);
sum_left += abs(value);
left_max = left_max < abs(value) ? abs(value) : left_max;
if (channel >= 2)
{
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_right += abs(value);
right_max = right_max < abs(value) ? abs(value) : right_max;
if (channel == 3)
{
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_lfe_db += abs(value);
lfe_max_db = lfe_max_db < abs(value) ? abs(value) : lfe_max_db;
}
if (channel == 4)
{
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_bl_db += abs(value);
bl_max_db = bl_max_db < abs(value) ? abs(value) : bl_max_db;
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_br_db += abs(value);
br_max_db = br_max_db < abs(value) ? abs(value) : br_max_db;
}
if (channel >= 5)
{
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_fc_db += abs(value);
fc_max_db = fc_max_db < abs(value) ? abs(value) : fc_max_db;
if (channel == 5)
{
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_bl_db += abs(value);
bl_max_db = bl_max_db < abs(value) ? abs(value) : bl_max_db;
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_br_db += abs(value);
br_max_db = br_max_db < abs(value) ? abs(value) : br_max_db;
}
else
{
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_lfe_db += abs(value);
lfe_max_db = lfe_max_db < abs(value) ? abs(value) : lfe_max_db;
if (channel == 7)
{
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_bc_db += abs(value);
bc_max_db = bc_max_db < abs(value) ? abs(value) : bc_max_db;
}
if (channel == 8)
{
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_bl_db += abs(value);
bl_max_db = bl_max_db < abs(value) ? abs(value) : bl_max_db;
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_br_db += abs(value);
br_max_db = br_max_db < abs(value) ? abs(value) : br_max_db;
}
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_sl_db += abs(value);
sl_max_db = sl_max_db < abs(value) ? abs(value) : sl_max_db;
i += 2;
memcpy(&value, pcmdata + i, 2);
sum_sr_db += abs(value);
sr_max_db = sr_max_db < abs(value) ? abs(value) : sr_max_db;
}
}
}
}
}
sum_left = sum_left / (size / 2 / channel);
sum_right = sum_right / (size / 2 / channel);
sum_fc_db = sum_fc_db / (size / 2 / channel);
sum_lfe_db = sum_lfe_db / (size / 2 / channel);
sum_bl_db = sum_bl_db / (size / 2 / channel);
sum_br_db = sum_br_db / (size / 2 / channel);
sum_sl_db = sum_sl_db / (size / 2 / channel);
sum_sr_db = sum_sr_db / (size / 2 / channel);
sum_bc_db = sum_bc_db / (size / 2 / channel);
if (sum_left > 0)
{
left_db = (int)(20.0 * log10(sum_left / 65535));
left_max = (int)(20.0 * log10(left_max / 65535));
}
if (sum_right > 0)
{
right_db = (int)(20.0 * log10(sum_right / 65535));
right_max = (int)(20.0 * log10(right_max / 65535));
}
if (sum_fc_db > 0)
{
fc_db = (int)(20.0 * log10(sum_fc_db / 65535));
fc_max_db = (int)(20.0 * log10(fc_max_db / 65535));
}
if (sum_lfe_db > 0)
{
lfe_db = (int)(20.0 * log10(sum_lfe_db / 65535));
lfe_max_db = (int)(20.0 * log10(lfe_max_db / 65535));
}
if (sum_bl_db > 0)
{
bl_db = (int)(20.0 * log10(sum_bl_db / 65535));
bl_max_db = (int)(20.0 * log10(bl_max_db / 65535));
}
if (sum_br_db > 0)
{
br_db = (int)(20.0 * log10(sum_br_db / 65535));
br_max_db = (int)(20.0 * log10(br_max_db / 65535));
}
if (sum_sl_db > 0)
{
sl_db = (int)(20.0 * log10(sum_sl_db / 65535));
sl_max_db = (int)(20.0 * log10(sl_max_db / 65535));
}
if (sum_sr_db > 0)
{
sr_db = (int)(20.0 * log10(sum_sr_db / 65535));
sr_max_db = (int)(20.0 * log10(sr_max_db / 65535));
}
if (sum_bc_db > 0)
{
bc_db = (int)(20.0 * log10(sum_bc_db / 65535));
bc_max_db = (int)(20.0 * log10(bc_max_db / 65535));
}
is->audio_db.channel = channel;
is->audio_db.FL_db = left_db;
is->audio_db.FL_max_db = left_max;
is->audio_db.FR_db = right_db;
is->audio_db.FR_max_db = right_max;
is->audio_db.FC_max_db = fc_max_db;
is->audio_db.FC_db = fc_db;
is->audio_db.LFE_max_db = lfe_max_db;
is->audio_db.LFE_db = lfe_db;
is->audio_db.BL_max_db = bl_max_db;
is->audio_db.BL_db = bl_db;
is->audio_db.BR_max_db = br_max_db;
is->audio_db.BR_db = br_db;
is->audio_db.SL_max_db = sl_max_db;
is->audio_db.SL_db = sl_db;
is->audio_db.SR_max_db = sr_max_db;
is->audio_db.SR_db = sr_db;
is->audio_db.BC_max_db = bc_max_db;
is->audio_db.BC_db = bc_db;
return 0;
}
is->audio_db结构体为Audiodb
/**
* 2: FL FR (stereo)
* 3: FL FR LFE (2.1 surround)
* 4: FL FR BL BR (quad)
* 5: FL FR FC BL BR (quad + center)
* 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR)
* 7: FL FR FC LFE BC SL SR (6.1 surround)
* 8: FL FR FC LFE BL BR SL SR (7.1 surround)
*/
typedef struct Audiodb
{
int channel;
int FL_max_db;//最大分贝
int FL_db;//平均分贝
int FR_max_db;
int FR_db;
int FC_max_db;
int FC_db;
int LFE_max_db;
int LFE_db;
int BL_max_db;
int BL_db;
int BR_max_db;
int BR_db;
int SL_max_db;
int SL_db;
int SR_max_db;
int SR_db;
int BC_max_db;
int BC_db;
}Audiodb;