diff options
author | melanson <melanson@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-02-02 22:45:39 +0000 |
---|---|---|
committer | melanson <melanson@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-02-02 22:45:39 +0000 |
commit | 80168a072df13df22f4782735cd5a7cd72743b4f (patch) | |
tree | e65a8f83929cc0427c46307a593b8c5726e78384 /roqav.c | |
parent | 9996ca0ac9ffa70efd3685beabb2fa1391ecb446 (diff) | |
download | mpv-80168a072df13df22f4782735cd5a7cd72743b4f.tar.bz2 mpv-80168a072df13df22f4782735cd5a7cd72743b4f.tar.xz |
further work on the RoQ audio decoder
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4487 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'roqav.c')
-rw-r--r-- | roqav.c | 57 |
1 files changed, 56 insertions, 1 deletions
@@ -1,17 +1,24 @@ /* RoQ A/V decoder for the MPlayer program by Mike Melanson - based on Dr. Tim Ferguson's RoQ document found at: + based on Dr. Tim Ferguson's RoQ document and accompanying source + code found at: http://www.csse.monash.edu.au/~timf/videocodec.html */ #include "config.h" #include "bswap.h" #include <stdio.h> +#include <stdlib.h> #define LE_16(x) (le2me_16(*(unsigned short *)(x))) #define LE_32(x) (le2me_32(*(unsigned int *)(x))) +#define CLAMP_S16(x) if (x < -32768) x = -32768; \ + else if (x > 32767) x = 32767; +#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; +// sign extend a 4-bit value + void *roq_decode_video_init(void) { } @@ -26,14 +33,62 @@ void roq_decode_video( { } +// Initialize the RoQ audio decoder, which is to say, initialize the table +// of squares. void *roq_decode_audio_init(void) { + short *square_array; + short square; + int i; + + square_array = (short *)malloc(256 * sizeof(short)); + if (!square_array) + return NULL; + + for (i = 0; i < 128; i++) + { + square = i * i; + square_array[i] = square; + square_array[i + 128] = -square; + } + + return square_array; } int roq_decode_audio( unsigned short *output, unsigned char *input, + int encoded_size, int channels, void *context) { + short *square_array = (short *)context; + int i; + int predictor[2]; + int channel_number = 0; + + // prepare the initial predictors + if (channels == 1) + predictor[0] = LE_16(&input[0]); + else + { + predictor[0] = input[1] << 8; + predictor[1] = input[0] << 8; + } + SE_16BIT(predictor[0]); + SE_16BIT(predictor[1]); + + // decode the samples + for (i = 2; i < encoded_size; i++) + { + predictor[channel_number] += square_array[input[i]]; + CLAMP_S16(predictor[channel_number]); + output[i - 2] = predictor[channel_number]; + + // toggle channel + channel_number ^= channels - 1; + } + + // return the number of samples decoded + return (encoded_size - 2); } |