当前位置:网站首页>Audio PCM data calculates sound decibel value to realize simple VAD function

Audio PCM data calculates sound decibel value to realize simple VAD function

2022-06-25 01:17:00 Songyulong's blog

Calculate audio data PCM Decibel value , Calculation formula :
L p = 20 ∗ L o g 10 ( P r m s / P r e f ) d B L_p=20*Log_{10}(Prms/Pref)dB Lp=20Log10(Prms/Pref)dB

P r m s Prms Prms: Current sound amplitude value ;
P r e f Pref Pref: The maximum amplitude of sound ( namely PCM The maximum value represented by the data );
about 16bitsPCM data , A sound sampling point is 2 Maximum bytes ( 2 16 − 1 = 65535 2^{16}-1=65535 2161=65535
We are right. n Sum the data of sampling points and then take the average value , As P r m s / P r e f Prms/Pref Prms/Pref

/** * @brief  obtain PCM Data decibel value  * * @param pcm : pcm Data pointer  * @param len : pcm Data length  * @return int :  Decibel value  = 20*log10(pcm Data average ) * @note Lp = 20*log10(Prms/Pref)dB | Lp: Calculate the audio decibel value of the result , Prms: Current sound amplitude value ,Pref: The maximum amplitude of sound (16bit=65535), 16Bit Maximum decibel value =20*log10(65535)=96.32(dB). * */
static int komijbox_sound_dB(const uint8_t *pcm, int len)
{
    
	int sum = 0;
	int dB = 0;
	short tmp = 0;
	short* pcmaddr = (short*)pcm;

	for (int i=0; i<len; i+=2) {
    
		memcpy(&tmp, pcmaddr+i, sizeof(short)); //  obtain 2 byte PCM data 
		sum += abs(tmp); //  Sum and accumulate absolute values 
	}
	
	sum = sum / (len /2); //  seek PCM The average of the data ,2 Bytes represent a 16Bit PCM Sampled data 
	if (sum) {
    
		dB = (int)(20*log10(sum));
	}

	return dB;
}

It is simple to realize through audio decibel value VAD function :

#define D_VAD_VALID_dB_Max 75 // VAD  Effective decibel value   Maximum   Greater than this value is considered VAD It works 
#define D_VAD_VALID_dB_Min 58 // VAD  Invalid DB value   minimum value   Less than this value is considered VAD Invalid 
#define D_VAD_VALID_UP_COUNT 2 // VAD  Pull up count ( Continuous valid value count ), Greater than this value triggers  VAD_UP event 
#define D_VAD_VALID_DOWN_COUNT 30 // VAD  Pull up count ( Continuous invalid value count ), Greater than this value triggers  VAD_DOWN event 

/** * @brief VAD  State type  * */
enum {
    
	E_VAD_STATUS_NONE = 0,
	E_VAD_STATUS_UP,	 		// Up
	E_VAD_STATUS_LISTENING,	 	// Listening
	E_VAD_STATUS_DOWN			// Down
};

typedef void (*vad_callback)(int vad_status);

struct __vad_t{
    
	int status;
	int up_count;
	int down_count;
	vad_callback up_cb;
	vad_callback down_cb;
	vad_callback listening_cb;
};


// TODO: Calculate audio PCM Data audio decibel value 
int dB = komijbox_sound_dB((uint8_t*)data, len);
	// printf("pcmdB:%d\n", dB);

	// TODO: Judge by audio decibel value VAD state , Realize the function of voice control switch 
	if (dB >= D_VAD_VALID_dB_Max) {
    
		__this->vad.up_count += 1;
		__this->vad.down_count = 0;
		if (__this->vad.up_count >= D_VAD_VALID_UP_COUNT) {
    
			// __this->vad.down_count = 0;

			if (__this->vad.status != E_VAD_STATUS_UP) {
    
				__this->vad.status = E_VAD_STATUS_UP;
			
				// TODO: VAD UP
				printf("=============== VAD Up\n");
				if (__this->vad.up_cb != NULL) {
    
					__this->vad.up_cb(__this->vad.status);
				}

			} else {
    
				// TODO: VAD LISTENING // listening
				printf("=============== VAD Listening\n");
			}			
		}
	} else if (dB <= D_VAD_VALID_dB_Min) {
    
		__this->vad.down_count += 1;
		__this->vad.up_count = 0;
		if (__this->vad.down_count >= D_VAD_VALID_DOWN_COUNT) {
    
			// __this->vad.up_count = 0;

			if (__this->vad.status != E_VAD_STATUS_DOWN) {
    
				__this->vad.status = E_VAD_STATUS_DOWN;

				// TODO: VAD DOWN
				printf("=============== VAD Down\n");
				if (__this->vad.down_cb != NULL) {
    
					__this->vad.down_cb(__this->vad.status);
				}
			}			
		}
	}
原网站

版权声明
本文为[Songyulong's blog]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206242035498287.html