计算音频的分贝值

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;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LabVIEW 是一种用于图形化编程的软件开发环境,可以用于各种信号处理和数据采集应用。在 LabVIEW 中,可以使用内置的工具和函数来实现音频信号的采集和分贝计算。 首先,需要使用适当的硬件设备(如声卡)连接输入音频信号源。在 LabVIEW 中,可以使用 DAQ (Data Acquisition) 功能模块来实现音频信号的采集。在 DAQ 功能模块中,可以选择适当的输入通道和采样率,并设置采集时长。 然后,可以使用 LabVIEW 中的信号处理工具进行分贝计算。一个常用的方法是使用 FFT (Fast Fourier Transform) 算法将时域的音频信号转换为频域的频谱图。在频谱图上,可以将每个频率对应的幅度计算出来,并转换为分贝。 在 LabVIEW 中,可以使用 FFT VI 来实现频谱分析。将采集到的音频信号输入到 FFT VI 中,并设置适当的参数,如采样率和窗函数类型。然后,可以通过调节 FFT VI 的输出结果来获取频谱幅度信息,并将其转换为分贝。 最后,可以使用 LabVIEW 中的图表或指示器来显示分贝结果。可以选择适当的图表类型,如折线图或条形图,来显示音频信号的频谱和分贝。也可以将分贝显示在数字指示器中,以便直观地了解音频信号的级别。 总之,使用 LabVIEW 实现音频信号的采集和分贝计算可以借助 DAQ 功能模块和 FFT VI 来实现。通过合适的参数设置和信号处理,可以获取音频信号的分贝信息,并通过图表或指示器进行展示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值