1
0
Fork 0
forked from len0rd/rockbox

FS #10690: Add support for 24 bit ALAC files based on libalac 0.2.0

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24475 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Tom Ross 2010-02-03 00:37:24 +00:00
parent b2ffb3e08f
commit db64bf9ea4
2 changed files with 283 additions and 189 deletions

View file

@ -38,6 +38,8 @@
#include "codeclib.h"
#include "decomp.h"
#define SIGNEXTEND24(val) (((signed)val<<8)>>8)
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;
@ -168,141 +170,126 @@ static inline void unreadbits(alac_file *alac, int bits)
#define count_leading_zeros(x) bs_generic(x, BS_CLZ|BS_SHORT)
void basterdised_rice_decompress(alac_file *alac,
int32_t *output_buffer,
int output_size,
int readsamplesize, /* arg_10 */
int rice_initialhistory, /* arg424->b */
int rice_kmodifier, /* arg424->d */
int rice_historymult, /* arg424->c */
int rice_kmodifier_mask /* arg424->e */
) ICODE_ATTR_ALAC;
void basterdised_rice_decompress(alac_file *alac,
int32_t *output_buffer,
int output_size,
int readsamplesize, /* arg_10 */
int rice_initialhistory, /* arg424->b */
int rice_kmodifier, /* arg424->d */
int rice_historymult, /* arg424->c */
int rice_kmodifier_mask /* arg424->e */
)
#define RICE_THRESHOLD 8 // maximum number of bits for a rice prefix.
static inline int32_t entropy_decode_value(alac_file* alac,
int readsamplesize,
int k) ICODE_ATTR_ALAC;
static inline int32_t entropy_decode_value(alac_file* alac,
int readsamplesize,
int k)
{
int output_count;
unsigned int history = rice_initialhistory;
int sign_modifier = 0;
int32_t x = 0; // decoded value
// read x, number of 1s before 0 represent the rice value.
while (x <= RICE_THRESHOLD && readbit(alac))
{
x++;
}
if (x > RICE_THRESHOLD)
{
// read the number from the bit stream (raw value)
int32_t value;
value = readbits(alac, readsamplesize);
/* mask value to readsamplesize size */
if (readsamplesize != 32)
value &= (((uint32_t)0xffffffff) >> (32 - readsamplesize));
x = value;
}
else
{
if (k != 1)
{
int extrabits = readbits(alac, k);
// x = x * (2^k - 1)
x = (x << k) - x;
if (extrabits > 1)
x += extrabits - 1;
else
unreadbits(alac, 1);
}
}
return x;
}
static void entropy_rice_decode(alac_file* alac,
int32_t* output_buffer,
int output_size,
int readsamplesize,
int rice_initialhistory,
int rice_kmodifier,
int rice_historymult,
int rice_kmodifier_mask) ICODE_ATTR_ALAC;
static void entropy_rice_decode(alac_file* alac,
int32_t* output_buffer,
int output_size,
int readsamplesize,
int rice_initialhistory,
int rice_kmodifier,
int rice_historymult,
int rice_kmodifier_mask)
{
int output_count;
int history = rice_initialhistory;
int sign_modifier = 0;
for (output_count = 0; output_count < output_size; output_count++)
{
int32_t x = 0;
int32_t x_modified;
int32_t final_val;
int32_t decoded_value;
int32_t final_value;
int32_t k;
/* read x - number of 1s before 0 represent the rice */
while (x <= 8 && readbit(alac))
{
x++;
}
k = 31 - rice_kmodifier - count_leading_zeros((history >> 9) + 3);
if (k < 0) k += rice_kmodifier;
else k = rice_kmodifier;
if (x > 8) /* RICE THRESHOLD */
{ /* use alternative encoding */
int32_t value;
decoded_value = entropy_decode_value(alac, readsamplesize, k);
value = readbits(alac, readsamplesize);
decoded_value += sign_modifier;
final_value = (decoded_value + 1) / 2; // inc by 1 and shift out sign bit
if (decoded_value & 1) // the sign is stored in the low bit
final_value *= -1;
/* mask value to readsamplesize size */
if (readsamplesize != 32)
value &= (0xffffffff >> (32 - readsamplesize));
x = value;
}
else
{ /* standard rice encoding */
int extrabits;
int k; /* size of extra bits */
/* read k, that is bits as is */
k = 31 - rice_kmodifier - count_leading_zeros((history >> 9) + 3);
if (k < 0) k += rice_kmodifier;
else k = rice_kmodifier;
if (k != 1)
{
extrabits = readbits(alac, k);
/* multiply x by 2^k - 1, as part of their strange algorithm */
x = (x << k) - x;
if (extrabits > 1)
{
x += extrabits - 1;
}
else unreadbits(alac, 1);
}
}
x_modified = sign_modifier + x;
final_val = (x_modified + 1) / 2;
if (x_modified & 1) final_val *= -1;
output_buffer[output_count] = final_val;
output_buffer[output_count] = final_value;
sign_modifier = 0;
/* now update the history */
history += (x_modified * rice_historymult)
- ((history * rice_historymult) >> 9);
// update history
history += (decoded_value * rice_historymult)
- ((history * rice_historymult) >> 9);
if (x_modified > 0xffff)
history = 0xffff;
if (decoded_value > 0xFFFF)
history = 0xFFFF;
/* special case: there may be compressed blocks of 0 */
if ((history < 128) && (output_count+1 < output_size))
// special case, for compressed blocks of 0
if ((history < 128) && (output_count + 1 < output_size))
{
int block_size;
int32_t block_size;
sign_modifier = 1;
x = 0;
while (x <= 8 && readbit(alac))
{
x++;
}
k = count_leading_zeros(history) + ((history + 16) / 64) - 24;
if (x > 8)
{
block_size = readbits(alac, 16);
block_size &= 0xffff;
}
else
{
int k;
int extrabits;
k = count_leading_zeros(history) + ((history + 16) >> 6 /* / 64 */) - 24;
extrabits = readbits(alac, k);
block_size = (((1 << k) - 1) & rice_kmodifier_mask) * x
+ extrabits - 1;
if (extrabits < 2)
{
x = 1 - extrabits;
block_size += x;
unreadbits(alac, 1);
}
}
// note: block_size is always 16bit
block_size = entropy_decode_value(alac, 16, k) & rice_kmodifier_mask;
// got block_size 0s
if (block_size > 0)
{
memset(&output_buffer[output_count+1], 0, block_size * 4);
memset(&output_buffer[output_count + 1], 0,
block_size * sizeof(*output_buffer));
output_count += block_size;
}
if (block_size > 0xffff)
if (block_size > 0xFFFF)
sign_modifier = 0;
history = 0;
@ -632,6 +619,72 @@ void deinterlace_16(int32_t* buffer0,
}
}
void deinterlace_24(int32_t *buffer0, int32_t *buffer1,
int uncompressed_bytes,
int32_t *uncompressed_bytes_buffer0,
int32_t *uncompressed_bytes_buffer1,
int numsamples,
uint8_t interlacing_shift,
uint8_t interlacing_leftweight) ICODE_ATTR_ALAC;
void deinterlace_24(int32_t *buffer0, int32_t *buffer1,
int uncompressed_bytes,
int32_t *uncompressed_bytes_buffer0,
int32_t *uncompressed_bytes_buffer1,
int numsamples,
uint8_t interlacing_shift,
uint8_t interlacing_leftweight)
{
int i;
if (numsamples <= 0) return;
/* weighted interlacing */
if (interlacing_leftweight)
{
for (i = 0; i < numsamples; i++)
{
int32_t difference, midright;
midright = buffer0[i];
difference = buffer1[i];
buffer0[i] = ((midright - ((difference * interlacing_leftweight)
>> interlacing_shift)) + difference) << SCALE24;
buffer1[i] = (midright - ((difference * interlacing_leftweight)
>> interlacing_shift)) << SCALE24;
if (uncompressed_bytes)
{
uint32_t mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8));
buffer0[i] <<= (uncompressed_bytes * 8);
buffer1[i] <<= (uncompressed_bytes * 8);
buffer0[i] |= uncompressed_bytes_buffer0[i] & mask;
buffer1[i] |= uncompressed_bytes_buffer1[i] & mask;
}
}
return;
}
/* otherwise basic interlacing took place */
for (i = 0; i < numsamples; i++)
{
if (uncompressed_bytes)
{
uint32_t mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8));
buffer0[i] <<= (uncompressed_bytes * 8);
buffer1[i] <<= (uncompressed_bytes * 8);
buffer0[i] |= uncompressed_bytes_buffer0[i] & mask;
buffer1[i] |= uncompressed_bytes_buffer1[i] & mask;
}
buffer0[i] = buffer0[i] << SCALE24;
buffer1[i] = buffer1[i] << SCALE24;
}
}
static inline int decode_frame_mono(
alac_file *alac,
@ -641,9 +694,10 @@ static inline int decode_frame_mono(
int hassize;
int isnotcompressed;
int readsamplesize;
int infosamplesize = alac->setinfo_sample_size;
int outputsamples = alac->setinfo_max_samples_per_frame;
int wasted_bytes;
int uncompressed_bytes;
int ricemodifier;
@ -656,7 +710,8 @@ static inline int decode_frame_mono(
hassize = readbits(alac, 1); /* the output sample size is stored soon */
wasted_bytes = readbits(alac, 2); /* unknown ? */
/* number of bytes in the (compressed) stream that are not compressed */
uncompressed_bytes = readbits(alac, 2);
isnotcompressed = readbits(alac, 1); /* whether the frame is compressed */
@ -667,7 +722,7 @@ static inline int decode_frame_mono(
outputsamples = readbits(alac, 32);
}
readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8);
readsamplesize = infosamplesize - (uncompressed_bytes * 8);
if (!isnotcompressed)
{ /* so it is compressed */
@ -693,24 +748,26 @@ static inline int decode_frame_mono(
predictor_coef_table[i] = (int16_t)readbits(alac, 16);
}
if (wasted_bytes)
if (uncompressed_bytes)
{
/* these bytes seem to have something to do with
* > 2 channel files.
*/
//fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
int i;
for (i = 0; i < outputsamples; i++)
{
outputbuffer[0][i] = readbits(alac, uncompressed_bytes * 8);
outputbuffer[1][i] = outputbuffer[0][i];
}
}
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);
entropy_rice_decode(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();
@ -738,14 +795,14 @@ static inline int decode_frame_mono(
}
else
{ /* not compressed, easy case */
if (readsamplesize <= 16)
if (infosamplesize <= 16)
{
int i;
for (i = 0; i < outputsamples; i++)
{
int32_t audiobits = readbits(alac, readsamplesize);
int32_t audiobits = readbits(alac, infosamplesize);
audiobits = SIGN_EXTENDED32(audiobits, readsamplesize);
audiobits = SIGN_EXTENDED32(audiobits, infosamplesize);
outputbuffer[0][i] = audiobits;
}
@ -760,20 +817,19 @@ static inline int decode_frame_mono(
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 = audiobits << (infosamplesize - 16);
audiobits |= readbits(alac, infosamplesize - 16);
audiobits = SIGNEXTEND24(audiobits);
outputbuffer[0][i] = audiobits;
}
}
/* wasted_bytes = 0; // unused */
uncompressed_bytes = 0; // always 0 for uncompressed
}
yield();
switch(alac->setinfo_sample_size)
switch(infosamplesize)
{
case 16:
{
@ -786,10 +842,29 @@ static inline int decode_frame_mono(
}
break;
}
case 20:
case 24:
{
int i;
for (i = 0; i < outputsamples; i++)
{
int32_t sample = outputbuffer[0][i];
if (uncompressed_bytes)
{
uint32_t mask;
sample = sample << (uncompressed_bytes * 8);
mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8));
sample |= outputbuffer[0][i] & mask;
}
outputbuffer[0][i] = sample << SCALE24;
outputbuffer[1][i] = outputbuffer[0][i];
}
break;
}
case 20:
case 32:
//fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
//fprintf(stderr, "FIXME: unimplemented sample size %i\n", infosamplesize);
break;
default:
break;
@ -806,8 +881,9 @@ static inline int decode_frame_stereo(
int hassize;
int isnotcompressed;
int readsamplesize;
int infosamplesize = alac->setinfo_sample_size;
int outputsamples = alac->setinfo_max_samples_per_frame;
int wasted_bytes;
int uncompressed_bytes;
uint8_t interlacing_shift;
uint8_t interlacing_leftweight;
@ -821,7 +897,8 @@ static inline int decode_frame_stereo(
hassize = readbits(alac, 1); /* the output sample size is stored soon */
wasted_bytes = readbits(alac, 2); /* unknown ? */
/* the number of bytes in the (compressed) stream that are not compressed */
uncompressed_bytes = readbits(alac, 2);
isnotcompressed = readbits(alac, 1); /* whether the frame is compressed */
@ -832,7 +909,7 @@ static inline int decode_frame_stereo(
outputsamples = readbits(alac, 32);
}
readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + 1;
readsamplesize = infosamplesize - (uncompressed_bytes * 8) + 1;
yield();
if (!isnotcompressed)
@ -879,21 +956,26 @@ static inline int decode_frame_stereo(
}
/*********************/
if (wasted_bytes)
if (uncompressed_bytes)
{ /* see mono case */
//fprintf(stderr, "FIXME: unimplemented, unhandling of wasted_bytes\n");
int i;
for (i = 0; i < outputsamples; i++)
{
outputbuffer[0][i] = readbits(alac, uncompressed_bytes * 8);
outputbuffer[1][i] = readbits(alac, uncompressed_bytes * 8);
}
}
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);
entropy_rice_decode(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)
@ -914,14 +996,14 @@ static inline int decode_frame_stereo(
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);
entropy_rice_decode(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)
@ -941,18 +1023,18 @@ static inline int decode_frame_stereo(
}
else
{ /* not compressed, easy case */
if (alac->setinfo_sample_size <= 16)
if (infosamplesize <= 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 = readbits(alac, infosamplesize);
audiobits_b = readbits(alac, infosamplesize);
audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size);
audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size);
audiobits_a = SIGN_EXTENDED32(audiobits_a, infosamplesize);
audiobits_b = SIGN_EXTENDED32(audiobits_b, infosamplesize);
outputbuffer[0][i] = audiobits_a;
outputbuffer[1][i] = audiobits_b;
@ -966,27 +1048,27 @@ static inline int decode_frame_stereo(
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_a = audiobits_a << (infosamplesize - 16);
audiobits_a |= readbits(alac, infosamplesize - 16);
audiobits_a = SIGNEXTEND24(audiobits_a);
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);
audiobits_b = audiobits_b << (infosamplesize - 16);
audiobits_b |= readbits(alac, infosamplesize - 16);
audiobits_b = SIGNEXTEND24(audiobits_b);
outputbuffer[0][i] = audiobits_a;
outputbuffer[1][i] = audiobits_b;
}
}
/* wasted_bytes = 0; */
uncompressed_bytes = 0; // always 0 for uncompressed
interlacing_shift = 0;
interlacing_leftweight = 0;
}
yield();
switch(alac->setinfo_sample_size)
switch(infosamplesize)
{
case 16:
{
@ -997,10 +1079,21 @@ static inline int decode_frame_stereo(
interlacing_leftweight);
break;
}
case 20:
case 24:
{
deinterlace_24(outputbuffer[0],
outputbuffer[1],
uncompressed_bytes,
outputbuffer[0],
outputbuffer[1],
outputsamples,
interlacing_shift,
interlacing_leftweight);
break;
}
case 20:
case 32:
//fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
//fprintf(stderr, "FIXME: unimplemented sample size %i\n", infosamplesize);
break;
default:
break;

View file

@ -8,6 +8,7 @@
/* Always output samples shifted to 28 bits + sign*/
#define ALAC_OUTPUT_DEPTH 29
#define SCALE16 (ALAC_OUTPUT_DEPTH - 16)
#define SCALE24 (ALAC_OUTPUT_DEPTH - 24)
#define ALAC_MAX_CHANNELS 2
#define ALAC_BLOCKSIZE 4096 /* Number of samples per channel per block */