xref: /OK3568_Linux_fs/buildroot/package/alsa-lib/0002-add-dcbfilter-16bit-process.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From e9f6ad9b0b7f208f0431d20dbf13b669143cc39d Mon Sep 17 00:00:00 2001
2From: Yu YongZhen <yuyz@rock-chips.com>
3Date: Fri, 11 May 2018 14:45:40 +0800
4Subject: [PATCH 2/4] add dcbfilter 16bit process
5
6---
7 src/pcm/pcm.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++-
8 1 file changed, 168 insertions(+), 1 deletion(-)
9
10diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
11index 9aec52d..a2eb529 100644
12--- a/src/pcm/pcm.c
13+++ b/src/pcm/pcm.c
14@@ -692,6 +692,168 @@ static int pcm_state_to_error(snd_pcm_state_t state)
15 			  P_STATE(PAUSED) | \
16 			  P_STATE(DRAINING))
17
18+//#define DCB_FILTER_16BIT
19+#ifdef DCB_FILTER_16BIT
20+
21+#define A1 32511 // (1-2^(-7))     Q32:1.31 // 32752=>0.99951171875
22+
23+#define TO_16BIT_SHIFT 15
24+#define MAX_Uint_PCMBIT_SIZE 4294967296
25+#define MAX_UNSIGN_PCMBIT_SIZE 65536
26+#define MAX_SIGN_POS_PCMBIT_SIZE 32768
27+#define MAX_SIGN_NEG_PCMBIT_SIZE -32768
28+
29+/* static variables for previous values */
30+/* left 1 */
31+static int16_t x_prev_l1=0;
32+static int16_t   y_prev_l1=0;
33+/* right 1 */
34+static int16_t x_prev_r1=0;
35+static int16_t   y_prev_r1=0;
36+/* left 2 */
37+static int16_t x_prev_l2=0;
38+static int16_t   y_prev_l2=0;
39+/* right 1 */
40+static int16_t x_prev_r2=0;
41+static int16_t   y_prev_r2=0;
42+/* left 1 */
43+static int16_t x_prev_l3=0;
44+static int16_t   y_prev_l3=0;
45+/* right 1 */
46+static int16_t x_prev_r3=0;
47+static int16_t   y_prev_r3=0;
48+
49+void dc_filter_left1(int16_t *pcmIn)
50+{
51+    int16_t sampleIn, delta_x, sampleOut;
52+    int16_t   a1_y_prev;
53+
54+    sampleIn = *pcmIn;
55+    delta_x = sampleIn-x_prev_l1;
56+    a1_y_prev = A1*y_prev_l1/MAX_SIGN_POS_PCMBIT_SIZE;
57+    sampleOut = delta_x+a1_y_prev;
58+
59+    x_prev_l1 = sampleIn;
60+    y_prev_l1 = sampleOut;
61+
62+    *pcmIn = sampleOut;
63+}
64+void dc_filter_right1(int16_t *pcmIn)
65+{
66+    int16_t sampleIn, delta_x, sampleOut;
67+    int16_t a1_y_prev;
68+
69+    sampleIn = *pcmIn;
70+    delta_x = sampleIn-x_prev_r1;
71+    a1_y_prev = A1*y_prev_r1/MAX_SIGN_POS_PCMBIT_SIZE;
72+    sampleOut = delta_x+a1_y_prev;
73+
74+    x_prev_r1 = sampleIn;
75+    y_prev_r1 = sampleOut;
76+
77+    *pcmIn = sampleOut;
78+}
79+void dc_filter_left2(int16_t *pcmIn)
80+{
81+    int16_t sampleIn, delta_x, sampleOut;
82+    int16_t a1_y_prev;
83+
84+    sampleIn = *pcmIn;
85+    delta_x = sampleIn-x_prev_l2;
86+    a1_y_prev = A1*y_prev_l2/MAX_SIGN_POS_PCMBIT_SIZE;
87+    sampleOut = delta_x+a1_y_prev;
88+
89+    x_prev_l2 = sampleIn;
90+    y_prev_l2 = sampleOut;
91+
92+    *pcmIn = sampleOut;
93+}
94+
95+void dc_filter_right2(int16_t *pcmIn)
96+{
97+    int16_t sampleIn, delta_x, sampleOut;
98+    int16_t a1_y_prev;
99+
100+    sampleIn = *pcmIn;
101+    delta_x = sampleIn-x_prev_r2;
102+    a1_y_prev = A1*y_prev_r2/MAX_SIGN_POS_PCMBIT_SIZE;
103+    sampleOut = delta_x+a1_y_prev;
104+
105+    x_prev_r2 = sampleIn;
106+    y_prev_r2 = sampleOut;
107+
108+    *pcmIn = sampleOut;
109+}
110+void dc_filter_left3(int16_t *pcmIn)
111+{
112+    int16_t sampleIn, delta_x, sampleOut;
113+    int16_t a1_y_prev;
114+
115+    sampleIn = *pcmIn;
116+    delta_x = sampleIn-x_prev_l3;
117+    a1_y_prev = A1*y_prev_l3/MAX_SIGN_POS_PCMBIT_SIZE;
118+    sampleOut = delta_x+a1_y_prev;
119+
120+    x_prev_l3 = sampleIn;
121+    y_prev_l3 = (int16_t)sampleOut;
122+
123+    *pcmIn = sampleOut;
124+}
125+
126+void dc_filter_right3(int16_t *pcmIn)
127+{
128+    int16_t sampleIn, delta_x, sampleOut;
129+    int16_t a1_y_prev;
130+
131+    sampleIn = *pcmIn;
132+    delta_x = sampleIn-x_prev_r3;
133+    a1_y_prev = A1*y_prev_r3/MAX_SIGN_POS_PCMBIT_SIZE;
134+    sampleOut = delta_x+a1_y_prev;
135+
136+    x_prev_r3 = sampleIn;
137+    y_prev_r3 = (int16_t)sampleOut;
138+
139+    *pcmIn = sampleOut;
140+}
141+
142+void DCBDoing(void* pIn, int length, int channels)
143+{
144+    int i = 0;
145+    int16_t * pInBuf  =  (int16_t *)pIn;
146+
147+    //printf("vicent-DCB_Doing---------------length = %d\n",length);
148+
149+    for(i = 0; i < length; i ++ ) {
150+
151+        int curChannel = i % channels;
152+
153+        switch(curChannel){
154+            case 0:
155+                dc_filter_left1(pInBuf);
156+                break;
157+            case 1:
158+                dc_filter_right1(pInBuf);
159+                break;
160+            case 2:
161+                dc_filter_left2(pInBuf);
162+                break;
163+            case 3:
164+                dc_filter_right2(pInBuf);
165+                break;
166+            case 4:
167+                dc_filter_left3(pInBuf);
168+                break;
169+            case 5:
170+                dc_filter_right3(pInBuf);
171+                break;
172+            default:
173+                break;
174+        }
175+        pInBuf++;
176+    }
177+}
178+#endif
179+
180 /* check whether the PCM is in the unexpected state */
181 static int bad_pcm_state(snd_pcm_t *pcm, unsigned int supported_states,
182 			 unsigned int noop_states)
183@@ -1646,7 +1808,12 @@ snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t
184 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
185 	if (err < 0)
186 		return err;
187-	return _snd_pcm_readi(pcm, buffer, size);
188+
189+	snd_pcm_sframes_t tmp = _snd_pcm_readi(pcm, buffer, size);
190+#ifdef DCB_FILTER_16BIT
191+	DCBDoing((void*)buffer, tmp * pcm->frame_bits / 8 / sizeof(int16_t), pcm->channels);
192+#endif
193+	return tmp;
194 }
195
196 /**
197--
1982.20.1
199
200