blob: 02e6d92f835174fb3fe92af1ab177f86ec48026b [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2005
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*****************************************************************************
37 *
38 * Filename:
39 * ---------
40 * PCMRB.c
41 *
42 * Project:
43 * --------
44 * Maui_sw
45 *
46 * Description:
47 * ------------
48 * PCMRB interface and driver, providing pcm ring buffer utility
49 *
50 * Author:
51 * -------
52 * -------
53 *============================================================================
54 * HISTORY
55 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
56 *------------------------------------------------------------------------------
57 * removed!
58 * removed!
59 * removed!
60 *
61 * removed!
62 * removed!
63 * removed!
64 *
65 * removed!
66 * removed!
67 * removed!
68 *
69 * removed!
70 * removed!
71 *
72 * removed!
73 * removed!
74 * removed!
75 *
76 * removed!
77 * removed!
78 * removed!
79 *
80 * removed!
81 * removed!
82 * removed!
83 *
84 * removed!
85 * removed!
86 * removed!
87 *
88 * removed!
89 * removed!
90 * removed!
91 *
92 * removed!
93 * removed!
94 * removed!
95 *
96 * removed!
97 * removed!
98 * removed!
99 *
100 * removed!
101 * removed!
102 * removed!
103 *
104 *
105 *------------------------------------------------------------------------------
106 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
107 *============================================================================
108 ****************************************************************************/
109
110/*****************************************************************************
111* C O M P I L E R F L A G S
112******************************************************************************
113*/
114
115/*****************************************************************************
116* E X T E R N A L R E F E R E N C E S
117******************************************************************************
118*/
119#include "kal_public_api.h"
120#include "sync_data.h"
121//#include "kal_non_specific_general_types.h"
122//#include "kal_release.h"
123#include "string.h"
124
125#include "l1aud_common_def.h"
126#include "pcmrb.h"
127/*****************************************************************************
128* C O N S T A N T S
129******************************************************************************
130*/
131
132/*****************************************************************************
133* D A T A T Y P E S
134******************************************************************************
135*/
136
137/*****************************************************************************
138* P U B L I C D A T A
139******************************************************************************
140*/
141
142/*****************************************************************************
143* P R I V A T E D A T A
144******************************************************************************
145*/
146
147/*****************************************************************************
148* M A C R O S
149******************************************************************************
150*/
151
152/*****************************************************************************
153* F U N C T I O N D E C L A R A T I O N S
154******************************************************************************
155*/
156
157/*****************************************************************************
158* F U N C T I O N S
159******************************************************************************
160*/
161
162__inline int16 pcm_add( int32 x, int32 y )
163{
164#if defined(__TARGET_FEATURE_DSPMUL)
165 int32 xs, ys, rs;
166 __asm {
167 mov xs, x, lsl #16;
168 mov ys, y, lsl #16;
169 qadd rs, xs, ys;
170 }
171 return (int16)(rs >> 16);
172#else
173 x = x + y;
174 if( x>32767 )
175 x = 32767;
176 else if( x< -32768 )
177 x = -32768;
178
179 return (int16)x;
180#endif
181}
182
183void pcm_mix_n( int16 *dest, int16 *src, int32 n )
184{
185 do {
186 int32 x = *dest;
187 int32 y = *src++;
188 *dest++ = pcm_add( x, y );
189 } while( --n>0 );
190}
191
192/*
193 * Description
194 * ---------
195 * The function initializes the ring buffer instance.
196 *
197 * Syntax
198 * ---------
199 * bool PCMRB_Init( PCMRB *rb, int16 *buffer, int32 buffer_size )
200 *
201 * where
202 * rb The ring buffer instance
203 * buffer Address of the memory allocated for the ring buffer
204 * buffer_size Size of the memory allocated for the ring buffer
205 *
206 * Return Value
207 * ---------
208 * true
209 * false
210 */
211bool PCMRB_Init( PCMRB *rb, int16 *buffer, int32 buffer_size )
212{
213 ASSERT( rb!=NULL );
214
215 memset( buffer, 0, buffer_size*sizeof(int16) );
216 rb->buffer = buffer;
217 rb->size = buffer_size;
218 rb->read = 0;
219 rb->write = 0;
220
221 return true;
222}
223
224/*
225 * Description
226 * ---------
227 * The function returns the available free space of the ring buffer instance.
228 *
229 * Syntax
230 * ---------
231 * int32 PCMRB_GetFreeSpace( PCMRB *rb )
232 *
233 * where
234 * rb The ring buffer instance
235 *
236 * Return Value
237 * ---------
238 * the free space in words
239 */
240int32 PCMRB_GetFreeSpace( PCMRB *rb )
241{
242 int32 count;
243
244 ASSERT( rb!=NULL );
245
246 count = rb->read - rb->write - 1;
247 if( 0>count )
248 count += rb->size;
249 return count;
250}
251
252/*
253 * Description
254 * ---------
255 * The function returns available data count of the ring buffer instance
256 *
257 * Syntax
258 * ---------
259 * int32 PCMRB_GetDataCount( PCMRB *rb )
260 *
261 * where
262 * rb The ring buffer instance
263 *
264 * Return Value
265 * ---------
266 * the data count in words
267 */
268int32 PCMRB_GetDataCount( PCMRB *rb )
269{
270 int32 count;
271
272 ASSERT( rb!=NULL );
273
274 count = rb->write - rb->read;
275 if( 0>count )
276 count += rb->size;
277 return count;
278}
279
280/*
281 * Description
282 * ---------
283 * The function copies data from a linear array to a ring buffer instance.
284 * The free space of the ring buffer instance shall be enough, or assertion will happen
285 *
286 * Syntax
287 * ---------
288 * void PCMRB_Write( PCMRB *dest_rb, int16 *src_buffer, int32 size )
289 *
290 * where
291 * dest_rb The ring buffer instance
292 * src_buffer Address of the linear array
293 * size Size of copy
294 *
295 * Return Value
296 * ---------
297 * none
298 */
299void PCMRB_Write( PCMRB *dest_rb, int16 *src_buffer, int32 size )
300{
301 int16 *write_ptr;
302 int32 write_cnt;
303/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write size=%d",size);
304 ASSERT( dest_rb!=NULL );
305 ASSERT( PCMRB_GetFreeSpace( dest_rb )>=size );
306
307 PCMRB_GetWriteBlock( dest_rb, &write_ptr, &write_cnt );
308 if( write_cnt>size ) write_cnt = size;
309
310 if( src_buffer == (int16 *)NULL ){
311 memset( write_ptr, 0, write_cnt*sizeof(int16) );
312/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write Null");
313 }else{
314 memcpy( write_ptr, src_buffer, write_cnt*sizeof(int16) );
315/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write %x %x %x %x", write_ptr, *(src_buffer+0),*(src_buffer+1),*(src_buffer+2));
316 }
317
318 PCMRB_ShiftWritePointer( dest_rb, write_cnt );
319 size -= write_cnt;
320
321 if( size>0 )
322 {
323 if( src_buffer != (int16 *)NULL ) src_buffer += write_cnt;
324
325 PCMRB_GetWriteBlock( dest_rb, &write_ptr, &write_cnt );
326 if( write_cnt>size ) write_cnt = size;
327
328 if( src_buffer == (int16 *)NULL ) memset( write_ptr, 0, write_cnt*sizeof(int16) );
329 else memcpy( write_ptr, src_buffer, write_cnt*sizeof(int16) );
330
331 PCMRB_ShiftWritePointer( dest_rb, write_cnt );
332 }
333}
334
335//fsju
336void PCMRB_Write_from_DSP( PCMRB *dest_rb, volatile uint16 *src_buffer, int32 size )
337{
338 int16 *write_ptr;
339 int32 write_cnt;
340 int32 i;
341/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write size=%d",size);
342 ASSERT( dest_rb!=NULL );
343 ASSERT( PCMRB_GetFreeSpace( dest_rb )>=size );
344
345 PCMRB_GetWriteBlock( dest_rb, &write_ptr, &write_cnt );
346 if( write_cnt>size ) write_cnt = size;
347
348 if( src_buffer == (volatile uint16 *)NULL ){
349 memset( write_ptr, 0, write_cnt*sizeof(int16) );
350/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write Null");
351 }else{
352 //memcpy( write_ptr, src_buffer, write_cnt*sizeof(int16) );
353 for(i=0; i<write_cnt; i++)
354 {
355 write_ptr[i] = src_buffer[i];
356 }
357/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write %x %x %x %x", write_ptr, *(src_buffer+0),*(src_buffer+1),*(src_buffer+2));
358 }
359
360 PCMRB_ShiftWritePointer( dest_rb, write_cnt );
361 size -= write_cnt;
362
363 if( size>0 )
364 {
365 if( src_buffer != (volatile uint16 *)NULL ) src_buffer += write_cnt;
366
367 PCMRB_GetWriteBlock( dest_rb, &write_ptr, &write_cnt );
368 if( write_cnt>size ) write_cnt = size;
369
370 if( src_buffer == (volatile uint16 *)NULL )
371 {
372 memset( write_ptr, 0, write_cnt*sizeof(int16) );
373 }
374 else
375 {
376 //memcpy( write_ptr, src_buffer, write_cnt*sizeof(int16) );
377 for(i=0; i<write_cnt; i++)
378 {
379 write_ptr[i] = src_buffer[i];
380 }
381 }
382
383 PCMRB_ShiftWritePointer( dest_rb, write_cnt );
384 }
385}
386
387//fsju, for test, should remove
388void PCMRB_Write2( PCMRB *dest_rb, int16 *src_buffer, int32 size )
389{
390 int16 *write_ptr;
391 int32 write_cnt;
392 int32 i;
393 static short test_val = 0;
394/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write size=%d",size);
395 ASSERT( dest_rb!=NULL );
396 ASSERT( PCMRB_GetFreeSpace( dest_rb )>=size );
397
398 PCMRB_GetWriteBlock( dest_rb, &write_ptr, &write_cnt );
399 if( write_cnt>size ) write_cnt = size;
400
401 if( src_buffer == (int16 *)NULL ){
402 memset( write_ptr, 0, write_cnt*sizeof(int16) );
403/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write Null");
404 }else{
405 //memcpy( write_ptr, src_buffer, write_cnt*sizeof(int16) );
406 for(i=0; i<write_cnt; i++)
407 {
408 write_ptr[i] = test_val;
409 test_val++;
410 }
411/// kal_prompt_trace(MOD_L1SP, "PCMRB_Write %x %x %x %x", write_ptr, *(src_buffer+0),*(src_buffer+1),*(src_buffer+2));
412 }
413
414 PCMRB_ShiftWritePointer( dest_rb, write_cnt );
415 size -= write_cnt;
416
417 if( size>0 )
418 {
419 if( src_buffer != (int16 *)NULL ) src_buffer += write_cnt;
420
421 PCMRB_GetWriteBlock( dest_rb, &write_ptr, &write_cnt );
422 if( write_cnt>size ) write_cnt = size;
423
424 if( src_buffer == (int16 *)NULL )
425 {
426 memset( write_ptr, 0, write_cnt*sizeof(int16) );
427 }
428 else
429 {
430 //memcpy( write_ptr, src_buffer, write_cnt*sizeof(int16) );
431 for(i=0; i<write_cnt; i++)
432 {
433 write_ptr[i] = test_val;
434 test_val++;
435 }
436 }
437
438 PCMRB_ShiftWritePointer( dest_rb, write_cnt );
439 }
440}
441//fsju add end
442
443/*
444 * Description
445 * ---------
446 * The function copies data from a ring buffer instance to a linear array
447 * The data count of the ring buffer instance shall be enough, or assertion will happen
448 *
449 * Syntax
450 * ---------
451 * void PCMRB_Read( PCMRB *src_rb, int16 *dest_buffer, int32 size )
452 *
453 * where
454 * src_rb The ring buffer instance
455 * dest_buffer Address of the linear array
456 * size Size of copy
457 *
458 * Return Value
459 * ---------
460 * none
461 */
462void PCMRB_Read( PCMRB *src_rb, int16 *dest_buffer, int32 size )
463{
464 int16 *read_ptr;
465 int32 read_cnt;
466/// kal_prompt_trace(MOD_L1SP, "PCMRB_Read size=%d",size);
467 ASSERT( src_rb!=NULL );
468 ASSERT( PCMRB_GetDataCount( src_rb )>=size );
469
470 PCMRB_GetReadBlock( src_rb, &read_ptr, &read_cnt );
471 if( read_cnt>size ) read_cnt = size;
472 memcpy( dest_buffer, read_ptr, read_cnt*sizeof(int16) );
473 PCMRB_ShiftReadPointer( src_rb, read_cnt );
474 size -= read_cnt;
475
476 if( size>0 )
477 {
478 dest_buffer += read_cnt;
479 PCMRB_GetReadBlock( src_rb, &read_ptr, &read_cnt );
480 if( read_cnt>size ) read_cnt = size;
481 memcpy( dest_buffer, read_ptr, read_cnt*sizeof(int16) );
482 PCMRB_ShiftReadPointer( src_rb, read_cnt );
483 }
484}
485
486//fsju
487void PCMRB_Read_to_DSP( PCMRB *src_rb, volatile uint16 *dest_buffer, int32 size )
488{
489#if 0
490/* under construction !*/
491/* under construction !*/
492/* under construction !*/
493/* under construction !*/
494/* under construction !*/
495/* under construction !*/
496/* under construction !*/
497/* under construction !*/
498/* under construction !*/
499/* under construction !*/
500/* under construction !*/
501/* under construction !*/
502/* under construction !*/
503/* under construction !*/
504/* under construction !*/
505/* under construction !*/
506/* under construction !*/
507/* under construction !*/
508/* under construction !*/
509/* under construction !*/
510/* under construction !*/
511/* under construction !*/
512/* under construction !*/
513/* under construction !*/
514/* under construction !*/
515/* under construction !*/
516/* under construction !*/
517/* under construction !*/
518/* under construction !*/
519/* under construction !*/
520#else //#if 0
521 int16 *read_ptr;
522 int32 read_cnt;
523 int32 i;
524 //volatile uint16* ptr_dest_buffer = dest_buffer;
525/// kal_prompt_trace(MOD_L1SP, "PCMRB_Read size=%d",size);
526 ASSERT( src_rb!=NULL );
527 ASSERT( PCMRB_GetDataCount( src_rb )>=size );
528
529 PCMRB_GetReadBlock( src_rb, &read_ptr, &read_cnt );
530 if( read_cnt>size ) read_cnt = size;
531 //memcpy( dest_buffer, read_ptr, read_cnt*sizeof(int16) );
532 for(i=0; i<read_cnt; i++)
533 {
534 dest_buffer[i] = read_ptr[i];
535 }
536 PCMRB_ShiftReadPointer( src_rb, read_cnt );
537 size -= read_cnt;
538
539 if( size>0 )
540 {
541 dest_buffer += read_cnt;
542 PCMRB_GetReadBlock( src_rb, &read_ptr, &read_cnt );
543 if( read_cnt>size ) read_cnt = size;
544 //memcpy( dest_buffer, read_ptr, read_cnt*sizeof(int16) );
545 for(i=0; i<read_cnt; i++)
546 {
547 dest_buffer[i] = read_ptr[i];
548 }
549 PCMRB_ShiftReadPointer( src_rb, read_cnt );
550 }
551
552 Data_Sync_Barrier();
553#endif //#if 0
554}
555
556
557void PCMRB_Read_to_DSP_Padding( PCMRB *src_rb, volatile uint16 *dest_buffer, int32 size )
558{
559 int16 *read_ptr;
560 int32 read_cnt;
561 int32 i;
562 //32k 20ms
563 uint32 buffered_data[640/sizeof(uint32)];
564 int32 read_cnt_total;
565
566 ASSERT( src_rb!=NULL );
567 //ASSERT( PCMRB_GetDataCount( src_rb )>=size );
568
569 PCMRB_GetReadBlock( src_rb, &read_ptr, &read_cnt );
570 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding1: read_cnt=%d, size=%d", read_cnt, size);
571 if( read_cnt>size ) read_cnt = size;
572 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding1: read_cnt=%d, size=%d", read_cnt, size);
573 for(i=0; i<read_cnt; i++)
574 {
575 dest_buffer[i] = read_ptr[i];
576 buffered_data[i] = read_ptr[i];
577 }
578 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding1: src_rb->read=%d, src_rb->write=%d", src_rb->read, src_rb->write);
579 PCMRB_ShiftReadPointer( src_rb, read_cnt );
580 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding1: src_rb->read=%d, src_rb->write=%d", src_rb->read, src_rb->write);
581 size -= read_cnt;
582 dest_buffer += read_cnt;
583 read_cnt_total = read_cnt;
584
585 if( size>0 )
586 {
587 PCMRB_GetReadBlock( src_rb, &read_ptr, &read_cnt );
588 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding2: read_cnt=%d, size=%d", read_cnt, size);
589 if( read_cnt>size ) read_cnt = size;
590 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding2: read_cnt=%d, size=%d", read_cnt, size);
591 for(i=0; i<read_cnt; i++)
592 {
593 dest_buffer[i] = read_ptr[i];
594 buffered_data[i+read_cnt_total] = read_ptr[i];
595 }
596 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding2: src_rb->read=%d, src_rb->write=%d", src_rb->read, src_rb->write);
597 PCMRB_ShiftReadPointer( src_rb, read_cnt );
598 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding2: src_rb->read=%d, src_rb->write=%d", src_rb->read, src_rb->write);
599 size -= read_cnt;
600 dest_buffer += read_cnt;
601 read_cnt_total += read_cnt;
602 }
603
604 //padding
605 while(size > 0)
606 {
607 read_cnt = read_cnt_total;
608 //kal_prompt_trace(MOD_L1SP, "PCMRB_Read_to_DSP_Padding3: read_cnt=%d, size=%d", read_cnt, size);
609 if(read_cnt > size)
610 {
611 read_cnt = size;
612 }
613 for(i=0; i<read_cnt; i++)
614 {
615 dest_buffer[i] = buffered_data[i];
616 }
617 size -= read_cnt;
618 dest_buffer += read_cnt;
619 }
620
621 Data_Sync_Barrier();
622}
623
624
625void PCMRB_ShiftReadPointer2( PCMRB *src_rb, int32 size )
626{
627 int16 *read_ptr;
628 int32 read_cnt;
629
630 ASSERT( src_rb!=NULL );
631 ASSERT( PCMRB_GetDataCount( src_rb )>=size );
632
633 PCMRB_GetReadBlock( src_rb, &read_ptr, &read_cnt );
634 if( read_cnt>size ) read_cnt = size;
635 //memcpy( dest_buffer, read_ptr, read_cnt*sizeof(int16) );
636 PCMRB_ShiftReadPointer( src_rb, read_cnt );
637 size -= read_cnt;
638
639 if( size>0 )
640 {
641 //dest_buffer += read_cnt;
642 PCMRB_GetReadBlock( src_rb, &read_ptr, &read_cnt );
643 if( read_cnt>size ) read_cnt = size;
644 // memcpy( dest_buffer, read_ptr, read_cnt*sizeof(int16) );
645 PCMRB_ShiftReadPointer( src_rb, read_cnt );
646 }
647}
648/*
649 * Description
650 * ---------
651 * The function returns the linear write block and its size of a ring buffer instance
652 *
653 * Syntax
654 * ---------
655 * void PCMRB_GetWriteBlock( PCMRB *dest_rb, int16 **write_ptr, int32 *write_cnt )
656 *
657 * where
658 * dest_rb The ring buffer instance
659 * write_ptr Address of the memory to put the address of the linear write block
660 * write_cnt Address of the memory to put the size of the linear write block
661 *
662 * Return Value
663 * ---------
664 * none
665 */
666void PCMRB_GetWriteBlock( PCMRB *dest_rb, int16 **write_ptr, int32 *write_cnt )
667{
668 int32 cnt;
669
670 ASSERT( (dest_rb!=NULL) && (write_ptr!=NULL) && (write_cnt!=NULL) );
671
672 if( dest_rb->read>dest_rb->write )
673 cnt = dest_rb->read - dest_rb->write - 1;
674 else if( dest_rb->read==0 )
675 cnt = dest_rb->size - dest_rb->write - 1;
676 else
677 cnt = dest_rb->size - dest_rb->write;
678
679 *write_cnt = cnt;
680 *write_ptr = &dest_rb->buffer[dest_rb->write];
681}
682
683/*
684 * Description
685 * ---------
686 * The function returns the linear read block and its size of a ring buffer instance
687 *
688 * Syntax
689 * ---------
690 * void PCMRB_GetReadBlock( PCMRB *src_rb, int16 **read_ptr, int32 *read_cnt )
691 *
692 * where
693 * src_rb The ring buffer instance
694 * read_ptr Address of the memory to put the address of the linear read block
695 * read_cnt Address of the memory to put the size of the linear read block
696 *
697 * Return Value
698 * ---------
699 * none
700 */
701void PCMRB_GetReadBlock( PCMRB *src_rb, int16 **read_ptr, int32 *read_cnt )
702{
703 int32 cnt;
704
705 ASSERT( (src_rb!=NULL) && (read_ptr!=NULL) && (read_cnt!=NULL) );
706
707 if( src_rb->write == src_rb->read )
708 cnt = 0;
709 else if( src_rb->write>src_rb->read )
710 cnt = src_rb->write - src_rb->read;
711 else
712 cnt = src_rb->size - src_rb->read;
713
714 *read_cnt = cnt;
715 *read_ptr = &src_rb->buffer[src_rb->read];
716}
717
718
719/*
720 * Description
721 * ---------
722 * The function shifts the write pointer of a ring buffer instance in circular way
723 * Use this with PCMRB_GetWriteBlock
724 *
725 * Syntax
726 * ---------
727 * void PCMRB_ShiftWritePointer( PCMRB *rb, int32 shamt )
728 *
729 * where
730 * rb The ring buffer instance
731 * shamt shift amount
732 *
733 * Return Value
734 * ---------
735 * none
736 */
737void PCMRB_ShiftWritePointer( PCMRB *rb, int32 shamt )
738{
739 ASSERT( rb!=NULL );
740
741 rb->write += shamt;
742 if( rb->write>=rb->size )
743 rb->write -= rb->size;
744}
745
746/*
747 * Description
748 * ---------
749 * The function shifts the read pointer of a ring buffer instance in circular way
750 * Use this with PCMRB_GetReadBlock
751 *
752 * Syntax
753 * ---------
754 * void PCMRB_ShiftReadPointer( PCMRB *rb, int32 shamt )
755 *
756 * where
757 * rb The ring buffer instance
758 * shamt shift amount
759 *
760 * Return Value
761 * ---------
762 * none
763 */
764void PCMRB_ShiftReadPointer( PCMRB *rb, int32 shamt )
765{
766 ASSERT( rb!=NULL );
767
768 rb->read += shamt;
769 if( rb->read>=rb->size )
770 rb->read -= rb->size;
771}
772
773/*
774 * Description
775 * ---------
776 * The function mixes two ring buffer instance without shift their pointers
777 *
778 * Syntax
779 * ---------
780 * void PCMRB_Mix( PCMRB *dest_rb, PCMRB *src_rb )
781 *
782 * where
783 * dest_rb One of the input ring buffer, also the output ring buffer
784 * src_rb One of the input ring buffer
785 *
786 * Return Value
787 * ---------
788 * none
789 */
790 void PCMRB_Mix( PCMRB *dest_rb, PCMRB *src_rb, int32 size )
791{
792 int32 dest_rb_write, src_rb_read;
793
794 ASSERT( dest_rb!=NULL );
795 ASSERT( src_rb!=NULL );
796 ASSERT( PCMRB_GetFreeSpace( dest_rb )>=size );
797 ASSERT( PCMRB_GetDataCount( src_rb )>=size );
798
799 dest_rb_write = dest_rb->write;
800 src_rb_read = src_rb->read;
801 while( 1 )
802 {
803 int32 cnt_write, cnt_read;
804 int16 *dest_rb_buf, *src_rb_buf;
805 int32 cnt;
806 if( src_rb->write>src_rb_read )
807 cnt_read = src_rb->write - src_rb_read;
808 else
809 cnt_read = src_rb->size - src_rb_read;
810 if( dest_rb->read>dest_rb_write )
811 cnt_write = dest_rb->read - dest_rb_write;
812 else
813 cnt_write = dest_rb->size - dest_rb_write;
814 cnt = (cnt_read<cnt_write)? cnt_read: cnt_write;
815 if( cnt>size ) cnt = size;
816
817 dest_rb_buf = dest_rb->buffer + dest_rb_write;
818 src_rb_buf = src_rb->buffer + src_rb_read;
819
820 pcm_mix_n( dest_rb_buf, src_rb_buf, cnt );
821
822 size -= cnt;
823 if( size==0 )
824 break;
825
826 dest_rb_write += cnt;
827 if( dest_rb_write==dest_rb->size )
828 dest_rb_write = 0;
829 src_rb_read += cnt;
830 if( src_rb_read==src_rb->size )
831 src_rb_read = 0;
832 }
833
834}
835
836