Mercurial > SDL_sound_CoreAudio
comparison alt_audio_convert.c @ 365:f61eadea1f44
More revisions from Frank.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Tue, 18 Jun 2002 21:49:44 +0000 |
parents | c984aa6990f7 |
children | eda146d666d1 |
comparison
equal
deleted
inserted
replaced
364:4bcbc442d145 | 365:f61eadea1f44 |
---|---|
1 /* | 1 /* |
2 Extended Audio Converter for SDL (Simple DirectMedia Layer) | 2 * Extended Audio Converter for SDL (Simple DirectMedia Layer) |
3 Copyright (C) 2002 Frank Ranostaj | 3 * Copyright (C) 2002 Frank Ranostaj |
4 Institute of Applied Physik | 4 * Institute of Applied Physik |
5 Johann Wolfgang Goethe-Universität | 5 * Johann Wolfgang Goethe-Universität |
6 Frankfurt am Main, Germany | 6 * Frankfurt am Main, Germany |
7 | 7 * |
8 This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
11 version 2 of the License, or (at your option) any later version. | 11 * version 2 of the License, or (at your option) any later version. |
12 | 12 * |
13 This library is distributed in the hope that it will be useful, | 13 * This library is distributed in the hope that it will be useful, |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 Library General Public License for more details. | 16 * Library General Public License for more details. |
17 | 17 * |
18 You should have received a copy of the GNU Library General Public | 18 * You should have received a copy of the GNU Library General Public |
19 License along with this library; if not, write to the Free | 19 * License along with this library; if not, write to the Free |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | 21 * |
22 Frank Ranostaj | 22 * Frank Ranostaj |
23 ranostaj@stud.uni-frankfurt.de | 23 * ranostaj@stud.uni-frankfurt.de |
24 | 24 * |
25 (This code blatantly abducted for SDL_sound. Thanks, Frank! --ryan.) | 25 * (This code blatantly abducted for SDL_sound. Thanks, Frank! --ryan.) |
26 | 26 */ |
27 */ | 27 |
28 #include "alt_audio_convert.h" | 28 #include "alt_audio_convert.h" |
29 #include <stdlib.h> | 29 #include <stdlib.h> |
30 #include <math.h> | 30 #include <math.h> |
31 | 31 |
32 /* just to make sure this is defined... */ | |
33 | |
34 #ifndef min | |
35 #define min(x, y) ( ((x) < (y)) ? (x) : (y) ) | |
36 #endif | |
37 | |
38 #ifndef max | |
39 #define max(x, y) ( ((x) > (y)) ? (x) : (y) ) | |
40 #endif | |
41 | |
42 | |
32 /* some macros for "parsing" format */ | 43 /* some macros for "parsing" format */ |
33 | 44 |
34 #define IS_8BIT(x) ((x).format & 0x0008) | 45 #define IS_8BIT(x) ((x).format & 0x0008) |
35 #define IS_16BIT(x) ((x).format & 0x0010) | 46 #define IS_16BIT(x) ((x).format & 0x0010) |
36 #define IS_FLOAT(x) ((x).format & 0x0020) /* !!! FIXME: is this ok? */ | 47 #define IS_FLOAT(x) ((x).format & 0x0020) |
37 #define IS_SIGNED(x) ((x).format & 0x8000) | 48 #define IS_SIGNED(x) ((x).format & 0x8000) |
38 #define IS_SYSENDIAN(x) ((AUDIO_U16SYS ^ (x).format) & 0x1000) | 49 #define IS_SYSENDIAN(x) ((~AUDIO_U16SYS ^ (x).format) & 0x1000) |
39 | 50 |
40 | 51 |
41 /*-------------------------------------------------------------------------*/ | 52 /*-------------------------------------------------------------------------*/ |
42 /* this filter (Kaiser-window beta=6.8) gives a decent -80dB attentuation */ | 53 /* this filter (Kaiser-window beta=6.8) gives a decent -80dB attentuation */ |
43 static const int filter[_fsize/2] = { | 54 static const int filter[_fsize / 2] = |
55 { | |
44 0, 20798, 0, -6764, 0, 3863, 0, -2560, | 56 0, 20798, 0, -6764, 0, 3863, 0, -2560, |
45 0, 1800, 0, -1295, 0, 936, 0, -671, | 57 0, 1800, 0, -1295, 0, 936, 0, -671, |
46 0, 474, 0, -326, 0, 217, 0, -138, | 58 0, 474, 0, -326, 0, 217, 0, -138, |
47 0, 83, 0, -46, 0, 23, 0, -9 }; | 59 0, 83, 0, -46, 0, 23, 0, -9 |
60 }; | |
61 | |
62 | |
63 /*-------------------------------------------------------------------------*/ | |
64 /* the purpose of the RateConverterBuffer is to provide a continous storage | |
65 for head and tail of the (sample)-buffer. This allows a simple and | |
66 perfomant implemantation of the sample rate converters. Depending of the | |
67 operation mode, two layouts for the RateConverterBuffer.inbuffer are | |
68 possible: | |
69 | |
70 in the Loop Mode: | |
71 ... T-4 T-3 T-2 T-1 H+0 H+1 H+2 H+3 H+4 ... | |
72 | | |
73 linp, finp | |
74 | |
75 in the Single Mode (non Loop): | |
76 ... T-4 T-3 T-2 T-1 0 0 0 ... 0 0 0 H+0 H+1 H+2 H+3 H+4 ... | |
77 | | | |
78 linp finp | |
79 | |
80 The RateConverterBuffer allows an accurate attack and decay of the | |
81 filters in the rate Converters. | |
82 | |
83 The pointer finp are actually shifted against the depicted position so | |
84 that on the first invocation of the rate converter the input of the | |
85 filter is nearly complete in the zero region, only one input value is | |
86 used. After the calculation of the first output value, the pointer are | |
87 incremented or decremented depending on down or up conversion and the | |
88 first two input value are taken into account. This procedure repeats | |
89 until the filter has processed all zeroes. The distance of the pointer | |
90 movement is stored in flength. | |
91 | |
92 Further a pointer cinp to the sample buffer itself is stored. The pointer | |
93 to the sample buffer is shifted too, so that on the first use of this | |
94 pointer the filter is complete in the sample buffer. The pointer moves | |
95 over the sample buffer until it reaches the other end. The distance of | |
96 the movement is stored in clength. | |
97 | |
98 Finally the decay of the filter is done by linp, llength like finp, | |
99 flength, but in reverse order. | |
100 | |
101 buffer denotes the start or the end of the output buffer, depending | |
102 on direction of the rate conversion. | |
103 | |
104 All pointer and length referring the buffer as Sint16. All length | |
105 are refering to the input buffer */ | |
106 | |
107 typedef struct | |
108 { | |
109 Sint16 inbuffer[6*_fsize]; | |
110 Sint16 *finp, *cinp, *linp; | |
111 Sint16 *buffer; | |
112 int flength, clength, llength; | |
113 } RateConverterBuffer; | |
114 | |
48 | 115 |
49 /* Mono (1 channel ) */ | 116 /* Mono (1 channel ) */ |
50 #define Suffix(x) x##1 | 117 #define Suffix(x) x##1 |
51 #include "filter_templates.h" | 118 #include "filter_templates.h" |
52 #undef Suffix | 119 #undef Suffix |
54 /* Stereo (2 channel ) */ | 121 /* Stereo (2 channel ) */ |
55 #define Suffix(x) x##2 | 122 #define Suffix(x) x##2 |
56 #include "filter_templates.h" | 123 #include "filter_templates.h" |
57 #undef Suffix | 124 #undef Suffix |
58 | 125 |
126 | |
59 /*-------------------------------------------------------------------------*/ | 127 /*-------------------------------------------------------------------------*/ |
60 static int ConvertAudio( Sound_AudioCVT *Data, | 128 static int ConvertAudio( Sound_AudioCVT *Data, |
61 Uint8* buffer, int length, int mode ) | 129 Uint8* buffer, int length, int mode ) |
62 { | 130 { |
63 AdapterC Temp; | 131 AdapterC Temp; |
64 int i; | 132 int i; |
65 | 133 |
66 /* Make sure there's a converter */ | 134 /* Make sure there's a converter */ |
291 buffer[i]= 38084 * buffer[i] >> 16; | 359 buffer[i]= 38084 * buffer[i] >> 16; |
292 return length; | 360 return length; |
293 } | 361 } |
294 | 362 |
295 /*-------------------------------------------------------------------------*/ | 363 /*-------------------------------------------------------------------------*/ |
364 static void initRateConverterBuffer( RateConverterBuffer *rcb, | |
365 AdapterC* Data, int length, int rel_size ) | |
366 { | |
367 int size, slength; | |
368 int den, num; | |
369 int i; | |
370 | |
371 den = Data->filter->denominator; | |
372 num = Data->filter->numerator; | |
373 size = _fsize * rel_size; | |
374 length >>= 1; | |
375 slength = rel_size > 0 ? length : -length; | |
376 | |
377 rcb->buffer = (Sint16*)( Data->buffer ); | |
378 | |
379 if( Data->mode & SDL_AI_Loop ) | |
380 { | |
381 // !!!FIXME: modulo length, take scale into account | |
382 for( i = 0; i < size; i++ ) | |
383 { | |
384 rcb->inbuffer[i] = rcb->buffer[length-size+i]; | |
385 rcb->inbuffer[i+size] = rcb->buffer[i]; | |
386 } | |
387 rcb->finp = rcb->linp = rcb->inbuffer + size; | |
388 if( size < 0 ) | |
389 rcb->buffer += num * ( length + 2 * size ) / den; | |
390 } | |
391 else | |
392 { | |
393 for( i = 0; i < size; i++ ) | |
394 { | |
395 int j; | |
396 j = length-size+i; | |
397 rcb->inbuffer[i] = j < 0 ? 0 : rcb->buffer[j]; | |
398 rcb->inbuffer[i+size] = 0; | |
399 rcb->inbuffer[i+2*size] = i < length ? rcb->buffer[i] : 0; | |
400 } | |
401 // !!!FIXME: take lenght < size into account | |
402 rcb->finp = rcb->inbuffer + abs( 3*size/2 ) + size/2; | |
403 rcb->linp = rcb->inbuffer + abs( 3*size/2 ) - size/2; | |
404 rcb->flength = rcb->llength = 2*size; | |
405 rcb->clength = slength - 2*size; | |
406 | |
407 if( size < 0 ) | |
408 rcb->buffer += num * ( length + 2 * size ) / den; | |
409 } | |
410 } | |
411 | |
412 static void nextRateConverterBuffer( RateConverterBuffer *rcb ) | |
413 { | |
414 rcb->buffer++; | |
415 rcb->finp++; | |
416 rcb->cinp++; | |
417 rcb->linp++; | |
418 } | |
419 | |
420 typedef Sint16* (*RateConverter)( Sint16*, Sint16*, int, VarFilter*, int*); | |
421 static int doRateConversion( RateConverterBuffer* rcb, | |
422 RateConverter ffp, VarFilter* filter ) | |
423 { | |
424 int pos = 0; | |
425 Sint16 *outp; | |
426 outp = rcb->buffer; | |
427 | |
428 outp = (*ffp)( outp, rcb->finp, rcb->flength, filter, &pos ); | |
429 outp = (*ffp)( outp, rcb->cinp, rcb->clength, filter, &pos ); | |
430 outp = (*ffp)( outp, rcb->linp, rcb->llength, filter, &pos ); | |
431 return 2 * abs( rcb->buffer - outp ); | |
432 } | |
433 | |
434 | |
435 /*-------------------------------------------------------------------------*/ | |
436 static int doubleRateMono( AdapterC Data, int length ) | |
437 { | |
438 RateConverterBuffer rcb; | |
439 initRateConverterBuffer( &rcb, &Data, length, 1 ); | |
440 return doRateConversion( &rcb, doubleRate1, NULL ); | |
441 } | |
442 | |
296 static int doubleRateStereo( AdapterC Data, int length ) | 443 static int doubleRateStereo( AdapterC Data, int length ) |
297 { | 444 { |
298 length >>= 2; | 445 RateConverterBuffer rcb; |
299 _doubleRate2( (Sint16*)Data.buffer, Data.mode, length ); | 446 initRateConverterBuffer( &rcb, &Data, length, 2 ); |
300 return 4*_doubleRate2( (Sint16*)Data.buffer+1, Data.mode, length ); | 447 doRateConversion( &rcb, doubleRate2, NULL ); |
301 } | 448 nextRateConverterBuffer( &rcb ); |
302 | 449 return 2 + doRateConversion( &rcb, doubleRate2, NULL ); |
303 static int doubleRateMono( AdapterC Data, int length ) | 450 } |
304 { | 451 |
305 return 2*_doubleRate1( (Sint16*)Data.buffer, Data.mode, length>>1 ); | 452 /*-------------------------------------------------------------------------*/ |
306 } | 453 static int halfRateMono( AdapterC Data, int length ) |
307 | 454 { |
308 /*-------------------------------------------------------------------------*/ | 455 RateConverterBuffer rcb; |
456 initRateConverterBuffer( &rcb, &Data, length, -1 ); | |
457 return doRateConversion( &rcb, halfRate1, NULL ); | |
458 } | |
459 | |
309 static int halfRateStereo( AdapterC Data, int length ) | 460 static int halfRateStereo( AdapterC Data, int length ) |
310 { | 461 { |
311 length >>= 2; | 462 RateConverterBuffer rcb; |
312 _halfRate2( (Sint16*)Data.buffer, Data.mode, length ); | 463 initRateConverterBuffer( &rcb, &Data, length, -2 ); |
313 return 4*_halfRate2( (Sint16*)Data.buffer+1, Data.mode, length ); | 464 doRateConversion( &rcb, halfRate2, NULL ); |
314 } | 465 nextRateConverterBuffer( &rcb ); |
315 | 466 return 2 + doRateConversion( &rcb, halfRate2, NULL ); |
316 static int halfRateMono( AdapterC Data, int length ) | 467 } |
317 { | 468 |
318 return 2*_halfRate2( (Sint16*)Data.buffer, Data.mode, length>>1 ); | 469 /*-------------------------------------------------------------------------*/ |
319 } | 470 static int increaseRateMono( AdapterC Data, int length ) |
320 | 471 { |
321 /*-------------------------------------------------------------------------*/ | 472 RateConverterBuffer rcb; |
322 static int varRateUpStereo( AdapterC Data, int length ) | 473 initRateConverterBuffer( &rcb, &Data, length, 2 ); |
323 { | 474 return doRateConversion( &rcb, increaseRate1, Data.filter ); |
324 length >>= 2; | 475 } |
325 _varRateUp2( (Sint16*)Data.buffer, Data.mode, Data.filter, length ); | 476 |
326 return 4 * _varRateUp2( (Sint16*)Data.buffer+1, | 477 static int increaseRateStereo( AdapterC Data, int length ) |
327 Data.mode, Data.filter, length ); | 478 { |
328 } | 479 RateConverterBuffer rcb; |
329 | 480 initRateConverterBuffer( &rcb, &Data, length, 4 ); |
330 static int varRateUpMono( AdapterC Data, int length ) | 481 doRateConversion( &rcb, increaseRate2, Data.filter ); |
331 { | 482 nextRateConverterBuffer( &rcb ); |
332 return 2 * _varRateUp1( (Sint16*)Data.buffer, | 483 return 2 + doRateConversion( &rcb, increaseRate2, Data.filter ); |
333 Data.mode, Data.filter, length>>1 ); | 484 } |
334 } | 485 |
335 | 486 /*-------------------------------------------------------------------------*/ |
336 static int varRateDownStereo( AdapterC Data, int length ) | 487 static int decreaseRateMono( AdapterC Data, int length ) |
337 { | 488 { |
338 length >>= 2; | 489 RateConverterBuffer rcb; |
339 _varRateDown2( (Sint16*)Data.buffer, Data.mode, Data.filter, length ); | 490 initRateConverterBuffer( &rcb, &Data, length, -2 ); |
340 return 2 * _varRateDown2( (Sint16*)Data.buffer+1, | 491 return doRateConversion( &rcb, decreaseRate1, Data.filter ); |
341 Data.mode, Data.filter, length ); | 492 } |
342 } | 493 |
343 | 494 static int decreaseRateStereo( AdapterC Data, int length ) |
344 static int varRateDownMono( AdapterC Data, int length ) | 495 { |
345 { | 496 RateConverterBuffer rcb; |
346 return _varRateDown1( (Sint16*)Data.buffer, | 497 initRateConverterBuffer( &rcb, &Data, length, -4 ); |
347 Data.mode, Data.filter, length>>1 ); | 498 doRateConversion( &rcb, decreaseRate2, Data.filter ); |
348 } | 499 nextRateConverterBuffer( &rcb ); |
500 return doRateConversion( &rcb, decreaseRate2, Data.filter ); | |
501 } | |
502 | |
349 | 503 |
350 /*-------------------------------------------------------------------------*/ | 504 /*-------------------------------------------------------------------------*/ |
351 typedef struct{ | 505 typedef struct{ |
352 Sint16 denominator; | 506 Sint16 denominator; |
353 Sint16 numerator; | 507 Sint16 numerator; |
354 } Fraction; | 508 } Fraction; |
355 | 509 |
510 /* gives a maximal error of 3% and typical less than 0.2% */ | |
356 static Fraction findFraction( float Value ) | 511 static Fraction findFraction( float Value ) |
357 { | 512 { |
358 /* gives a maximal error of 3% and typical less than 0.2% */ | 513 const Sint8 frac[95]={ |
359 const Uint8 frac[96]={ | 514 2, -1, /* /1 */ |
360 1, 2, -1, /* /1 */ | |
361 1, 3, -1, /* /2 */ | 515 1, 3, -1, /* /2 */ |
362 2, 4, 5, -1, /* /3 */ | 516 2, 4, 5, -1, /* /3 */ |
363 3, 5, 7, -1, /* /4 */ | 517 3, 5, 7, -1, /* /4 */ |
364 3, 4, 6, 7, 8, 9, -1, /* /5 */ | 518 3, 4, 6, 7, 8, 9, -1, /* /5 */ |
365 5, 7, 11, -1, /* /6 */ | 519 5, 7, 11, -1, /* /6 */ |
374 8, 11, 13, 14, 16, -1, /* /15 */ | 528 8, 11, 13, 14, 16, -1, /* /15 */ |
375 9, 11, 13, 15 }; /* /16 */ | 529 9, 11, 13, 15 }; /* /16 */ |
376 | 530 |
377 | 531 |
378 Fraction Result = {0,0}; | 532 Fraction Result = {0,0}; |
379 int n,num,den=1; | 533 int n,num=1,den=1; |
380 | 534 |
381 float RelErr, BestErr = 0; | 535 float RelErr, BestErr = 0; |
382 if( Value < 31/64. || Value > 64/31. ) return Result; | 536 if( Value < 31/64. || Value > 64/31. ) return Result; |
383 | 537 |
384 for( n = 0; n < sizeof(frac); num=frac[++n] ) | 538 for( n = 0; n < sizeof(frac); num=frac[n++] ) |
385 { | 539 { |
386 if( num < 0 ) den++; | 540 if( num < 0 ) den++; |
387 RelErr = Value * num / den; | 541 RelErr = Value * num / den; |
388 RelErr = min( RelErr, 1/RelErr ); | 542 RelErr = min( RelErr, 1/RelErr ); |
389 if( RelErr > BestErr ) | 543 if( RelErr > BestErr ) |
401 { | 555 { |
402 if( x > -1e-24 && x < 1e-24 ) return 1.; | 556 if( x > -1e-24 && x < 1e-24 ) return 1.; |
403 else return sin(x)/x; | 557 else return sin(x)/x; |
404 } | 558 } |
405 | 559 |
406 static void calculateVarFilter( Sint16* dst, float Ratio, float phase, float scale ) | 560 static void calculateVarFilter( Sint16* dst, |
561 float Ratio, float phase, float scale ) | |
407 { | 562 { |
408 const Uint16 KaiserWindow7[]= { | 563 const Uint16 KaiserWindow7[]= { |
409 22930, 16292, 14648, 14288, 14470, 14945, 15608, 16404, | 564 22930, 16292, 14648, 14288, 14470, 14945, 15608, 16404, |
410 17304, 18289, 19347, 20467, 21644, 22872, 24145, 25460, | 565 17304, 18289, 19347, 20467, 21644, 22872, 24145, 25460, |
411 26812, 28198, 29612, 31052, 32513, 33991, 35482, 36983, | 566 26812, 28198, 29612, 31052, 32513, 33991, 35482, 36983, |
438 static void setupVarFilter( VarFilter* filter, | 593 static void setupVarFilter( VarFilter* filter, |
439 float Ratio, VarFilterMode Direction ) | 594 float Ratio, VarFilterMode Direction ) |
440 { | 595 { |
441 int i,n,d; | 596 int i,n,d; |
442 Fraction IRatio; | 597 Fraction IRatio; |
443 float phase; | 598 float phase = 0.; |
444 IRatio = findFraction( Ratio ); | 599 IRatio = findFraction( Ratio ); |
445 Ratio = min( Ratio, 1/Ratio ); | 600 Ratio = min( Ratio, 1/Ratio ); |
446 | 601 |
447 n = IRatio.numerator; | 602 n = IRatio.numerator; |
448 d = IRatio.denominator; | 603 d = IRatio.denominator; |
449 filter->pos_mod = d; | 604 filter->denominator = d; |
605 filter->numerator = n; | |
450 | 606 |
451 for( i = 0; i < d; i++ ) | 607 for( i = 0; i < d; i++ ) |
452 { | 608 { |
453 if( phase >= n ) | 609 if( phase >= n ) |
454 { | 610 { |
464 } | 620 } |
465 } | 621 } |
466 | 622 |
467 /*-------------------------------------------------------------------------*/ | 623 /*-------------------------------------------------------------------------*/ |
468 static void createRateConverter( Sound_AudioCVT *Data, int* fip, | 624 static void createRateConverter( Sound_AudioCVT *Data, int* fip, |
469 int SrcRate, int DestRate, int Channel ) | 625 int SrcRate, int DestRate, int Channel ) |
470 { | 626 { |
471 int filter_index = *fip; | 627 int filter_index = *fip; |
472 | 628 |
473 int VarPos = 0; | 629 int VarPos = 0; |
474 int Mono = 2 - Channel; | 630 int Mono = 2 - Channel; |
504 | 660 |
505 if( Ratio > 1. ) | 661 if( Ratio > 1. ) |
506 { | 662 { |
507 setupVarFilter( &Data->filter, Ratio, Up ); | 663 setupVarFilter( &Data->filter, Ratio, Up ); |
508 Data->adapter[VarPos] = | 664 Data->adapter[VarPos] = |
509 Mono ? varRateUpMono : varRateUpStereo; | 665 Mono ? increaseRateMono : increaseRateStereo; |
510 Data->len_mult *= 2; | 666 Data->len_mult *= 2; |
511 Data->add *= 2; | 667 Data->add *= 2; |
512 Data->add += _fsize; | 668 Data->add += _fsize; |
513 } | 669 } |
514 else | 670 else |
515 { | 671 { |
516 setupVarFilter( &Data->filter, Ratio, Down ); | 672 setupVarFilter( &Data->filter, Ratio, Down ); |
517 Data->adapter[filter_index++] = | 673 Data->adapter[filter_index++] = |
518 Mono ? varRateDownMono : varRateDownStereo; | 674 Mono ? decreaseRateMono : decreaseRateStereo; |
519 } | 675 } |
520 *fip = filter_index; | 676 *fip = filter_index; |
521 } | 677 } |
522 | 678 |
523 /*-------------------------------------------------------------------------*/ | 679 /*-------------------------------------------------------------------------*/ |
641 *fip = filter_index; | 797 *fip = filter_index; |
642 } | 798 } |
643 | 799 |
644 | 800 |
645 /*-------------------------------------------------------------------------*/ | 801 /*-------------------------------------------------------------------------*/ |
646 DECLSPEC int BuildAudioCVT(Sound_AudioCVT *Data, | 802 int BuildAudioCVT( Sound_AudioCVT *Data, |
647 SDL_AudioSpec src, SDL_AudioSpec dst ) | 803 SDL_AudioSpec src, SDL_AudioSpec dst ) |
648 { | 804 { |
649 SDL_AudioSpec intrm; | 805 SDL_AudioSpec intrm; |
650 int filter_index = 0; | 806 int filter_index = 0; |
651 | 807 |
652 if( Data == NULL ) return -1; | 808 if( Data == NULL ) return -1; |
731 AdapterDesc(convertStereoToMonoS8Bit), | 887 AdapterDesc(convertStereoToMonoS8Bit), |
732 AdapterDesc(convertStereoToMonoU8Bit), | 888 AdapterDesc(convertStereoToMonoU8Bit), |
733 AdapterDesc(convertMonoToStereo16Bit), | 889 AdapterDesc(convertMonoToStereo16Bit), |
734 AdapterDesc(convertMonoToStereo8Bit), | 890 AdapterDesc(convertMonoToStereo8Bit), |
735 AdapterDesc(minus5dB), | 891 AdapterDesc(minus5dB), |
892 AdapterDesc(doubleRateMono), | |
736 AdapterDesc(doubleRateStereo), | 893 AdapterDesc(doubleRateStereo), |
737 AdapterDesc(doubleRateMono), | 894 AdapterDesc(halfRateMono), |
738 AdapterDesc(halfRateStereo), | 895 AdapterDesc(halfRateStereo), |
739 AdapterDesc(halfRateMono), | 896 AdapterDesc(increaseRateMono), |
740 AdapterDesc(varRateUpStereo), | 897 AdapterDesc(increaseRateStereo), |
741 AdapterDesc(varRateUpMono), | 898 AdapterDesc(decreaseRateMono), |
742 AdapterDesc(varRateDownStereo), | 899 AdapterDesc(decreaseRateStereo), |
743 AdapterDesc(varRateDownMono), | |
744 { NULL, "----------NULL-----------" } | 900 { NULL, "----------NULL-----------" } |
745 }; | 901 }; |
746 const int AdapterDescMax = sizeof(AdapterDescription) | 902 const int AdapterDescMax = sizeof(AdapterDescription) |
747 / sizeof(*AdapterDescription); | 903 / sizeof(*AdapterDescription); |
748 | 904 |
764 fprintf( stderr, " Error: NULL adapter missing\n" ); | 920 fprintf( stderr, " Error: NULL adapter missing\n" ); |
765 } | 921 } |
766 | 922 |
767 | 923 |
768 int Sound_BuildAudioCVT(Sound_AudioCVT *Data, | 924 int Sound_BuildAudioCVT(Sound_AudioCVT *Data, |
769 Uint16 src_format, Uint8 src_channels, int src_rate, | 925 Uint16 src_format, Uint8 src_channels, int src_rate, |
770 Uint16 dst_format, Uint8 dst_channels, int dst_rate) | 926 Uint16 dst_format, Uint8 dst_channels, int dst_rate) |
771 { | 927 { |
772 SDL_AudioSpec src, dst; | 928 SDL_AudioSpec src, dst; |
773 int ret; | 929 int ret; |
774 | 930 |
775 fprintf (stderr, | 931 fprintf (stderr, |