1 /* $Id$ */
2 /*
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #include <pjmedia/delaybuf.h>
22 #include <pjmedia/circbuf.h>
23 #include <pjmedia/errno.h>
24 #include <pjmedia/frame.h>
25 #include <pjmedia/wsola.h>
26 #include <pj/assert.h>
27 #include <pj/lock.h>
28 #include <pj/log.h>
29 #include <pj/math.h>
30 #include <pj/pool.h>
31 
32 
33 #if 0
34 #   define TRACE__(x) PJ_LOG(3,x)
35 #else
36 #   define TRACE__(x)
37 #endif
38 
39 /* Operation types of delay buffer */
40 enum OP
41 {
42     OP_PUT,
43     OP_GET
44 };
45 
46 /* Specify time for delaybuf to recalculate effective delay, in ms.
47  */
48 #define RECALC_TIME	    2000
49 
50 /* Default value of maximum delay, in ms, this value is used when
51  * maximum delay requested is less than ptime (one frame length).
52  */
53 #define DEFAULT_MAX_DELAY   400
54 
55 /* Number of frames to add to learnt level for additional stability.
56  */
57 #define SAFE_MARGIN	    0
58 
59 /* This structure describes internal delaybuf settings and states.
60  */
61 struct pjmedia_delay_buf
62 {
63     /* Properties and configuration */
64     char	     obj_name[PJ_MAX_OBJ_NAME];
65     pj_lock_t	    *lock;		/**< Lock object.		     */
66     unsigned	     samples_per_frame; /**< Number of samples in one frame  */
67     unsigned	     ptime;		/**< Frame time, in ms		     */
68     unsigned	     channel_count;	/**< Channel count, in ms	     */
69     pjmedia_circ_buf *circ_buf;		/**< Circular buffer to store audio
70 					     samples			     */
71     unsigned	     max_cnt;		/**< Maximum samples to be buffered  */
72     unsigned	     eff_cnt;		/**< Effective count of buffered
73 					     samples to keep the optimum
74 					     balance between delay and
75 					     stability. This is calculated
76 					     based on burst level.	     */
77 
78     /* Learning vars */
79     unsigned	     level;		/**< Burst level counter	     */
80     enum OP	     last_op;		/**< Last op (GET or PUT) of learning*/
81     int		     recalc_timer;	/**< Timer for recalculating max_level*/
82     unsigned	     max_level;		/**< Current max burst level	     */
83 
84     /* Drift handler */
85     pjmedia_wsola   *wsola;		/**< Drift handler		     */
86 };
87 
88 
pjmedia_delay_buf_create(pj_pool_t * pool,const char * name,unsigned clock_rate,unsigned samples_per_frame,unsigned channel_count,unsigned max_delay,unsigned options,pjmedia_delay_buf ** p_b)89 PJ_DEF(pj_status_t) pjmedia_delay_buf_create( pj_pool_t *pool,
90 					      const char *name,
91 					      unsigned clock_rate,
92 					      unsigned samples_per_frame,
93 					      unsigned channel_count,
94 					      unsigned max_delay,
95 					      unsigned options,
96 					      pjmedia_delay_buf **p_b)
97 {
98     pjmedia_delay_buf *b;
99     pj_status_t status;
100 
101     PJ_ASSERT_RETURN(pool && samples_per_frame && clock_rate && channel_count &&
102 		     p_b, PJ_EINVAL);
103 
104     if (!name) {
105 	name = "delaybuf";
106     }
107 
108     b = PJ_POOL_ZALLOC_T(pool, pjmedia_delay_buf);
109 
110     pj_ansi_strncpy(b->obj_name, name, PJ_MAX_OBJ_NAME-1);
111 
112     b->samples_per_frame = samples_per_frame;
113     b->channel_count = channel_count;
114     b->ptime = samples_per_frame * 1000 / clock_rate / channel_count;
115     if (max_delay < b->ptime)
116 	max_delay = PJ_MAX(DEFAULT_MAX_DELAY, b->ptime);
117 
118     b->max_cnt = samples_per_frame * max_delay / b->ptime;
119     b->eff_cnt = b->max_cnt >> 1;
120     b->recalc_timer = RECALC_TIME;
121 
122     /* Create circular buffer */
123     status = pjmedia_circ_buf_create(pool, b->max_cnt, &b->circ_buf);
124     if (status != PJ_SUCCESS)
125 	return status;
126 
127     if (!(options & PJMEDIA_DELAY_BUF_SIMPLE_FIFO)) {
128         /* Create WSOLA */
129         status = pjmedia_wsola_create(pool, clock_rate, samples_per_frame, 1,
130 				      PJMEDIA_WSOLA_NO_FADING, &b->wsola);
131         if (status != PJ_SUCCESS)
132 	    return status;
133         PJ_LOG(5, (b->obj_name, "Using delay buffer with WSOLA."));
134     } else {
135         PJ_LOG(5, (b->obj_name, "Using simple FIFO delay buffer."));
136     }
137 
138     /* Finally, create mutex */
139     status = pj_lock_create_recursive_mutex(pool, b->obj_name,
140 					    &b->lock);
141     if (status != PJ_SUCCESS)
142 	return status;
143 
144     *p_b = b;
145 
146     TRACE__((b->obj_name,"Delay buffer created"));
147 
148     return PJ_SUCCESS;
149 }
150 
pjmedia_delay_buf_destroy(pjmedia_delay_buf * b)151 PJ_DEF(pj_status_t) pjmedia_delay_buf_destroy(pjmedia_delay_buf *b)
152 {
153     pj_status_t status = PJ_SUCCESS;
154 
155     PJ_ASSERT_RETURN(b, PJ_EINVAL);
156 
157     pj_lock_acquire(b->lock);
158 
159     if (b->wsola) {
160         status = pjmedia_wsola_destroy(b->wsola);
161         if (status == PJ_SUCCESS)
162 	    b->wsola = NULL;
163     }
164 
165     pj_lock_release(b->lock);
166 
167     pj_lock_destroy(b->lock);
168     b->lock = NULL;
169 
170     return status;
171 }
172 
173 /* This function will erase samples from delay buffer.
174  * The number of erased samples is guaranteed to be >= erase_cnt.
175  */
shrink_buffer(pjmedia_delay_buf * b,unsigned erase_cnt)176 static void shrink_buffer(pjmedia_delay_buf *b, unsigned erase_cnt)
177 {
178     pj_int16_t *buf1, *buf2;
179     unsigned buf1len;
180     unsigned buf2len;
181     pj_status_t status;
182 
183     pj_assert(b && erase_cnt && pjmedia_circ_buf_get_len(b->circ_buf));
184 
185     pjmedia_circ_buf_get_read_regions(b->circ_buf, &buf1, &buf1len,
186 				      &buf2, &buf2len);
187     status = pjmedia_wsola_discard(b->wsola, buf1, buf1len, buf2, buf2len,
188 				   &erase_cnt);
189 
190     if ((status == PJ_SUCCESS) && (erase_cnt > 0)) {
191 	/* WSOLA discard will manage the first buffer to be full, unless
192 	 * erase_cnt is greater than second buffer length. So it is safe
193 	 * to just set the circular buffer length.
194 	 */
195 
196 	pjmedia_circ_buf_set_len(b->circ_buf,
197 				 pjmedia_circ_buf_get_len(b->circ_buf) -
198 				 erase_cnt);
199 
200 	PJ_LOG(5,(b->obj_name,"%d samples reduced, buf_cnt=%d",
201 	       erase_cnt, pjmedia_circ_buf_get_len(b->circ_buf)));
202     }
203 }
204 
205 /* Fast increase, slow decrease */
206 #define AGC_UP(cur, target) cur = (cur + target*3) >> 2
207 #define AGC_DOWN(cur, target) cur = (cur*3 + target) >> 2
208 #define AGC(cur, target) \
209     if (cur < target) AGC_UP(cur, target); \
210     else AGC_DOWN(cur, target)
211 
update(pjmedia_delay_buf * b,enum OP op)212 static void update(pjmedia_delay_buf *b, enum OP op)
213 {
214     /* Sequential operation */
215     if (op == b->last_op) {
216 	++b->level;
217 	return;
218     }
219 
220     /* Switching operation */
221     if (b->level > b->max_level)
222 	b->max_level = b->level;
223 
224     b->recalc_timer -= (b->level * b->ptime) >> 1;
225 
226     b->last_op = op;
227     b->level = 1;
228 
229     /* Recalculate effective count based on max_level */
230     if (b->recalc_timer <= 0) {
231 	unsigned new_eff_cnt = (b->max_level+SAFE_MARGIN)*b->samples_per_frame;
232 
233 	/* Smoothening effective count transition */
234 	AGC(b->eff_cnt, new_eff_cnt);
235 
236 	/* Make sure the new effective count is multiplication of
237 	 * channel_count, so let's round it up.
238 	 */
239 	if (b->eff_cnt % b->channel_count)
240 	    b->eff_cnt += b->channel_count - (b->eff_cnt % b->channel_count);
241 
242 	TRACE__((b->obj_name,"Cur eff_cnt=%d", b->eff_cnt));
243 
244 	b->max_level = 0;
245 	b->recalc_timer = RECALC_TIME;
246     }
247 
248     /* See if we need to shrink the buffer to reduce delay */
249     if (op == OP_PUT && pjmedia_circ_buf_get_len(b->circ_buf) >
250 	b->samples_per_frame + b->eff_cnt)
251     {
252 	unsigned erase_cnt = b->samples_per_frame >> 1;
253 	unsigned old_buf_cnt = pjmedia_circ_buf_get_len(b->circ_buf);
254 
255 	shrink_buffer(b, erase_cnt);
256 	PJ_LOG(4,(b->obj_name,"Buffer size adjusted from %d to %d (eff_cnt=%d)",
257 	          old_buf_cnt,
258 		  pjmedia_circ_buf_get_len(b->circ_buf),
259 		  b->eff_cnt));
260     }
261 }
262 
pjmedia_delay_buf_put(pjmedia_delay_buf * b,pj_int16_t frame[])263 PJ_DEF(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
264 					   pj_int16_t frame[])
265 {
266     pj_status_t status;
267 
268     PJ_ASSERT_RETURN(b && frame, PJ_EINVAL);
269 
270     pj_lock_acquire(b->lock);
271 
272     if (b->wsola) {
273         update(b, OP_PUT);
274 
275         status = pjmedia_wsola_save(b->wsola, frame, PJ_FALSE);
276         if (status != PJ_SUCCESS) {
277 	    pj_lock_release(b->lock);
278 	    return status;
279         }
280     }
281 
282     /* Overflow checking */
283     if (pjmedia_circ_buf_get_len(b->circ_buf) + b->samples_per_frame >
284 	b->max_cnt)
285     {
286 	unsigned erase_cnt;
287 
288         if (b->wsola) {
289 	    /* shrink one frame or just the diff? */
290 	    //erase_cnt = b->samples_per_frame;
291 	    erase_cnt = pjmedia_circ_buf_get_len(b->circ_buf) +
292 		        b->samples_per_frame - b->max_cnt;
293 
294 	    shrink_buffer(b, erase_cnt);
295         }
296 
297 	/* Check if shrinking failed or erased count is less than requested,
298 	 * delaybuf needs to drop eldest samples, this is bad since the voice
299 	 * samples get rough transition which may produce tick noise.
300 	 */
301 	if (pjmedia_circ_buf_get_len(b->circ_buf) + b->samples_per_frame >
302 	    b->max_cnt)
303 	{
304 	    erase_cnt = pjmedia_circ_buf_get_len(b->circ_buf) +
305 			b->samples_per_frame - b->max_cnt;
306 
307 	    pjmedia_circ_buf_adv_read_ptr(b->circ_buf, erase_cnt);
308 
309 	    PJ_LOG(4,(b->obj_name,"%sDropping %d eldest samples, buf_cnt=%d",
310                       (b->wsola? "Shrinking failed or insufficient. ": ""),
311                       erase_cnt, pjmedia_circ_buf_get_len(b->circ_buf)));
312 	}
313     }
314 
315     pjmedia_circ_buf_write(b->circ_buf, frame, b->samples_per_frame);
316 
317     pj_lock_release(b->lock);
318     return PJ_SUCCESS;
319 }
320 
pjmedia_delay_buf_get(pjmedia_delay_buf * b,pj_int16_t frame[])321 PJ_DEF(pj_status_t) pjmedia_delay_buf_get( pjmedia_delay_buf *b,
322 					   pj_int16_t frame[])
323 {
324     pj_status_t status = PJ_SUCCESS;
325 
326     PJ_ASSERT_RETURN(b && frame, PJ_EINVAL);
327 
328     pj_lock_acquire(b->lock);
329 
330     if (b->wsola)
331         update(b, OP_GET);
332 
333     /* Starvation checking */
334     if (pjmedia_circ_buf_get_len(b->circ_buf) < b->samples_per_frame) {
335 
336 	PJ_LOG(4,(b->obj_name,"Underflow, buf_cnt=%d, will generate 1 frame",
337 		  pjmedia_circ_buf_get_len(b->circ_buf)));
338 
339         if (b->wsola) {
340             status = pjmedia_wsola_generate(b->wsola, frame);
341 
342 	    if (status == PJ_SUCCESS) {
343 	        TRACE__((b->obj_name,"Successfully generate 1 frame"));
344 	        if (pjmedia_circ_buf_get_len(b->circ_buf) == 0) {
345 		    pj_lock_release(b->lock);
346 		    return PJ_SUCCESS;
347 	        }
348 
349 	        /* Put generated frame into buffer */
350 	        pjmedia_circ_buf_write(b->circ_buf, frame,
351                                        b->samples_per_frame);
352             }
353         }
354 
355 	if (!b->wsola || status != PJ_SUCCESS) {
356 	    unsigned buf_len = pjmedia_circ_buf_get_len(b->circ_buf);
357 
358 	    /* Give all what delay buffer has, then pad with zeroes */
359             if (b->wsola)
360 	        PJ_PERROR(4,(b->obj_name, status, "Error generating frame"));
361 
362 	    pjmedia_circ_buf_read(b->circ_buf, frame, buf_len);
363 	    pjmedia_zero_samples(&frame[buf_len],
364 				 b->samples_per_frame - buf_len);
365 
366 	    /* The buffer is empty now, reset it */
367 	    pjmedia_circ_buf_reset(b->circ_buf);
368 
369 	    pj_lock_release(b->lock);
370 
371 	    return PJ_SUCCESS;
372 	}
373     }
374 
375     pjmedia_circ_buf_read(b->circ_buf, frame, b->samples_per_frame);
376 
377     pj_lock_release(b->lock);
378 
379     return PJ_SUCCESS;
380 }
381 
382 
pjmedia_delay_buf_reset(pjmedia_delay_buf * b)383 PJ_DEF(pj_status_t) pjmedia_delay_buf_reset(pjmedia_delay_buf *b)
384 {
385     PJ_ASSERT_RETURN(b, PJ_EINVAL);
386 
387     pj_lock_acquire(b->lock);
388 
389     b->recalc_timer = RECALC_TIME;
390 
391     /* Reset buffer */
392     pjmedia_circ_buf_reset(b->circ_buf);
393 
394     /* Reset WSOLA */
395     if (b->wsola)
396         pjmedia_wsola_reset(b->wsola, 0);
397 
398     pj_lock_release(b->lock);
399 
400     PJ_LOG(5,(b->obj_name,"Delay buffer is reset"));
401 
402     return PJ_SUCCESS;
403 }
404 
405