Mercurial > mplayer.hg
diff roqav.c @ 4486:e69bed07cb27
further work on the RoQ audio decoder
author | melanson |
---|---|
date | Sat, 02 Feb 2002 22:45:39 +0000 |
parents | 3da8c5706371 |
children | 026329111b09 |
line wrap: on
line diff
--- a/roqav.c Sat Feb 02 22:35:47 2002 +0000 +++ b/roqav.c Sat Feb 02 22:45:39 2002 +0000 @@ -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 @@ { } +// 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); }