From 673c78183bfc17fdd79c012e93b83fbe601ef3a3 Mon Sep 17 00:00:00 2001 From: malc Date: Thu, 20 Nov 2008 11:12:30 +0300 Subject: [PATCH] Audio decoder --- README | 4 +++ adpcm.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 adpcm.c diff --git a/README b/README index 81510ec..df11dd8 100644 --- a/README +++ b/README @@ -39,6 +39,10 @@ swizzling code: http://playstation2-linux.com/download/p2lsd/sparkys_swizzle_cod altivec code is based on: http://www.freevec.org/category/simd/algorithms/algebra/matrix_operations +adpcm decoder is slightly modified: + PSX VAG-Packer, hacked by bITmASTER@bigfoot.com + with block interleave figured out by Antti Huovilainen + Disorder handshakes ------------------- Skal, Unreal, Ex, Coderipper, dAS, Action, Vastator, pGeist, diff --git a/adpcm.c b/adpcm.c new file mode 100644 index 0000000..eef11e5 --- /dev/null +++ b/adpcm.c @@ -0,0 +1,96 @@ +/* Based on: + + PSX VAG-Packer, hacked by bITmASTER@bigfoot.com + + v0.1 +*/ + +/* Block interleave figured out by Antti Huovilainen. */ + +/* Usage: + $ cc -o adpcm adpcm.c + $ dd if=/path/to/sotc/dvd/XAD \ + | ./adpcm | sox -t raw -r 22050 -s -w -c 2 - -t ossdsp /dev/dsp +*/ + +#include +#include + +static const double f[5][2] = { { 0.0, 0.0 }, + { 60.0 / 64.0, 0.0 }, + { 115.0 / 64.0, -52.0 / 64.0 }, + { 98.0 / 64.0, -55.0 / 64.0 }, + { 122.0 / 64.0, -60.0 / 64.0 } }; + +int main (void) +{ + int predict_nr, shift_factor, flags; + int i, block = 0; + unsigned int d; + int s; + struct { + double s_1; + double s_2; + double s_11; + double s_21; + } ctxs[2] = {0}, *ctx = ctxs; + signed short int left[28*64], right[28*64]; + signed short int *chan = left; + double samples[28]; + + for (;;) { + signed char data[16]; + + if (fread (data, 16, 1, stdin) != 1) { + perror ("fread"); + exit (EXIT_FAILURE); + } + + if (data[1] == 7) break; + + predict_nr = data[0]; + shift_factor = predict_nr & 0xf; + predict_nr >>= 4; + + for (i = 0; i < 28; i += 2) { + d = data[i / 2 + 2]; + s = (d & 0xf) << 12; + if (s & 0x8000) + s |= 0xffff0000; + samples[i] = (double) (s >> shift_factor); + s = (d & 0xf0) << 8; + if (s & 0x8000) + s |= 0xffff0000; + samples[i+1] = (double) (s >> shift_factor); + } + + for (i = 0; i < 28; i++) { + samples[i] += ctx->s_1 * f[predict_nr][0] + ctx->s_2 * f[predict_nr][1]; + ctx->s_2 = ctx->s_1; + ctx->s_1 = samples[i]; + d = (int) (samples[i] + 0.5); + chan[i + block*28] = d; + } + + block++; + if (block == 64) { + if (chan == left) { + chan = right; + ctx = &ctxs[1]; + } + else { + chan = left; + ctx = &ctxs[0]; + + for (i = 0; i < 28*64; ++i) { + fputc (left[i] >> 8, stdout); + fputc (left[i], stdout); + fputc (right[i] >> 8, stdout); + fputc (right[i], stdout); + } + } + block = 0; + } + } + return 0; +} -- 2.11.4.GIT