From 200cb3393dbdbb14847cb9b6a96a6f823ae93f50 Mon Sep 17 00:00:00 2001 From: Yu YongZhen Date: Fri, 11 May 2018 14:45:40 +0800 Subject: [PATCH] add dcbfilter 16bit process --- src/pcm/pcm.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 1 deletion(-) diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index fc7bd52..9c90afb 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -664,6 +664,167 @@ playback devices. P_STATE(PAUSED) | \ P_STATE(DRAINING)) +//#define DCB_FILTER_16BIT +#ifdef DCB_FILTER_16BIT + +#define A1 32511 // (1-2^(-7)) Q32:1.31 // 32752=>0.99951171875 + +#define TO_16BIT_SHIFT 15 +#define MAX_Uint_PCMBIT_SIZE 4294967296 +#define MAX_UNSIGN_PCMBIT_SIZE 65536 +#define MAX_SIGN_POS_PCMBIT_SIZE 32768 +#define MAX_SIGN_NEG_PCMBIT_SIZE -32768 + +/* static variables for previous values */ +/* left 1 */ +static int16_t x_prev_l1=0; +static int16_t y_prev_l1=0; +/* right 1 */ +static int16_t x_prev_r1=0; +static int16_t y_prev_r1=0; +/* left 2 */ +static int16_t x_prev_l2=0; +static int16_t y_prev_l2=0; +/* right 1 */ +static int16_t x_prev_r2=0; +static int16_t y_prev_r2=0; +/* left 1 */ +static int16_t x_prev_l3=0; +static int16_t y_prev_l3=0; +/* right 1 */ +static int16_t x_prev_r3=0; +static int16_t y_prev_r3=0; + +void dc_filter_left1(int16_t *pcmIn) +{ + int16_t sampleIn, delta_x, sampleOut; + int16_t a1_y_prev; + + sampleIn = *pcmIn; + delta_x = sampleIn-x_prev_l1; + a1_y_prev = A1*y_prev_l1/MAX_SIGN_POS_PCMBIT_SIZE; + sampleOut = delta_x+a1_y_prev; + + x_prev_l1 = sampleIn; + y_prev_l1 = sampleOut; + + *pcmIn = sampleOut; +} +void dc_filter_right1(int16_t *pcmIn) +{ + int16_t sampleIn, delta_x, sampleOut; + int16_t a1_y_prev; + + sampleIn = *pcmIn; + delta_x = sampleIn-x_prev_r1; + a1_y_prev = A1*y_prev_r1/MAX_SIGN_POS_PCMBIT_SIZE; + sampleOut = delta_x+a1_y_prev; + + x_prev_r1 = sampleIn; + y_prev_r1 = sampleOut; + + *pcmIn = sampleOut; +} +void dc_filter_left2(int16_t *pcmIn) +{ + int16_t sampleIn, delta_x, sampleOut; + int16_t a1_y_prev; + + sampleIn = *pcmIn; + delta_x = sampleIn-x_prev_l2; + a1_y_prev = A1*y_prev_l2/MAX_SIGN_POS_PCMBIT_SIZE; + sampleOut = delta_x+a1_y_prev; + + x_prev_l2 = sampleIn; + y_prev_l2 = sampleOut; + + *pcmIn = sampleOut; +} + +void dc_filter_right2(int16_t *pcmIn) +{ + int16_t sampleIn, delta_x, sampleOut; + int16_t a1_y_prev; + + sampleIn = *pcmIn; + delta_x = sampleIn-x_prev_r2; + a1_y_prev = A1*y_prev_r2/MAX_SIGN_POS_PCMBIT_SIZE; + sampleOut = delta_x+a1_y_prev; + + x_prev_r2 = sampleIn; + y_prev_r2 = sampleOut; + + *pcmIn = sampleOut; +} +void dc_filter_left3(int16_t *pcmIn) +{ + int16_t sampleIn, delta_x, sampleOut; + int16_t a1_y_prev; + + sampleIn = *pcmIn; + delta_x = sampleIn-x_prev_l3; + a1_y_prev = A1*y_prev_l3/MAX_SIGN_POS_PCMBIT_SIZE; + sampleOut = delta_x+a1_y_prev; + + x_prev_l3 = sampleIn; + y_prev_l3 = (int16_t)sampleOut; + + *pcmIn = sampleOut; +} + +void dc_filter_right3(int16_t *pcmIn) +{ + int16_t sampleIn, delta_x, sampleOut; + int16_t a1_y_prev; + + sampleIn = *pcmIn; + delta_x = sampleIn-x_prev_r3; + a1_y_prev = A1*y_prev_r3/MAX_SIGN_POS_PCMBIT_SIZE; + sampleOut = delta_x+a1_y_prev; + + x_prev_r3 = sampleIn; + y_prev_r3 = (int16_t)sampleOut; + + *pcmIn = sampleOut; +} + +void DCBDoing(void* pIn, int length, int channels) +{ + int i = 0; + int16_t * pInBuf = (int16_t *)pIn; + + //printf("vicent-DCB_Doing---------------length = %d\n",length); + + for(i = 0; i < length; i ++ ) { + + int curChannel = i % channels; + + switch(curChannel){ + case 0: + dc_filter_left1(pInBuf); + break; + case 1: + dc_filter_right1(pInBuf); + break; + case 2: + dc_filter_left2(pInBuf); + break; + case 3: + dc_filter_right2(pInBuf); + break; + case 4: + dc_filter_left3(pInBuf); + break; + case 5: + dc_filter_right3(pInBuf); + break; + default: + break; + } + pInBuf++; + } +} +#endif /* check whether the PCM is in the unexpected state */ static int bad_pcm_state(snd_pcm_t *pcm, unsigned int supported_states) { @@ -1509,7 +1670,12 @@ snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t } if (bad_pcm_state(pcm, P_STATE_RUNNABLE)) return -EBADFD; - return _snd_pcm_readi(pcm, buffer, size); + + snd_pcm_sframes_t tmp = _snd_pcm_readi(pcm, buffer, size); +#ifdef DCB_FILTER_16BIT + DCBDoing((void*)buffer, tmp * pcm->frame_bits / 8 / sizeof(int16_t), pcm->channels); +#endif + return tmp; } /** -- 2.7.4