summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2005-10-28 00:11:28 +0000
committerDave Chapman <dave@dchapman.com>2005-10-28 00:11:28 +0000
commitf1844c41663119b3061d8c16407cec0f300e2bbb (patch)
tree6dd5741fc8929780a4e15d50e9a66aadec25dd45 /apps
parent7da9477bc3401cbd90b2984f625f96f451ecaf6b (diff)
downloadrockbox-f1844c41663119b3061d8c16407cec0f300e2bbb.tar.gz
rockbox-f1844c41663119b3061d8c16407cec0f300e2bbb.tar.bz2
rockbox-f1844c41663119b3061d8c16407cec0f300e2bbb.zip
1) Always enable the DSP. 2) Change codec to output one 32-bit array per channel containing samples left-shifted to 28-bits (instead of 16-bit interleaved samples). 3) Remove the two 16KB internal predicterror_buffer arrays (we use the output arrays instead) 4) Small internal rearrangement of the code.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7667 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/codecs/alac.c23
-rw-r--r--apps/codecs/libalac/alac.c662
-rw-r--r--apps/codecs/libalac/decomp.h14
3 files changed, 354 insertions, 345 deletions
diff --git a/apps/codecs/alac.c b/apps/codecs/alac.c
index c049ca114d..d4823233f2 100644
--- a/apps/codecs/alac.c
+++ b/apps/codecs/alac.c
@@ -31,6 +31,7 @@ extern char iramend[];
#define destBufferSize (1024*16)
char inputBuffer[1024*32]; /* Input buffer */
+int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE] IBSS_ATTR;
size_t mdat_offset;
struct codec_api* rb;
struct codec_api* ci;
@@ -241,11 +242,10 @@ enum codec_status codec_start(struct codec_api* api)
uint32_t elapsedtime;
uint32_t sample_duration;
uint32_t sample_byte_size;
- int outputBytes;
+ int samplesdecoded;
unsigned int i;
unsigned char* buffer;
alac_file alac;
- int16_t* pDestBuffer;
/* Generic codec initialisation */
TEST_CODEC_API(api);
@@ -261,9 +261,10 @@ enum codec_status codec_start(struct codec_api* api)
ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512));
ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128));
+ ci->configure(CODEC_DSP_ENABLE, (bool *)true);
ci->configure(DSP_DITHER, (bool *)false);
- ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED);
- ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16));
+ ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED);
+ ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(28));
next_track:
@@ -275,12 +276,7 @@ enum codec_status codec_start(struct codec_api* api)
while (!rb->taginfo_ready)
rb->yield();
- if (rb->id3->frequency != NATIVE_FREQUENCY) {
- rb->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency));
- rb->configure(CODEC_DSP_ENABLE, (bool *)true);
- } else {
- rb->configure(CODEC_DSP_ENABLE, (bool *)false);
- }
+ ci->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency));
stream_create(&input_stream);
@@ -349,9 +345,8 @@ enum codec_status codec_start(struct codec_api* api)
}
/* Decode one block - returned samples will be host-endian */
- outputBytes = destBufferSize;
rb->yield();
- pDestBuffer=decode_frame(&alac, buffer, &outputBytes, rb->yield);
+ samplesdecoded=alac_decode_frame(&alac, buffer, outputbuffer, rb->yield);
/* Advance codec buffer - unless we did a read */
if ((char*)buffer!=(char*)inputBuffer) {
@@ -360,7 +355,9 @@ enum codec_status codec_start(struct codec_api* api)
/* Output the audio */
rb->yield();
- while(!ci->pcmbuf_insert((char*)pDestBuffer,outputBytes))
+ while(!ci->pcmbuf_insert_split(outputbuffer[0],
+ outputbuffer[1],
+ samplesdecoded*sizeof(int32_t)))
rb->yield();
/* Update the elapsed-time indicator */
diff --git a/apps/codecs/libalac/alac.c b/apps/codecs/libalac/alac.c
index f3bfada5b7..22d04d2def 100644
--- a/apps/codecs/libalac/alac.c
+++ b/apps/codecs/libalac/alac.c
@@ -51,10 +51,6 @@
int16_t predictor_coef_table[32] IBSS_ATTR;
int16_t predictor_coef_table_a[32] IBSS_ATTR;
int16_t predictor_coef_table_b[32] IBSS_ATTR;
-int32_t predicterror_buffer_a[4096];
-int32_t predicterror_buffer_b[4096];
-int32_t outputsamples_buffer_a[4096] IBSS_ATTR;
-int32_t outputsamples_buffer_b[4096] IBSS_ATTR;
void alac_set_info(alac_file *alac, char *inputbuffer)
{
@@ -609,9 +605,9 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer,
}
}
-void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b,
- int16_t *buffer_out,
- int numchannels, int numsamples,
+void deinterlace_16(int32_t* buffer0,
+ int32_t* buffer1,
+ int numsamples,
uint8_t interlacing_shift,
uint8_t interlacing_leftweight)
{
@@ -625,11 +621,13 @@ void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b,
{
int32_t difference, midright;
- midright = buffer_a[i];
- difference = buffer_b[i];
+ midright = buffer0[i];
+ difference = buffer1[i];
- buffer_out[i*numchannels] = (midright - ((difference * interlacing_leftweight) >> interlacing_shift)) + difference;
- buffer_out[i*numchannels + 1] = midright - ((difference * interlacing_leftweight) >> interlacing_shift);
+ buffer0[i] = ((midright - ((difference * interlacing_leftweight)
+ >> interlacing_shift)) + difference) << SCALE16;
+ buffer1[i] = (midright - ((difference * interlacing_leftweight)
+ >> interlacing_shift)) << SCALE16;
}
return;
@@ -638,406 +636,414 @@ void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b,
/* otherwise basic interlacing took place */
for (i = 0; i < numsamples; i++)
{
- buffer_out[i*numchannels] = buffer_a[i];
- buffer_out[i*numchannels + 1] = buffer_b[i];
+ buffer0[i] = buffer0[i] << SCALE16;
+ buffer1[i] = buffer1[i] << SCALE16;
}
}
-int16_t* decode_frame(alac_file *alac,
- unsigned char *inbuffer,
- int *outputsize,
- void (*yield)(void))
+
+static inline int decode_frame_mono(
+ alac_file *alac,
+ int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE],
+ void (*yield)(void))
{
- int channels;
- int16_t* outbuffer;
- int32_t outputsamples = alac->setinfo_max_samples_per_frame;
+ int hassize;
+ int isnotcompressed;
+ int readsamplesize;
+ int outputsamples = alac->setinfo_max_samples_per_frame;
- /* setup the stream */
- alac->input_buffer = inbuffer;
- alac->input_buffer_bitaccumulator = 0;
+ int wasted_bytes;
+ int ricemodifier;
- /* We can share the same buffer for outputbuffer
- and outputsamples_buffer_b - and hence have them both in IRAM*/
- outbuffer=(int16_t*)outputsamples_buffer_b;
- channels = readbits(alac, 3);
+ /* 2^result = something to do with output waiting.
+ * perhaps matters if we read > 1 frame in a pass?
+ */
+ readbits(alac, 4);
- *outputsize = outputsamples * alac->bytespersample;
+ readbits(alac, 12); /* unknown, skip 12 bits */
- switch(channels)
- {
- case 0: /* 1 channel */
- {
- int hassize;
- int isnotcompressed;
- int readsamplesize;
+ hassize = readbits(alac, 1); /* the output sample size is stored soon */
- int wasted_bytes;
- int ricemodifier;
+ wasted_bytes = readbits(alac, 2); /* unknown ? */
+ isnotcompressed = readbits(alac, 1); /* whether the frame is compressed */
- /* 2^result = something to do with output waiting.
- * perhaps matters if we read > 1 frame in a pass?
- */
- readbits(alac, 4);
+ if (hassize)
+ {
+ /* now read the number of samples,
+ * as a 32bit integer */
+ outputsamples = readbits(alac, 32);
+ }
- readbits(alac, 12); /* unknown, skip 12 bits */
+ readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8);
- hassize = readbits(alac, 1); /* the output sample size is stored soon */
+ if (!isnotcompressed)
+ { /* so it is compressed */
+ int predictor_coef_num;
+ int prediction_type;
+ int prediction_quantitization;
+ int i;
- wasted_bytes = readbits(alac, 2); /* unknown ? */
+ /* skip 16 bits, not sure what they are. seem to be used in
+ * two channel case */
+ readbits(alac, 8);
+ readbits(alac, 8);
- isnotcompressed = readbits(alac, 1); /* whether the frame is compressed */
+ prediction_type = readbits(alac, 4);
+ prediction_quantitization = readbits(alac, 4);
- if (hassize)
+ ricemodifier = readbits(alac, 3);
+ predictor_coef_num = readbits(alac, 5);
+
+ /* read the predictor table */
+ for (i = 0; i < predictor_coef_num; i++)
{
- /* now read the number of samples,
- * as a 32bit integer */
- outputsamples = readbits(alac, 32);
- *outputsize = outputsamples * alac->bytespersample;
+ predictor_coef_table[i] = (int16_t)readbits(alac, 16);
}
- readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8);
+ if (wasted_bytes)
+ {
+ /* these bytes seem to have something to do with
+ * > 2 channel files.
+ */
+ //fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
+ }
- if (!isnotcompressed)
- { /* so it is compressed */
- int predictor_coef_num;
- int prediction_type;
- int prediction_quantitization;
- int i;
+ yield();
- /* skip 16 bits, not sure what they are. seem to be used in
- * two channel case */
- readbits(alac, 8);
- readbits(alac, 8);
+ basterdised_rice_decompress(alac,
+ outputbuffer[0],
+ outputsamples,
+ readsamplesize,
+ alac->setinfo_rice_initialhistory,
+ alac->setinfo_rice_kmodifier,
+ ricemodifier * alac->setinfo_rice_historymult / 4,
+ (1 << alac->setinfo_rice_kmodifier) - 1);
- prediction_type = readbits(alac, 4);
- prediction_quantitization = readbits(alac, 4);
+ yield();
- ricemodifier = readbits(alac, 3);
- predictor_coef_num = readbits(alac, 5);
+ if (prediction_type == 0)
+ { /* adaptive fir */
+ predictor_decompress_fir_adapt(outputbuffer[0],
+ outputbuffer[0],
+ outputsamples,
+ readsamplesize,
+ predictor_coef_table,
+ predictor_coef_num,
+ prediction_quantitization);
+ }
+ else
+ {
+ //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type);
+ /* i think the only other prediction type (or perhaps this is just a
+ * boolean?) runs adaptive fir twice.. like:
+ * predictor_decompress_fir_adapt(predictor_error, tempout, ...)
+ * predictor_decompress_fir_adapt(predictor_error, outputsamples ...)
+ * little strange..
+ */
+ }
- /* read the predictor table */
- for (i = 0; i < predictor_coef_num; i++)
+ }
+ else
+ { /* not compressed, easy case */
+ if (readsamplesize <= 16)
+ {
+ int i;
+ for (i = 0; i < outputsamples; i++)
{
- predictor_coef_table[i] = (int16_t)readbits(alac, 16);
- }
+ int32_t audiobits = readbits(alac, readsamplesize);
- if (wasted_bytes)
- {
- /* these bytes seem to have something to do with
- * > 2 channel files.
- */
- //fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
- }
+ audiobits = SIGN_EXTENDED32(audiobits, readsamplesize);
- yield();
-
- basterdised_rice_decompress(alac,
- predicterror_buffer_a,
- outputsamples,
- readsamplesize,
- alac->setinfo_rice_initialhistory,
- alac->setinfo_rice_kmodifier,
- ricemodifier * alac->setinfo_rice_historymult / 4,
- (1 << alac->setinfo_rice_kmodifier) - 1);
-
- yield();
-
- if (prediction_type == 0)
- { /* adaptive fir */
- predictor_decompress_fir_adapt(predicterror_buffer_a,
- outputsamples_buffer_a,
- outputsamples,
- readsamplesize,
- predictor_coef_table,
- predictor_coef_num,
- prediction_quantitization);
+ outputbuffer[0][i] = audiobits;
}
- else
- {
- //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type);
- /* i think the only other prediction type (or perhaps this is just a
- * boolean?) runs adaptive fir twice.. like:
- * predictor_decompress_fir_adapt(predictor_error, tempout, ...)
- * predictor_decompress_fir_adapt(predictor_error, outputsamples ...)
- * little strange..
- */
- }
-
}
else
- { /* not compressed, easy case */
- if (readsamplesize <= 16)
- {
- int i;
- for (i = 0; i < outputsamples; i++)
- {
- int32_t audiobits = readbits(alac, readsamplesize);
-
- audiobits = SIGN_EXTENDED32(audiobits, readsamplesize);
-
- outputsamples_buffer_a[i] = audiobits;
- }
- }
- else
+ {
+ int i;
+ for (i = 0; i < outputsamples; i++)
{
- int i;
- for (i = 0; i < outputsamples; i++)
- {
- int32_t audiobits;
+ int32_t audiobits;
- audiobits = readbits(alac, 16);
- /* special case of sign extension..
- * as we'll be ORing the low 16bits into this */
- audiobits = audiobits << 16;
- audiobits = audiobits >> (32 - readsamplesize);
+ audiobits = readbits(alac, 16);
+ /* special case of sign extension..
+ * as we'll be ORing the low 16bits into this */
+ audiobits = audiobits << 16;
+ audiobits = audiobits >> (32 - readsamplesize);
- audiobits |= readbits(alac, readsamplesize - 16);
+ audiobits |= readbits(alac, readsamplesize - 16);
- outputsamples_buffer_a[i] = audiobits;
- }
+ outputbuffer[0][i] = audiobits;
}
- /* wasted_bytes = 0; // unused */
}
+ /* wasted_bytes = 0; // unused */
+ }
- yield();
+ yield();
- switch(alac->setinfo_sample_size)
- {
- case 16:
+ switch(alac->setinfo_sample_size)
+ {
+ case 16:
+ {
+ int i;
+ for (i = 0; i < outputsamples; i++)
{
- int i;
- for (i = 0; i < outputsamples; i++)
- {
- /* Output mono data as stereo */
- outbuffer[i*2] = outputsamples_buffer_a[i];
- outbuffer[i*2+1] = outputsamples_buffer_a[i];
- }
- break;
- }
- case 20:
- case 24:
- case 32:
- //fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
- break;
- default:
- break;
+ /* Output mono data as stereo */
+ outputbuffer[0][i] = outputbuffer[0][i] << SCALE16;
+ outputbuffer[1][i] = outputbuffer[0][i];
}
break;
}
- case 1: /* 2 channels */
+ case 20:
+ case 24:
+ case 32:
+ //fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
+ break;
+ default:
+ break;
+ }
+
+ return outputsamples;
+}
+
+static inline int decode_frame_stereo(
+ alac_file *alac,
+ int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE],
+ void (*yield)(void))
+{
+ int hassize;
+ int isnotcompressed;
+ int readsamplesize;
+ int outputsamples = alac->setinfo_max_samples_per_frame;
+ int wasted_bytes;
+
+ uint8_t interlacing_shift;
+ uint8_t interlacing_leftweight;
+
+ /* 2^result = something to do with output waiting.
+ * perhaps matters if we read > 1 frame in a pass?
+ */
+ readbits(alac, 4);
+
+ readbits(alac, 12); /* unknown, skip 12 bits */
+
+ hassize = readbits(alac, 1); /* the output sample size is stored soon */
+
+ wasted_bytes = readbits(alac, 2); /* unknown ? */
+
+ isnotcompressed = readbits(alac, 1); /* whether the frame is compressed */
+
+ if (hassize)
{
- int hassize;
- int isnotcompressed;
- int readsamplesize;
+ /* now read the number of samples,
+ * as a 32bit integer */
+ outputsamples = readbits(alac, 32);
+ }
- int wasted_bytes;
+ readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + 1;
- uint8_t interlacing_shift;
- uint8_t interlacing_leftweight;
+ yield();
+ if (!isnotcompressed)
+ { /* compressed */
+ int predictor_coef_num_a;
+ int prediction_type_a;
+ int prediction_quantitization_a;
+ int ricemodifier_a;
- /* 2^result = something to do with output waiting.
- * perhaps matters if we read > 1 frame in a pass?
- */
- readbits(alac, 4);
+ int predictor_coef_num_b;
+ int prediction_type_b;
+ int prediction_quantitization_b;
+ int ricemodifier_b;
- readbits(alac, 12); /* unknown, skip 12 bits */
+ int i;
- hassize = readbits(alac, 1); /* the output sample size is stored soon */
+ interlacing_shift = readbits(alac, 8);
+ interlacing_leftweight = readbits(alac, 8);
- wasted_bytes = readbits(alac, 2); /* unknown ? */
+ /******** channel 1 ***********/
+ prediction_type_a = readbits(alac, 4);
+ prediction_quantitization_a = readbits(alac, 4);
- isnotcompressed = readbits(alac, 1); /* whether the frame is compressed */
+ ricemodifier_a = readbits(alac, 3);
+ predictor_coef_num_a = readbits(alac, 5);
- if (hassize)
+ /* read the predictor table */
+ for (i = 0; i < predictor_coef_num_a; i++)
{
- /* now read the number of samples,
- * as a 32bit integer */
- outputsamples = readbits(alac, 32);
- *outputsize = outputsamples * alac->bytespersample;
+ predictor_coef_table_a[i] = (int16_t)readbits(alac, 16);
}
- readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + 1;
-
- yield();
- if (!isnotcompressed)
- { /* compressed */
- int predictor_coef_num_a;
- int prediction_type_a;
- int prediction_quantitization_a;
- int ricemodifier_a;
-
- int predictor_coef_num_b;
- int prediction_type_b;
- int prediction_quantitization_b;
- int ricemodifier_b;
+ /******** channel 2 *********/
+ prediction_type_b = readbits(alac, 4);
+ prediction_quantitization_b = readbits(alac, 4);
- int i;
+ ricemodifier_b = readbits(alac, 3);
+ predictor_coef_num_b = readbits(alac, 5);
- interlacing_shift = readbits(alac, 8);
- interlacing_leftweight = readbits(alac, 8);
+ /* read the predictor table */
+ for (i = 0; i < predictor_coef_num_b; i++)
+ {
+ predictor_coef_table_b[i] = (int16_t)readbits(alac, 16);
+ }
- /******** channel 1 ***********/
- prediction_type_a = readbits(alac, 4);
- prediction_quantitization_a = readbits(alac, 4);
+ /*********************/
+ if (wasted_bytes)
+ { /* see mono case */
+ //fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
+ }
- ricemodifier_a = readbits(alac, 3);
- predictor_coef_num_a = readbits(alac, 5);
+ yield();
+ /* channel 1 */
+ basterdised_rice_decompress(alac,
+ outputbuffer[0],
+ outputsamples,
+ readsamplesize,
+ alac->setinfo_rice_initialhistory,
+ alac->setinfo_rice_kmodifier,
+ ricemodifier_a * alac->setinfo_rice_historymult / 4,
+ (1 << alac->setinfo_rice_kmodifier) - 1);
- /* read the predictor table */
- for (i = 0; i < predictor_coef_num_a; i++)
- {
- predictor_coef_table_a[i] = (int16_t)readbits(alac, 16);
- }
+ yield();
+ if (prediction_type_a == 0)
+ { /* adaptive fir */
+ predictor_decompress_fir_adapt(outputbuffer[0],
+ outputbuffer[0],
+ outputsamples,
+ readsamplesize,
+ predictor_coef_table_a,
+ predictor_coef_num_a,
+ prediction_quantitization_a);
+ }
+ else
+ { /* see mono case */
+ //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_a);
+ }
- /******** channel 2 *********/
- prediction_type_b = readbits(alac, 4);
- prediction_quantitization_b = readbits(alac, 4);
+ yield();
- ricemodifier_b = readbits(alac, 3);
- predictor_coef_num_b = readbits(alac, 5);
+ /* channel 2 */
+ basterdised_rice_decompress(alac,
+ outputbuffer[1],
+ outputsamples,
+ readsamplesize,
+ alac->setinfo_rice_initialhistory,
+ alac->setinfo_rice_kmodifier,
+ ricemodifier_b * alac->setinfo_rice_historymult / 4,
+ (1 << alac->setinfo_rice_kmodifier) - 1);
- /* read the predictor table */
- for (i = 0; i < predictor_coef_num_b; i++)
+ yield();
+ if (prediction_type_b == 0)
+ { /* adaptive fir */
+ predictor_decompress_fir_adapt(outputbuffer[1],
+ outputbuffer[1],
+ outputsamples,
+ readsamplesize,
+ predictor_coef_table_b,
+ predictor_coef_num_b,
+ prediction_quantitization_b);
+ }
+ else
+ {
+ //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_b);
+ }
+ }
+ else
+ { /* not compressed, easy case */
+ if (alac->setinfo_sample_size <= 16)
+ {
+ int i;
+ for (i = 0; i < outputsamples; i++)
{
- predictor_coef_table_b[i] = (int16_t)readbits(alac, 16);
- }
+ int32_t audiobits_a, audiobits_b;
- /*********************/
- if (wasted_bytes)
- { /* see mono case */
- //fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
- }
+ audiobits_a = readbits(alac, alac->setinfo_sample_size);
+ audiobits_b = readbits(alac, alac->setinfo_sample_size);
- yield();
- /* channel 1 */
- basterdised_rice_decompress(alac,
- predicterror_buffer_a,
- outputsamples,
- readsamplesize,
- alac->setinfo_rice_initialhistory,
- alac->setinfo_rice_kmodifier,
- ricemodifier_a * alac->setinfo_rice_historymult / 4,
- (1 << alac->setinfo_rice_kmodifier) - 1);
-
- yield();
- if (prediction_type_a == 0)
- { /* adaptive fir */
- predictor_decompress_fir_adapt(predicterror_buffer_a,
- outputsamples_buffer_a,
- outputsamples,
- readsamplesize,
- predictor_coef_table_a,
- predictor_coef_num_a,
- prediction_quantitization_a);
- }
- else
- { /* see mono case */
- //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_a);
- }
+ audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size);
+ audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size);
- yield();
-
- /* channel 2 */
- basterdised_rice_decompress(alac,
- predicterror_buffer_b,
- outputsamples,
- readsamplesize,
- alac->setinfo_rice_initialhistory,
- alac->setinfo_rice_kmodifier,
- ricemodifier_b * alac->setinfo_rice_historymult / 4,
- (1 << alac->setinfo_rice_kmodifier) - 1);
-
- yield();
- if (prediction_type_b == 0)
- { /* adaptive fir */
- predictor_decompress_fir_adapt(predicterror_buffer_b,
- outputsamples_buffer_b,
- outputsamples,
- readsamplesize,
- predictor_coef_table_b,
- predictor_coef_num_b,
- prediction_quantitization_b);
- }
- else
- {
- //fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_b);
+ outputbuffer[0][i] = audiobits_a;
+ outputbuffer[1][i] = audiobits_b;
}
}
else
- { /* not compressed, easy case */
- if (alac->setinfo_sample_size <= 16)
+ {
+ int i;
+ for (i = 0; i < outputsamples; i++)
{
- int i;
- for (i = 0; i < outputsamples; i++)
- {
- int32_t audiobits_a, audiobits_b;
+ int32_t audiobits_a, audiobits_b;
- audiobits_a = readbits(alac, alac->setinfo_sample_size);
- audiobits_b = readbits(alac, alac->setinfo_sample_size);
+ audiobits_a = readbits(alac, 16);
+ audiobits_a = audiobits_a << 16;
+ audiobits_a = audiobits_a >> (32 - alac->setinfo_sample_size);
+ audiobits_a |= readbits(alac, alac->setinfo_sample_size - 16);
- audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size);
- audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size);
+ audiobits_b = readbits(alac, 16);
+ audiobits_b = audiobits_b << 16;
+ audiobits_b = audiobits_b >> (32 - alac->setinfo_sample_size);
+ audiobits_b |= readbits(alac, alac->setinfo_sample_size - 16);
- outputsamples_buffer_a[i] = audiobits_a;
- outputsamples_buffer_b[i] = audiobits_b;
- }
+ outputbuffer[0][i] = audiobits_a;
+ outputbuffer[1][i] = audiobits_b;
}
- else
- {
- int i;
- for (i = 0; i < outputsamples; i++)
- {
- int32_t audiobits_a, audiobits_b;
+ }
+ /* wasted_bytes = 0; */
+ interlacing_shift = 0;
+ interlacing_leftweight = 0;
+ }
- audiobits_a = readbits(alac, 16);
- audiobits_a = audiobits_a << 16;
- audiobits_a = audiobits_a >> (32 - alac->setinfo_sample_size);
- audiobits_a |= readbits(alac, alac->setinfo_sample_size - 16);
+ yield();
- audiobits_b = readbits(alac, 16);
- audiobits_b = audiobits_b << 16;
- audiobits_b = audiobits_b >> (32 - alac->setinfo_sample_size);
- audiobits_b |= readbits(alac, alac->setinfo_sample_size - 16);
+ switch(alac->setinfo_sample_size)
+ {
+ case 16:
+ {
+ deinterlace_16(outputbuffer[0],
+ outputbuffer[1],
+ outputsamples,
+ interlacing_shift,
+ interlacing_leftweight);
+ break;
+ }
+ case 20:
+ case 24:
+ case 32:
+ //fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
+ break;
+ default:
+ break;
+ }
+ return outputsamples;
+}
- outputsamples_buffer_a[i] = audiobits_a;
- outputsamples_buffer_b[i] = audiobits_b;
- }
- }
- /* wasted_bytes = 0; */
- interlacing_shift = 0;
- interlacing_leftweight = 0;
- }
+int alac_decode_frame(alac_file *alac,
+ unsigned char *inbuffer,
+ int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE],
+ void (*yield)(void))
+{
+ int channels;
+ int outputsamples;
- yield();
+ /* setup the stream */
+ alac->input_buffer = inbuffer;
+ alac->input_buffer_bitaccumulator = 0;
- switch(alac->setinfo_sample_size)
- {
- case 16:
- {
- deinterlace_16(outputsamples_buffer_a,
- outputsamples_buffer_b,
- (int16_t*)outbuffer,
- alac->numchannels,
- outputsamples,
- interlacing_shift,
- interlacing_leftweight);
- break;
- }
- case 20:
- case 24:
- case 32:
- //fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
+ channels = readbits(alac, 3);
+
+ /* TODO: The mono and stereo functions should be combined. */
+ switch(channels)
+ {
+ case 0: /* 1 channel */
+ outputsamples=decode_frame_mono(alac,outputbuffer,yield);
break;
- default:
+ case 1: /* 2 channels */
+ outputsamples=decode_frame_stereo(alac,outputbuffer,yield);
break;
- }
-
- break;
- }
+ default: /* Unsupported */
+ return -1;
}
- return outbuffer;
+ return outputsamples;
}
void create_alac(int samplesize, int numchannels, alac_file* alac)
diff --git a/apps/codecs/libalac/decomp.h b/apps/codecs/libalac/decomp.h
index 15b8910681..caa9f90059 100644
--- a/apps/codecs/libalac/decomp.h
+++ b/apps/codecs/libalac/decomp.h
@@ -1,6 +1,12 @@
#ifndef __ALAC__DECOMP_H
#define __ALAC__DECOMP_H
+/* Always output samples shifted to 28 bits */
+#define ALAC_OUTPUT_DEPTH 28
+#define SCALE16 (ALAC_OUTPUT_DEPTH - 16)
+#define ALAC_MAX_CHANNELS 2
+#define ALAC_BLOCKSIZE 4096 /* Number of samples per channel per block */
+
typedef struct
{
unsigned char *input_buffer;
@@ -26,10 +32,10 @@ typedef struct
} alac_file;
void create_alac(int samplesize, int numchannels, alac_file* alac);
-int16_t* decode_frame(alac_file *alac,
- unsigned char *inbuffer,
- int *outputsize,
- void (*yield)(void));
+int alac_decode_frame(alac_file *alac,
+ unsigned char *inbuffer,
+ int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE],
+ void (*yield)(void));
void alac_set_info(alac_file *alac, char *inputbuffer);
#endif /* __ALAC__DECOMP_H */