mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-22 19:42:40 -05:00
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
This commit is contained in:
parent
7da9477bc3
commit
f1844c4166
3 changed files with 420 additions and 411 deletions
|
|
@ -31,6 +31,7 @@ extern char iramend[];
|
||||||
#define destBufferSize (1024*16)
|
#define destBufferSize (1024*16)
|
||||||
|
|
||||||
char inputBuffer[1024*32]; /* Input buffer */
|
char inputBuffer[1024*32]; /* Input buffer */
|
||||||
|
int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE] IBSS_ATTR;
|
||||||
size_t mdat_offset;
|
size_t mdat_offset;
|
||||||
struct codec_api* rb;
|
struct codec_api* rb;
|
||||||
struct codec_api* ci;
|
struct codec_api* ci;
|
||||||
|
|
@ -241,11 +242,10 @@ enum codec_status codec_start(struct codec_api* api)
|
||||||
uint32_t elapsedtime;
|
uint32_t elapsedtime;
|
||||||
uint32_t sample_duration;
|
uint32_t sample_duration;
|
||||||
uint32_t sample_byte_size;
|
uint32_t sample_byte_size;
|
||||||
int outputBytes;
|
int samplesdecoded;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned char* buffer;
|
unsigned char* buffer;
|
||||||
alac_file alac;
|
alac_file alac;
|
||||||
int16_t* pDestBuffer;
|
|
||||||
|
|
||||||
/* Generic codec initialisation */
|
/* Generic codec initialisation */
|
||||||
TEST_CODEC_API(api);
|
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_WATERMARK, (int *)(1024*512));
|
||||||
ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128));
|
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_DITHER, (bool *)false);
|
||||||
ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED);
|
ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED);
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16));
|
ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(28));
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
|
|
||||||
|
|
@ -275,12 +276,7 @@ enum codec_status codec_start(struct codec_api* api)
|
||||||
while (!rb->taginfo_ready)
|
while (!rb->taginfo_ready)
|
||||||
rb->yield();
|
rb->yield();
|
||||||
|
|
||||||
if (rb->id3->frequency != NATIVE_FREQUENCY) {
|
ci->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->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);
|
|
||||||
}
|
|
||||||
|
|
||||||
stream_create(&input_stream);
|
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 */
|
/* Decode one block - returned samples will be host-endian */
|
||||||
outputBytes = destBufferSize;
|
|
||||||
rb->yield();
|
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 */
|
/* Advance codec buffer - unless we did a read */
|
||||||
if ((char*)buffer!=(char*)inputBuffer) {
|
if ((char*)buffer!=(char*)inputBuffer) {
|
||||||
|
|
@ -360,7 +355,9 @@ enum codec_status codec_start(struct codec_api* api)
|
||||||
|
|
||||||
/* Output the audio */
|
/* Output the audio */
|
||||||
rb->yield();
|
rb->yield();
|
||||||
while(!ci->pcmbuf_insert((char*)pDestBuffer,outputBytes))
|
while(!ci->pcmbuf_insert_split(outputbuffer[0],
|
||||||
|
outputbuffer[1],
|
||||||
|
samplesdecoded*sizeof(int32_t)))
|
||||||
rb->yield();
|
rb->yield();
|
||||||
|
|
||||||
/* Update the elapsed-time indicator */
|
/* Update the elapsed-time indicator */
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,6 @@
|
||||||
int16_t predictor_coef_table[32] IBSS_ATTR;
|
int16_t predictor_coef_table[32] IBSS_ATTR;
|
||||||
int16_t predictor_coef_table_a[32] IBSS_ATTR;
|
int16_t predictor_coef_table_a[32] IBSS_ATTR;
|
||||||
int16_t predictor_coef_table_b[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)
|
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,
|
void deinterlace_16(int32_t* buffer0,
|
||||||
int16_t *buffer_out,
|
int32_t* buffer1,
|
||||||
int numchannels, int numsamples,
|
int numsamples,
|
||||||
uint8_t interlacing_shift,
|
uint8_t interlacing_shift,
|
||||||
uint8_t interlacing_leftweight)
|
uint8_t interlacing_leftweight)
|
||||||
{
|
{
|
||||||
|
|
@ -625,11 +621,13 @@ void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b,
|
||||||
{
|
{
|
||||||
int32_t difference, midright;
|
int32_t difference, midright;
|
||||||
|
|
||||||
midright = buffer_a[i];
|
midright = buffer0[i];
|
||||||
difference = buffer_b[i];
|
difference = buffer1[i];
|
||||||
|
|
||||||
buffer_out[i*numchannels] = (midright - ((difference * interlacing_leftweight) >> interlacing_shift)) + difference;
|
buffer0[i] = ((midright - ((difference * interlacing_leftweight)
|
||||||
buffer_out[i*numchannels + 1] = midright - ((difference * interlacing_leftweight) >> interlacing_shift);
|
>> interlacing_shift)) + difference) << SCALE16;
|
||||||
|
buffer1[i] = (midright - ((difference * interlacing_leftweight)
|
||||||
|
>> interlacing_shift)) << SCALE16;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -638,406 +636,414 @@ void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b,
|
||||||
/* otherwise basic interlacing took place */
|
/* otherwise basic interlacing took place */
|
||||||
for (i = 0; i < numsamples; i++)
|
for (i = 0; i < numsamples; i++)
|
||||||
{
|
{
|
||||||
buffer_out[i*numchannels] = buffer_a[i];
|
buffer0[i] = buffer0[i] << SCALE16;
|
||||||
buffer_out[i*numchannels + 1] = buffer_b[i];
|
buffer1[i] = buffer1[i] << SCALE16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t* decode_frame(alac_file *alac,
|
|
||||||
unsigned char *inbuffer,
|
static inline int decode_frame_mono(
|
||||||
int *outputsize,
|
alac_file *alac,
|
||||||
void (*yield)(void))
|
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;
|
||||||
|
int ricemodifier;
|
||||||
|
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
/* now read the number of samples,
|
||||||
|
* as a 32bit integer */
|
||||||
|
outputsamples = readbits(alac, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8);
|
||||||
|
|
||||||
|
if (!isnotcompressed)
|
||||||
|
{ /* so it is compressed */
|
||||||
|
int predictor_coef_num;
|
||||||
|
int prediction_type;
|
||||||
|
int prediction_quantitization;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* skip 16 bits, not sure what they are. seem to be used in
|
||||||
|
* two channel case */
|
||||||
|
readbits(alac, 8);
|
||||||
|
readbits(alac, 8);
|
||||||
|
|
||||||
|
prediction_type = readbits(alac, 4);
|
||||||
|
prediction_quantitization = readbits(alac, 4);
|
||||||
|
|
||||||
|
ricemodifier = readbits(alac, 3);
|
||||||
|
predictor_coef_num = readbits(alac, 5);
|
||||||
|
|
||||||
|
/* read the predictor table */
|
||||||
|
for (i = 0; i < predictor_coef_num; i++)
|
||||||
|
{
|
||||||
|
predictor_coef_table[i] = (int16_t)readbits(alac, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasted_bytes)
|
||||||
|
{
|
||||||
|
/* these bytes seem to have something to do with
|
||||||
|
* > 2 channel files.
|
||||||
|
*/
|
||||||
|
//fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
yield();
|
||||||
|
|
||||||
|
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..
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
outputbuffer[0][i] = audiobits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < outputsamples; i++)
|
||||||
|
{
|
||||||
|
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, readsamplesize - 16);
|
||||||
|
|
||||||
|
outputbuffer[0][i] = audiobits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* wasted_bytes = 0; // unused */
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
|
||||||
|
switch(alac->setinfo_sample_size)
|
||||||
|
{
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < outputsamples; i++)
|
||||||
|
{
|
||||||
|
/* Output mono data as stereo */
|
||||||
|
outputbuffer[0][i] = outputbuffer[0][i] << SCALE16;
|
||||||
|
outputbuffer[1][i] = outputbuffer[0][i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
/* now read the number of samples,
|
||||||
|
* as a 32bit integer */
|
||||||
|
outputsamples = readbits(alac, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
interlacing_shift = readbits(alac, 8);
|
||||||
|
interlacing_leftweight = readbits(alac, 8);
|
||||||
|
|
||||||
|
/******** channel 1 ***********/
|
||||||
|
prediction_type_a = readbits(alac, 4);
|
||||||
|
prediction_quantitization_a = readbits(alac, 4);
|
||||||
|
|
||||||
|
ricemodifier_a = readbits(alac, 3);
|
||||||
|
predictor_coef_num_a = readbits(alac, 5);
|
||||||
|
|
||||||
|
/* read the predictor table */
|
||||||
|
for (i = 0; i < predictor_coef_num_a; i++)
|
||||||
|
{
|
||||||
|
predictor_coef_table_a[i] = (int16_t)readbits(alac, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******** channel 2 *********/
|
||||||
|
prediction_type_b = readbits(alac, 4);
|
||||||
|
prediction_quantitization_b = readbits(alac, 4);
|
||||||
|
|
||||||
|
ricemodifier_b = readbits(alac, 3);
|
||||||
|
predictor_coef_num_b = readbits(alac, 5);
|
||||||
|
|
||||||
|
/* read the predictor table */
|
||||||
|
for (i = 0; i < predictor_coef_num_b; i++)
|
||||||
|
{
|
||||||
|
predictor_coef_table_b[i] = (int16_t)readbits(alac, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
if (wasted_bytes)
|
||||||
|
{ /* see mono case */
|
||||||
|
//fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
int32_t audiobits_a, audiobits_b;
|
||||||
|
|
||||||
|
audiobits_a = readbits(alac, alac->setinfo_sample_size);
|
||||||
|
audiobits_b = readbits(alac, alac->setinfo_sample_size);
|
||||||
|
|
||||||
|
audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size);
|
||||||
|
audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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_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);
|
||||||
|
|
||||||
|
outputbuffer[0][i] = audiobits_a;
|
||||||
|
outputbuffer[1][i] = audiobits_b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* wasted_bytes = 0; */
|
||||||
|
interlacing_shift = 0;
|
||||||
|
interlacing_leftweight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int alac_decode_frame(alac_file *alac,
|
||||||
|
unsigned char *inbuffer,
|
||||||
|
int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE],
|
||||||
|
void (*yield)(void))
|
||||||
{
|
{
|
||||||
int channels;
|
int channels;
|
||||||
int16_t* outbuffer;
|
int outputsamples;
|
||||||
int32_t outputsamples = alac->setinfo_max_samples_per_frame;
|
|
||||||
|
|
||||||
/* setup the stream */
|
/* setup the stream */
|
||||||
alac->input_buffer = inbuffer;
|
alac->input_buffer = inbuffer;
|
||||||
alac->input_buffer_bitaccumulator = 0;
|
alac->input_buffer_bitaccumulator = 0;
|
||||||
|
|
||||||
/* 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);
|
channels = readbits(alac, 3);
|
||||||
|
|
||||||
*outputsize = outputsamples * alac->bytespersample;
|
/* TODO: The mono and stereo functions should be combined. */
|
||||||
|
|
||||||
switch(channels)
|
switch(channels)
|
||||||
{
|
{
|
||||||
case 0: /* 1 channel */
|
case 0: /* 1 channel */
|
||||||
{
|
outputsamples=decode_frame_mono(alac,outputbuffer,yield);
|
||||||
int hassize;
|
|
||||||
int isnotcompressed;
|
|
||||||
int readsamplesize;
|
|
||||||
|
|
||||||
int wasted_bytes;
|
|
||||||
int ricemodifier;
|
|
||||||
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
/* now read the number of samples,
|
|
||||||
* as a 32bit integer */
|
|
||||||
outputsamples = readbits(alac, 32);
|
|
||||||
*outputsize = outputsamples * alac->bytespersample;
|
|
||||||
}
|
|
||||||
|
|
||||||
readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8);
|
|
||||||
|
|
||||||
if (!isnotcompressed)
|
|
||||||
{ /* so it is compressed */
|
|
||||||
int predictor_coef_num;
|
|
||||||
int prediction_type;
|
|
||||||
int prediction_quantitization;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* skip 16 bits, not sure what they are. seem to be used in
|
|
||||||
* two channel case */
|
|
||||||
readbits(alac, 8);
|
|
||||||
readbits(alac, 8);
|
|
||||||
|
|
||||||
prediction_type = readbits(alac, 4);
|
|
||||||
prediction_quantitization = readbits(alac, 4);
|
|
||||||
|
|
||||||
ricemodifier = readbits(alac, 3);
|
|
||||||
predictor_coef_num = readbits(alac, 5);
|
|
||||||
|
|
||||||
/* read the predictor table */
|
|
||||||
for (i = 0; i < predictor_coef_num; i++)
|
|
||||||
{
|
|
||||||
predictor_coef_table[i] = (int16_t)readbits(alac, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wasted_bytes)
|
|
||||||
{
|
|
||||||
/* these bytes seem to have something to do with
|
|
||||||
* > 2 channel files.
|
|
||||||
*/
|
|
||||||
//fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
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, readsamplesize - 16);
|
|
||||||
|
|
||||||
outputsamples_buffer_a[i] = audiobits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* wasted_bytes = 0; // unused */
|
|
||||||
}
|
|
||||||
|
|
||||||
yield();
|
|
||||||
|
|
||||||
switch(alac->setinfo_sample_size)
|
|
||||||
{
|
|
||||||
case 16:
|
|
||||||
{
|
|
||||||
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;
|
break;
|
||||||
}
|
case 1: /* 2 channels */
|
||||||
case 20:
|
outputsamples=decode_frame_stereo(alac,outputbuffer,yield);
|
||||||
case 24:
|
|
||||||
case 32:
|
|
||||||
//fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default: /* Unsupported */
|
||||||
break;
|
return -1;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case 1: /* 2 channels */
|
return outputsamples;
|
||||||
{
|
|
||||||
int hassize;
|
|
||||||
int isnotcompressed;
|
|
||||||
int readsamplesize;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
/* now read the number of samples,
|
|
||||||
* as a 32bit integer */
|
|
||||||
outputsamples = readbits(alac, 32);
|
|
||||||
*outputsize = outputsamples * alac->bytespersample;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
interlacing_shift = readbits(alac, 8);
|
|
||||||
interlacing_leftweight = readbits(alac, 8);
|
|
||||||
|
|
||||||
/******** channel 1 ***********/
|
|
||||||
prediction_type_a = readbits(alac, 4);
|
|
||||||
prediction_quantitization_a = readbits(alac, 4);
|
|
||||||
|
|
||||||
ricemodifier_a = readbits(alac, 3);
|
|
||||||
predictor_coef_num_a = readbits(alac, 5);
|
|
||||||
|
|
||||||
/* read the predictor table */
|
|
||||||
for (i = 0; i < predictor_coef_num_a; i++)
|
|
||||||
{
|
|
||||||
predictor_coef_table_a[i] = (int16_t)readbits(alac, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******** channel 2 *********/
|
|
||||||
prediction_type_b = readbits(alac, 4);
|
|
||||||
prediction_quantitization_b = readbits(alac, 4);
|
|
||||||
|
|
||||||
ricemodifier_b = readbits(alac, 3);
|
|
||||||
predictor_coef_num_b = readbits(alac, 5);
|
|
||||||
|
|
||||||
/* read the predictor table */
|
|
||||||
for (i = 0; i < predictor_coef_num_b; i++)
|
|
||||||
{
|
|
||||||
predictor_coef_table_b[i] = (int16_t)readbits(alac, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************/
|
|
||||||
if (wasted_bytes)
|
|
||||||
{ /* see mono case */
|
|
||||||
//fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ /* not compressed, easy case */
|
|
||||||
if (alac->setinfo_sample_size <= 16)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < outputsamples; i++)
|
|
||||||
{
|
|
||||||
int32_t audiobits_a, audiobits_b;
|
|
||||||
|
|
||||||
audiobits_a = readbits(alac, alac->setinfo_sample_size);
|
|
||||||
audiobits_b = readbits(alac, alac->setinfo_sample_size);
|
|
||||||
|
|
||||||
audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size);
|
|
||||||
audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size);
|
|
||||||
|
|
||||||
outputsamples_buffer_a[i] = audiobits_a;
|
|
||||||
outputsamples_buffer_b[i] = audiobits_b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < outputsamples; i++)
|
|
||||||
{
|
|
||||||
int32_t audiobits_a, audiobits_b;
|
|
||||||
|
|
||||||
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_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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* wasted_bytes = 0; */
|
|
||||||
interlacing_shift = 0;
|
|
||||||
interlacing_leftweight = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield();
|
|
||||||
|
|
||||||
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);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return outbuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_alac(int samplesize, int numchannels, alac_file* alac)
|
void create_alac(int samplesize, int numchannels, alac_file* alac)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
#ifndef __ALAC__DECOMP_H
|
#ifndef __ALAC__DECOMP_H
|
||||||
#define __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
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned char *input_buffer;
|
unsigned char *input_buffer;
|
||||||
|
|
@ -26,10 +32,10 @@ typedef struct
|
||||||
} alac_file;
|
} alac_file;
|
||||||
|
|
||||||
void create_alac(int samplesize, int numchannels, alac_file* alac);
|
void create_alac(int samplesize, int numchannels, alac_file* alac);
|
||||||
int16_t* decode_frame(alac_file *alac,
|
int alac_decode_frame(alac_file *alac,
|
||||||
unsigned char *inbuffer,
|
unsigned char *inbuffer,
|
||||||
int *outputsize,
|
int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE],
|
||||||
void (*yield)(void));
|
void (*yield)(void));
|
||||||
void alac_set_info(alac_file *alac, char *inputbuffer);
|
void alac_set_info(alac_file *alac, char *inputbuffer);
|
||||||
|
|
||||||
#endif /* __ALAC__DECOMP_H */
|
#endif /* __ALAC__DECOMP_H */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue