From 6978972c80c72467411ad914ba74ed4b0f12ff09 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 9 Jan 2009 15:41:45 +0000 Subject: [PATCH] First shot at autogenerated audio resamplers. Don't check in a new SDL_audiotypecvt.c yet, though. --- src/audio/sdlgenaudiocvt.pl | 420 ++++++++++++++++++++++++++++++++++-- 1 file changed, 401 insertions(+), 19 deletions(-) diff --git a/src/audio/sdlgenaudiocvt.pl b/src/audio/sdlgenaudiocvt.pl index b6ee0893f..7af86f9a6 100755 --- a/src/audio/sdlgenaudiocvt.pl +++ b/src/audio/sdlgenaudiocvt.pl @@ -16,11 +16,23 @@ F32MSB ); +my @channels = ( 1, 2, 4, 6, 8 ); my %funcs; - my $custom_converters = 0; +sub getTypeConvertHashId { + my ($from, $to) = @_; + return "TYPECONVERTER $from/$to"; +} + + +sub getResamplerHashId { + my ($from, $channels, $upsample, $multiple) = @_; + return "RESAMPLER $from/$channels/$upsample/$multiple"; +} + + sub outputHeader { print < 1) { my $sym = "SDL_Convert_${from}_to_${to}"; $funcs{$hashid} = $sym; @@ -274,39 +288,407 @@ sub buildCvtFunc { } } -outputHeader(); -foreach (@audiotypes) { - my $from = $_; +sub buildTypeConverters { + foreach (@audiotypes) { + my $from = $_; + foreach (@audiotypes) { + my $to = $_; + buildCvtFunc($from, $to); + } + } + + print "const SDL_AudioTypeFilters sdl_audio_type_filters[] =\n{\n"; foreach (@audiotypes) { - my $to = $_; - buildCvtFunc($from, $to); + my $from = $_; + foreach (@audiotypes) { + my $to = $_; + if ($from ne $to) { + my $hashid = getTypeConvertHashId($from, $to); + my $sym = $funcs{$hashid}; + print(" { AUDIO_$from, AUDIO_$to, $sym },\n"); + } + } + } + + print "};\n\n\n"; +} + +sub getBiggerCtype { + my ($isfloat, $size) = @_; + + if ($isfloat) { + if ($size == 32) { + return 'double'; + } + die("bug in script.\n"); + } + + if ($size == 8) { + return 'Sint16'; + } elsif ($size == 16) { + return 'Sint32' + } elsif ($size == 32) { + return 'Sint64' } + + die("bug in script.\n"); } -print <> 1'; + + my $resample = ($upsample) ? 'Upsample' : 'Downsample'; + my $hashid = getResamplerHashId($from, $channels, $upsample, 0); + my $sym = "SDL_${resample}_${from}_${channels}c"; + $funcs{$hashid} = $sym; + $custom_converters++; + + my $fudge = $fsize * $channels * 2; # !!! FIXME + my $eps_adjust = ($upsample) ? 'dstsize' : 'srcsize'; + my $incr = ''; + my $incr2 = ''; + + + # !!! FIXME: DEBUG_CONVERT should report frequencies. + print <rate_incr); +#endif + + const int srcsize = cvt->len_cvt - $fudge; + const int dstsize = (int) (((double)cvt->len_cvt) * cvt->rate_incr); + register int eps = 0; EOF -foreach (@audiotypes) { - my $from = $_; - foreach (@audiotypes) { - my $to = $_; - if ($from ne $to) { - my $hashid = "$from/$to"; - my $sym = $funcs{$hashid}; - print(" { AUDIO_$from, AUDIO_$to, $sym },\n"); + # Upsampling (growing the buffer) needs to work backwards, since we + # overwrite the buffer as we go. + if ($upsample) { + print <buf + dstsize)) - $channels; + const $fctype *src = (($fctype *) (cvt->buf + cvt->len_cvt)) - $channels; + const $fctype *target = ((const $fctype *) cvt->buf) - $channels; +EOF + } else { + print <buf; + const $fctype *src = ($fctype *) cvt->buf; + const $fctype *target = (const $fctype *) (cvt->buf + dstsize); +EOF + } + + for (my $i = 0; $i < $channels; $i++) { + my $idx = ($upsample) ? (($channels - $i) - 1) : $i; + my $val = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "src[$idx]"); + print <= dstsize) { + $incr2; +EOF + } else { # downsample. + $incr = ($channels == 1) ? 'src++' : "src += $channels"; + print <= srcsize) { +EOF + for (my $i = 0; $i < $channels; $i++) { + my $val = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "sample${i}"); + print <len_cvt = dstsize; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); } } -print <> 1'; + my $interp2 = ($ffloat) ? '* 0.25' : '>> 2'; + my $mult3 = ($ffloat) ? '3.0' : '3'; + my $lencvtop = ($upsample) ? '*' : '/'; + + my $resample = ($upsample) ? 'Upsample' : 'Downsample'; + my $hashid = getResamplerHashId($from, $channels, $upsample, $multiple); + my $sym = "SDL_${resample}_${from}_${channels}c_x${multiple}"; + $funcs{$hashid} = $sym; + $custom_converters++; + + # !!! FIXME: DEBUG_CONVERT should report frequencies. + print <len_cvt; + const int dstsize = cvt->len_cvt $lencvtop $multiple; +EOF + + # Upsampling (growing the buffer) needs to work backwards, since we + # overwrite the buffer as we go. + if ($upsample) { + print <buf + dstsize)) - $channels; + const $fctype *src = (($fctype *) (cvt->buf + cvt->len_cvt)) - $channels; + const $fctype *target = ((const $fctype *) cvt->buf) - $channels; +EOF + } else { + print <buf; + const $fctype *src = ($fctype *) cvt->buf; + const $fctype *target = (const $fctype *) (cvt->buf + dstsize); +EOF + } + + for (my $i = 0; $i < $channels; $i++) { + my $idx = ($upsample) ? (($channels - $i) - 1) : $i; + my $val = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, "src[$idx]"); + print <= 0; $i--) { + my $dsti = $i + $channels; + print <= 0; $i--) { + my $dsti = $i; + print <= 0; $i--) { + my $dsti = $i + ($channels * 3); + print <= 0; $i--) { + my $dsti = $i + ($channels * 2); + print <= 0; $i--) { + my $dsti = $i + ($channels * 1); + print <= 0; $i--) { + my $dsti = $i + ($channels * 0); + print <len_cvt = dstsize; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index] (cvt, format); + } +} + +EOF + +} + +sub buildResamplers { + foreach (@audiotypes) { + my $from = $_; + foreach (@channels) { + my $channel = $_; + for (my $multiple = 2; $multiple <= 4; $multiple += 2) { + buildMultipleResampleFunc($from, $channel, 1, $multiple); + buildMultipleResampleFunc($from, $channel, 0, $multiple); + } + buildArbitraryResampleFunc($from, $channel, 1); + buildArbitraryResampleFunc($from, $channel, 0); + } + } + + print "const SDL_AudioRateFilters sdl_audio_rate_filters[] =\n{\n"; + foreach (@audiotypes) { + my $from = $_; + foreach (@channels) { + my $channel = $_; + for (my $multiple = 0; $multiple <= 4; $multiple += 2) { + for (my $upsample = 0; $upsample <= 1; $upsample++) { + my $hashid = getResamplerHashId($from, $channel, $upsample, $multiple); + my $sym = $funcs{$hashid}; + print(" { AUDIO_$from, $channel, $upsample, $multiple, $sym },\n"); + } + } + } + } + + print "};\n\n"; +} + + +# mainline ... + +outputHeader(); +buildTypeConverters(); +buildResamplers(); outputFooter(); exit 0;