sdlgenaudiocvt.pl (21172B)
1#!/usr/bin/perl -w 2 3use warnings; 4use strict; 5 6my @audiotypes = qw( 7 U8 8 S8 9 U16LSB 10 S16LSB 11 U16MSB 12 S16MSB 13 S32LSB 14 S32MSB 15 F32LSB 16 F32MSB 17); 18 19my @channels = ( 1, 2, 4, 6, 8 ); 20my %funcs; 21my $custom_converters = 0; 22 23 24sub getTypeConvertHashId { 25 my ($from, $to) = @_; 26 return "TYPECONVERTER $from/$to"; 27} 28 29 30sub getResamplerHashId { 31 my ($from, $channels, $upsample, $multiple) = @_; 32 return "RESAMPLER $from/$channels/$upsample/$multiple"; 33} 34 35 36sub outputHeader { 37 print <<EOF; 38/* DO NOT EDIT! This file is generated by sdlgenaudiocvt.pl */ 39/* 40 Simple DirectMedia Layer 41 Copyright (C) 1997-2014 Sam Lantinga <slouken\@libsdl.org> 42 43 This software is provided 'as-is', without any express or implied 44 warranty. In no event will the authors be held liable for any damages 45 arising from the use of this software. 46 47 Permission is granted to anyone to use this software for any purpose, 48 including commercial applications, and to alter it and redistribute it 49 freely, subject to the following restrictions: 50 51 1. The origin of this software must not be misrepresented; you must not 52 claim that you wrote the original software. If you use this software 53 in a product, an acknowledgment in the product documentation would be 54 appreciated but is not required. 55 2. Altered source versions must be plainly marked as such, and must not be 56 misrepresented as being the original software. 57 3. This notice may not be removed or altered from any source distribution. 58*/ 59 60#include "../SDL_internal.h" 61#include "SDL_audio.h" 62#include "SDL_audio_c.h" 63 64#ifndef DEBUG_CONVERT 65#define DEBUG_CONVERT 0 66#endif 67 68 69/* If you can guarantee your data and need space, you can eliminate code... */ 70 71/* Just build the arbitrary resamplers if you're saving code space. */ 72#ifndef LESS_RESAMPLERS 73#define LESS_RESAMPLERS 0 74#endif 75 76/* Don't build any resamplers if you're REALLY saving code space. */ 77#ifndef NO_RESAMPLERS 78#define NO_RESAMPLERS 0 79#endif 80 81/* Don't build any type converters if you're saving code space. */ 82#ifndef NO_CONVERTERS 83#define NO_CONVERTERS 0 84#endif 85 86 87/* *INDENT-OFF* */ 88 89EOF 90 91 my @vals = ( 127, 32767, 2147483647 ); 92 foreach (@vals) { 93 my $val = $_; 94 my $fval = 1.0 / $val; 95 print("#define DIVBY${val} ${fval}f\n"); 96 } 97 98 print("\n"); 99} 100 101sub outputFooter { 102 print <<EOF; 103/* $custom_converters converters generated. */ 104 105/* *INDENT-ON* */ 106 107/* vi: set ts=4 sw=4 expandtab: */ 108EOF 109} 110 111sub splittype { 112 my $t = shift; 113 my ($signed, $size, $endian) = $t =~ /([USF])(\d+)([LM]SB|)/; 114 my $float = ($signed eq 'F') ? 1 : 0; 115 $signed = (($float) or ($signed eq 'S')) ? 1 : 0; 116 $endian = 'NONE' if ($endian eq ''); 117 118 my $ctype = ''; 119 if ($float) { 120 $ctype = (($size == 32) ? 'float' : 'double'); 121 } else { 122 $ctype = (($signed) ? 'S' : 'U') . "int${size}"; 123 } 124 125 return ($signed, $float, $size, $endian, $ctype); 126} 127 128sub getSwapFunc { 129 my ($size, $signed, $float, $endian, $val) = @_; 130 my $BEorLE = (($endian eq 'MSB') ? 'BE' : 'LE'); 131 my $code = ''; 132 133 if ($float) { 134 $code = "SDL_SwapFloat${BEorLE}($val)"; 135 } else { 136 if ($size > 8) { 137 $code = "SDL_Swap${BEorLE}${size}($val)"; 138 } else { 139 $code = $val; 140 } 141 142 if (($signed) and (!$float)) { 143 $code = "((Sint${size}) $code)"; 144 } 145 } 146 147 return "${code}"; 148} 149 150 151sub maxIntVal { 152 my $size = shift; 153 if ($size == 8) { 154 return 0x7F; 155 } elsif ($size == 16) { 156 return 0x7FFF; 157 } elsif ($size == 32) { 158 return 0x7FFFFFFF; 159 } 160 161 die("bug in script.\n"); 162} 163 164sub getFloatToIntMult { 165 my $size = shift; 166 my $val = maxIntVal($size) . '.0'; 167 $val .= 'f' if ($size < 32); 168 return $val; 169} 170 171sub getIntToFloatDivBy { 172 my $size = shift; 173 return 'DIVBY' . maxIntVal($size); 174} 175 176sub getSignFlipVal { 177 my $size = shift; 178 if ($size == 8) { 179 return '0x80'; 180 } elsif ($size == 16) { 181 return '0x8000'; 182 } elsif ($size == 32) { 183 return '0x80000000'; 184 } 185 186 die("bug in script.\n"); 187} 188 189sub buildCvtFunc { 190 my ($from, $to) = @_; 191 my ($fsigned, $ffloat, $fsize, $fendian, $fctype) = splittype($from); 192 my ($tsigned, $tfloat, $tsize, $tendian, $tctype) = splittype($to); 193 my $diffs = 0; 194 $diffs++ if ($fsize != $tsize); 195 $diffs++ if ($fsigned != $tsigned); 196 $diffs++ if ($ffloat != $tfloat); 197 $diffs++ if ($fendian ne $tendian); 198 199 return if ($diffs == 0); 200 201 my $hashid = getTypeConvertHashId($from, $to); 202 if (1) { # !!! FIXME: if ($diffs > 1) { 203 my $sym = "SDL_Convert_${from}_to_${to}"; 204 $funcs{$hashid} = $sym; 205 $custom_converters++; 206 207 # Always unsigned for ints, for possible byteswaps. 208 my $srctype = (($ffloat) ? 'float' : "Uint${fsize}"); 209 210 print <<EOF; 211static void SDLCALL 212${sym}(SDL_AudioCVT * cvt, SDL_AudioFormat format) 213{ 214 int i; 215 const $srctype *src; 216 $tctype *dst; 217 218#if DEBUG_CONVERT 219 fprintf(stderr, "Converting AUDIO_${from} to AUDIO_${to}.\\n"); 220#endif 221 222EOF 223 224 if ($fsize < $tsize) { 225 my $mult = $tsize / $fsize; 226 print <<EOF; 227 src = ((const $srctype *) (cvt->buf + cvt->len_cvt)) - 1; 228 dst = (($tctype *) (cvt->buf + cvt->len_cvt * $mult)) - 1; 229 for (i = cvt->len_cvt / sizeof ($srctype); i; --i, --src, --dst) { 230EOF 231 } else { 232 print <<EOF; 233 src = (const $srctype *) cvt->buf; 234 dst = ($tctype *) cvt->buf; 235 for (i = cvt->len_cvt / sizeof ($srctype); i; --i, ++src, ++dst) { 236EOF 237 } 238 239 # Have to convert to/from float/int. 240 # !!! FIXME: cast through double for int32<->float? 241 my $code = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, '*src'); 242 if ($ffloat != $tfloat) { 243 if ($ffloat) { 244 my $mult = getFloatToIntMult($tsize); 245 if (!$tsigned) { # bump from -1.0f/1.0f to 0.0f/2.0f 246 $code = "($code + 1.0f)"; 247 } 248 $code = "(($tctype) ($code * $mult))"; 249 } else { 250 # $divby will be the reciprocal, to avoid pipeline stalls 251 # from floating point division...so multiply it. 252 my $divby = getIntToFloatDivBy($fsize); 253 $code = "(((float) $code) * $divby)"; 254 if (!$fsigned) { # bump from 0.0f/2.0f to -1.0f/1.0f. 255 $code = "($code - 1.0f)"; 256 } 257 } 258 } else { 259 # All integer conversions here. 260 if ($fsigned != $tsigned) { 261 my $signflipval = getSignFlipVal($fsize); 262 $code = "(($code) ^ $signflipval)"; 263 } 264 265 my $shiftval = abs($fsize - $tsize); 266 if ($fsize < $tsize) { 267 $code = "((($tctype) $code) << $shiftval)"; 268 } elsif ($fsize > $tsize) { 269 $code = "(($tctype) ($code >> $shiftval))"; 270 } 271 } 272 273 my $swap = getSwapFunc($tsize, $tsigned, $tfloat, $tendian, 'val'); 274 275 print <<EOF; 276 const $tctype val = $code; 277 *dst = ${swap}; 278 } 279 280EOF 281 282 if ($fsize > $tsize) { 283 my $divby = $fsize / $tsize; 284 print(" cvt->len_cvt /= $divby;\n"); 285 } elsif ($fsize < $tsize) { 286 my $mult = $tsize / $fsize; 287 print(" cvt->len_cvt *= $mult;\n"); 288 } 289 290 print <<EOF; 291 if (cvt->filters[++cvt->filter_index]) { 292 cvt->filters[cvt->filter_index] (cvt, AUDIO_$to); 293 } 294} 295 296EOF 297 298 } else { 299 if ($fsigned != $tsigned) { 300 $funcs{$hashid} = 'SDL_ConvertSigned'; 301 } elsif ($ffloat != $tfloat) { 302 $funcs{$hashid} = 'SDL_ConvertFloat'; 303 } elsif ($fsize != $tsize) { 304 $funcs{$hashid} = 'SDL_ConvertSize'; 305 } elsif ($fendian ne $tendian) { 306 $funcs{$hashid} = 'SDL_ConvertEndian'; 307 } else { 308 die("error in script.\n"); 309 } 310 } 311} 312 313 314sub buildTypeConverters { 315 print "#if !NO_CONVERTERS\n\n"; 316 foreach (@audiotypes) { 317 my $from = $_; 318 foreach (@audiotypes) { 319 my $to = $_; 320 buildCvtFunc($from, $to); 321 } 322 } 323 print "#endif /* !NO_CONVERTERS */\n\n\n"; 324 325 print "const SDL_AudioTypeFilters sdl_audio_type_filters[] =\n{\n"; 326 print "#if !NO_CONVERTERS\n"; 327 foreach (@audiotypes) { 328 my $from = $_; 329 foreach (@audiotypes) { 330 my $to = $_; 331 if ($from ne $to) { 332 my $hashid = getTypeConvertHashId($from, $to); 333 my $sym = $funcs{$hashid}; 334 print(" { AUDIO_$from, AUDIO_$to, $sym },\n"); 335 } 336 } 337 } 338 print "#endif /* !NO_CONVERTERS */\n"; 339 340 print(" { 0, 0, NULL }\n"); 341 print "};\n\n\n"; 342} 343 344sub getBiggerCtype { 345 my ($isfloat, $size) = @_; 346 347 if ($isfloat) { 348 if ($size == 32) { 349 return 'double'; 350 } 351 die("bug in script.\n"); 352 } 353 354 if ($size == 8) { 355 return 'Sint16'; 356 } elsif ($size == 16) { 357 return 'Sint32' 358 } elsif ($size == 32) { 359 return 'Sint64' 360 } 361 362 die("bug in script.\n"); 363} 364 365 366# These handle arbitrary resamples...44100Hz to 48000Hz, for example. 367# Man, this code is skanky. 368sub buildArbitraryResampleFunc { 369 # !!! FIXME: we do a lot of unnecessary and ugly casting in here, due to getSwapFunc(). 370 my ($from, $channels, $upsample) = @_; 371 my ($fsigned, $ffloat, $fsize, $fendian, $fctype) = splittype($from); 372 373 my $bigger = getBiggerCtype($ffloat, $fsize); 374 my $interp = ($ffloat) ? '* 0.5' : '>> 1'; 375 376 my $resample = ($upsample) ? 'Upsample' : 'Downsample'; 377 my $hashid = getResamplerHashId($from, $channels, $upsample, 0); 378 my $sym = "SDL_${resample}_${from}_${channels}c"; 379 $funcs{$hashid} = $sym; 380 $custom_converters++; 381 382 my $fudge = $fsize * $channels * 2; # !!! FIXME 383 my $eps_adjust = ($upsample) ? 'dstsize' : 'srcsize'; 384 my $incr = ''; 385 my $incr2 = ''; 386 my $block_align = $channels * $fsize/8; 387 388 389 # !!! FIXME: DEBUG_CONVERT should report frequencies. 390 print <<EOF; 391static void SDLCALL 392${sym}(SDL_AudioCVT * cvt, SDL_AudioFormat format) 393{ 394#if DEBUG_CONVERT 395 fprintf(stderr, "$resample arbitrary (x%f) AUDIO_${from}, ${channels} channels.\\n", cvt->rate_incr); 396#endif 397 398 const int srcsize = cvt->len_cvt - $fudge; 399 const int dstsize = (int) (((double)(cvt->len_cvt/${block_align})) * cvt->rate_incr) * ${block_align}; 400 register int eps = 0; 401EOF 402 403 my $endcomparison = '!='; 404 405 # Upsampling (growing the buffer) needs to work backwards, since we 406 # overwrite the buffer as we go. 407 if ($upsample) { 408 $endcomparison = '>='; # dst > target 409 print <<EOF; 410 $fctype *dst = (($fctype *) (cvt->buf + dstsize)) - $channels; 411 const $fctype *src = (($fctype *) (cvt->buf + cvt->len_cvt)) - $channels; 412 const $fctype *target = ((const $fctype *) cvt->buf); 413EOF 414 } else { 415 $endcomparison = '<'; # dst < target 416 print <<EOF; 417 $fctype *dst = ($fctype *) cvt->buf; 418 const $fctype *src = ($fctype *) cvt->buf; 419 const $fctype *target = (const $fctype *) (cvt->buf + dstsize); 420EOF 421 } 422 423 for (my $i = 0; $i < $channels; $i++) { 424 my $idx = ($upsample) ? (($channels - $i) - 1) : $i; 425 my $val = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "src[$idx]"); 426 print <<EOF; 427 $fctype sample${idx} = $val; 428EOF 429 } 430 431 for (my $i = 0; $i < $channels; $i++) { 432 my $idx = ($upsample) ? (($channels - $i) - 1) : $i; 433 print <<EOF; 434 $fctype last_sample${idx} = sample${idx}; 435EOF 436 } 437 438 print <<EOF; 439 while (dst $endcomparison target) { 440EOF 441 442 if ($upsample) { 443 for (my $i = 0; $i < $channels; $i++) { 444 # !!! FIXME: don't do this swap every write, just when the samples change. 445 my $idx = (($channels - $i) - 1); 446 my $val = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "sample${idx}"); 447 print <<EOF; 448 dst[$idx] = $val; 449EOF 450 } 451 452 $incr = ($channels == 1) ? 'dst--' : "dst -= $channels"; 453 $incr2 = ($channels == 1) ? 'src--' : "src -= $channels"; 454 455 print <<EOF; 456 $incr; 457 eps += srcsize; 458 if ((eps << 1) >= dstsize) { 459 $incr2; 460EOF 461 } else { # downsample. 462 $incr = ($channels == 1) ? 'src++' : "src += $channels"; 463 print <<EOF; 464 $incr; 465 eps += dstsize; 466 if ((eps << 1) >= srcsize) { 467EOF 468 for (my $i = 0; $i < $channels; $i++) { 469 my $val = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "sample${i}"); 470 print <<EOF; 471 dst[$i] = $val; 472EOF 473 } 474 475 $incr = ($channels == 1) ? 'dst++' : "dst += $channels"; 476 print <<EOF; 477 $incr; 478EOF 479 } 480 481 for (my $i = 0; $i < $channels; $i++) { 482 my $idx = ($upsample) ? (($channels - $i) - 1) : $i; 483 my $swapped = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "src[$idx]"); 484 print <<EOF; 485 sample${idx} = ($fctype) (((($bigger) $swapped) + (($bigger) last_sample${idx})) $interp); 486EOF 487 } 488 489 for (my $i = 0; $i < $channels; $i++) { 490 my $idx = ($upsample) ? (($channels - $i) - 1) : $i; 491 print <<EOF; 492 last_sample${idx} = sample${idx}; 493EOF 494 } 495 496 print <<EOF; 497 eps -= $eps_adjust; 498 } 499 } 500EOF 501 502 print <<EOF; 503 cvt->len_cvt = dstsize; 504 if (cvt->filters[++cvt->filter_index]) { 505 cvt->filters[cvt->filter_index] (cvt, format); 506 } 507} 508 509EOF 510 511} 512 513# These handle clean resamples...doubling and quadrupling the sample rate, etc. 514sub buildMultipleResampleFunc { 515 # !!! FIXME: we do a lot of unnecessary and ugly casting in here, due to getSwapFunc(). 516 my ($from, $channels, $upsample, $multiple) = @_; 517 my ($fsigned, $ffloat, $fsize, $fendian, $fctype) = splittype($from); 518 519 my $bigger = getBiggerCtype($ffloat, $fsize); 520 my $interp = ($ffloat) ? '* 0.5' : '>> 1'; 521 my $interp2 = ($ffloat) ? '* 0.25' : '>> 2'; 522 my $mult3 = ($ffloat) ? '3.0' : '3'; 523 my $lencvtop = ($upsample) ? '*' : '/'; 524 525 my $resample = ($upsample) ? 'Upsample' : 'Downsample'; 526 my $hashid = getResamplerHashId($from, $channels, $upsample, $multiple); 527 my $sym = "SDL_${resample}_${from}_${channels}c_x${multiple}"; 528 $funcs{$hashid} = $sym; 529 $custom_converters++; 530 531 # !!! FIXME: DEBUG_CONVERT should report frequencies. 532 print <<EOF; 533static void SDLCALL 534${sym}(SDL_AudioCVT * cvt, SDL_AudioFormat format) 535{ 536#if DEBUG_CONVERT 537 fprintf(stderr, "$resample (x${multiple}) AUDIO_${from}, ${channels} channels.\\n"); 538#endif 539 540 const int dstsize = cvt->len_cvt $lencvtop $multiple; 541EOF 542 543 my $endcomparison = '!='; 544 545 # Upsampling (growing the buffer) needs to work backwards, since we 546 # overwrite the buffer as we go. 547 if ($upsample) { 548 $endcomparison = '>='; # dst > target 549 print <<EOF; 550 $fctype *dst = (($fctype *) (cvt->buf + dstsize)) - $channels * $multiple; 551 const $fctype *src = (($fctype *) (cvt->buf + cvt->len_cvt)) - $channels; 552 const $fctype *target = ((const $fctype *) cvt->buf); 553EOF 554 } else { 555 $endcomparison = '<'; # dst < target 556 print <<EOF; 557 $fctype *dst = ($fctype *) cvt->buf; 558 const $fctype *src = ($fctype *) cvt->buf; 559 const $fctype *target = (const $fctype *) (cvt->buf + dstsize); 560EOF 561 } 562 563 for (my $i = 0; $i < $channels; $i++) { 564 my $idx = ($upsample) ? (($channels - $i) - 1) : $i; 565 my $val = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "src[$idx]"); 566 print <<EOF; 567 $bigger last_sample${idx} = ($bigger) $val; 568EOF 569 } 570 571 print <<EOF; 572 while (dst $endcomparison target) { 573EOF 574 575 for (my $i = 0; $i < $channels; $i++) { 576 my $idx = ($upsample) ? (($channels - $i) - 1) : $i; 577 my $val = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "src[$idx]"); 578 print <<EOF; 579 const $bigger sample${idx} = ($bigger) $val; 580EOF 581 } 582 583 my $incr = ''; 584 if ($upsample) { 585 $incr = ($channels == 1) ? 'src--' : "src -= $channels"; 586 } else { 587 my $amount = $channels * $multiple; 588 $incr = "src += $amount"; # can't ever be 1, so no "++" version. 589 } 590 591 592 print <<EOF; 593 $incr; 594EOF 595 596 # !!! FIXME: This really begs for some Altivec or SSE, etc. 597 if ($upsample) { 598 if ($multiple == 2) { 599 for (my $i = $channels-1; $i >= 0; $i--) { 600 my $dsti = $i + $channels; 601 print <<EOF; 602 dst[$dsti] = ($fctype) ((sample${i} + last_sample${i}) $interp); 603EOF 604 } 605 for (my $i = $channels-1; $i >= 0; $i--) { 606 my $dsti = $i; 607 print <<EOF; 608 dst[$dsti] = ($fctype) sample${i}; 609EOF 610 } 611 } elsif ($multiple == 4) { 612 for (my $i = $channels-1; $i >= 0; $i--) { 613 my $dsti = $i + ($channels * 3); 614 print <<EOF; 615 dst[$dsti] = ($fctype) ((sample${i} + ($mult3 * last_sample${i})) $interp2); 616EOF 617 } 618 619 for (my $i = $channels-1; $i >= 0; $i--) { 620 my $dsti = $i + ($channels * 2); 621 print <<EOF; 622 dst[$dsti] = ($fctype) ((sample${i} + last_sample${i}) $interp); 623EOF 624 } 625 626 for (my $i = $channels-1; $i >= 0; $i--) { 627 my $dsti = $i + ($channels * 1); 628 print <<EOF; 629 dst[$dsti] = ($fctype) ((($mult3 * sample${i}) + last_sample${i}) $interp2); 630EOF 631 } 632 633 for (my $i = $channels-1; $i >= 0; $i--) { 634 my $dsti = $i + ($channels * 0); 635 print <<EOF; 636 dst[$dsti] = ($fctype) sample${i}; 637EOF 638 } 639 } else { 640 die('bug in program.'); # we only handle x2 and x4. 641 } 642 } else { # downsample. 643 if ($multiple == 2) { 644 for (my $i = 0; $i < $channels; $i++) { 645 print <<EOF; 646 dst[$i] = ($fctype) ((sample${i} + last_sample${i}) $interp); 647EOF 648 } 649 } elsif ($multiple == 4) { 650 # !!! FIXME: interpolate all 4 samples? 651 for (my $i = 0; $i < $channels; $i++) { 652 print <<EOF; 653 dst[$i] = ($fctype) ((sample${i} + last_sample${i}) $interp); 654EOF 655 } 656 } else { 657 die('bug in program.'); # we only handle x2 and x4. 658 } 659 } 660 661 for (my $i = 0; $i < $channels; $i++) { 662 my $idx = ($upsample) ? (($channels - $i) - 1) : $i; 663 print <<EOF; 664 last_sample${idx} = sample${idx}; 665EOF 666 } 667 668 if ($upsample) { 669 my $amount = $channels * $multiple; 670 $incr = "dst -= $amount"; # can't ever be 1, so no "--" version. 671 } else { 672 $incr = ($channels == 1) ? 'dst++' : "dst += $channels"; 673 } 674 675 print <<EOF; 676 $incr; 677 } 678 679 cvt->len_cvt = dstsize; 680 if (cvt->filters[++cvt->filter_index]) { 681 cvt->filters[cvt->filter_index] (cvt, format); 682 } 683} 684 685EOF 686 687} 688 689sub buildResamplers { 690 print "#if !NO_RESAMPLERS\n\n"; 691 foreach (@audiotypes) { 692 my $from = $_; 693 foreach (@channels) { 694 my $channel = $_; 695 buildArbitraryResampleFunc($from, $channel, 1); 696 buildArbitraryResampleFunc($from, $channel, 0); 697 } 698 } 699 700 print "\n#if !LESS_RESAMPLERS\n\n"; 701 foreach (@audiotypes) { 702 my $from = $_; 703 foreach (@channels) { 704 my $channel = $_; 705 for (my $multiple = 2; $multiple <= 4; $multiple += 2) { 706 buildMultipleResampleFunc($from, $channel, 1, $multiple); 707 buildMultipleResampleFunc($from, $channel, 0, $multiple); 708 } 709 } 710 } 711 712 print "#endif /* !LESS_RESAMPLERS */\n"; 713 print "#endif /* !NO_RESAMPLERS */\n\n\n"; 714 715 print "const SDL_AudioRateFilters sdl_audio_rate_filters[] =\n{\n"; 716 print "#if !NO_RESAMPLERS\n"; 717 foreach (@audiotypes) { 718 my $from = $_; 719 foreach (@channels) { 720 my $channel = $_; 721 for (my $upsample = 0; $upsample <= 1; $upsample++) { 722 my $hashid = getResamplerHashId($from, $channel, $upsample, 0); 723 my $sym = $funcs{$hashid}; 724 print(" { AUDIO_$from, $channel, $upsample, 0, $sym },\n"); 725 } 726 } 727 } 728 729 print "#if !LESS_RESAMPLERS\n"; 730 foreach (@audiotypes) { 731 my $from = $_; 732 foreach (@channels) { 733 my $channel = $_; 734 for (my $multiple = 2; $multiple <= 4; $multiple += 2) { 735 for (my $upsample = 0; $upsample <= 1; $upsample++) { 736 my $hashid = getResamplerHashId($from, $channel, $upsample, $multiple); 737 my $sym = $funcs{$hashid}; 738 print(" { AUDIO_$from, $channel, $upsample, $multiple, $sym },\n"); 739 } 740 } 741 } 742 } 743 744 print "#endif /* !LESS_RESAMPLERS */\n"; 745 print "#endif /* !NO_RESAMPLERS */\n"; 746 print(" { 0, 0, 0, 0, NULL }\n"); 747 print "};\n\n"; 748} 749 750 751# mainline ... 752 753outputHeader(); 754buildTypeConverters(); 755buildResamplers(); 756outputFooter(); 757 758exit 0; 759 760# end of sdlgenaudiocvt.pl ... 761