forked from len0rd/rockbox
Update libwavpack to the latest stream specification, and cross fingers
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9769 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
2ec18b521c
commit
b76bb60219
4 changed files with 51 additions and 29 deletions
|
@ -128,7 +128,7 @@ int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
signed char *byteptr = wpmd->data;
|
signed char *byteptr = wpmd->data;
|
||||||
struct decorr_pass *dpp;
|
struct decorr_pass *dpp;
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG))
|
if (!(wps->wphdr.flags & MONO_DATA))
|
||||||
termcnt /= 2;
|
termcnt /= 2;
|
||||||
|
|
||||||
if (termcnt > wps->num_terms)
|
if (termcnt > wps->num_terms)
|
||||||
|
@ -140,7 +140,7 @@ int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
while (--dpp >= wps->decorr_passes && termcnt--) {
|
while (--dpp >= wps->decorr_passes && termcnt--) {
|
||||||
dpp->weight_A = restore_weight (*byteptr++);
|
dpp->weight_A = restore_weight (*byteptr++);
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG))
|
if (!(wps->wphdr.flags & MONO_DATA))
|
||||||
dpp->weight_B = restore_weight (*byteptr++);
|
dpp->weight_B = restore_weight (*byteptr++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
if (wps->wphdr.version == 0x402 && (wps->wphdr.flags & HYBRID_FLAG)) {
|
if (wps->wphdr.version == 0x402 && (wps->wphdr.flags & HYBRID_FLAG)) {
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG))
|
if (!(wps->wphdr.flags & MONO_DATA))
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
dpp->samples_A [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
|
dpp->samples_A [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
|
||||||
byteptr += 4;
|
byteptr += 4;
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG)) {
|
if (!(wps->wphdr.flags & MONO_DATA)) {
|
||||||
dpp->samples_B [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
dpp->samples_B [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
||||||
dpp->samples_B [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
|
dpp->samples_B [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
|
||||||
byteptr += 4;
|
byteptr += 4;
|
||||||
|
@ -198,7 +198,7 @@ int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
dpp->samples_A [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
dpp->samples_A [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG)) {
|
if (!(wps->wphdr.flags & MONO_DATA)) {
|
||||||
dpp->samples_B [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
dpp->samples_B [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_co
|
||||||
|
|
||||||
///////////////////// handle version 4 mono data /////////////////////////
|
///////////////////// handle version 4 mono data /////////////////////////
|
||||||
|
|
||||||
if (flags & MONO_FLAG) {
|
if (flags & MONO_DATA) {
|
||||||
eptr = buffer + sample_count;
|
eptr = buffer + sample_count;
|
||||||
i = get_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
|
i = get_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
|
||||||
|
|
||||||
|
@ -394,9 +394,20 @@ int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_co
|
||||||
fixup_samples (wps, buffer, i);
|
fixup_samples (wps, buffer, i);
|
||||||
|
|
||||||
if (flags & FLOAT_DATA)
|
if (flags & FLOAT_DATA)
|
||||||
float_normalize (buffer, (flags & MONO_FLAG) ? i : i * 2,
|
float_normalize (buffer, (flags & MONO_DATA) ? i : i * 2,
|
||||||
127 - wps->float_norm_exp + wpc->norm_offset);
|
127 - wps->float_norm_exp + wpc->norm_offset);
|
||||||
|
|
||||||
|
if (flags & FALSE_STEREO) {
|
||||||
|
int32_t *dptr = buffer + i * 2;
|
||||||
|
int32_t *sptr = buffer + i;
|
||||||
|
int32_t c = i;
|
||||||
|
|
||||||
|
while (c--) {
|
||||||
|
*--dptr = *--sptr;
|
||||||
|
*--dptr = *sptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wps->sample_index += i;
|
wps->sample_index += i;
|
||||||
wps->crc = crc;
|
wps->crc = crc;
|
||||||
|
|
||||||
|
@ -695,12 +706,12 @@ static void fixup_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_
|
||||||
shift += 21 - (flags & BYTES_STORED) * 8; // this provides RockBox with 28-bit (+sign)
|
shift += 21 - (flags & BYTES_STORED) * 8; // this provides RockBox with 28-bit (+sign)
|
||||||
|
|
||||||
if (flags & FLOAT_DATA) {
|
if (flags & FLOAT_DATA) {
|
||||||
float_values (wps, buffer, (flags & MONO_FLAG) ? sample_count : sample_count * 2);
|
float_values (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & INT32_DATA) {
|
if (flags & INT32_DATA) {
|
||||||
uint32_t count = (flags & MONO_FLAG) ? sample_count : sample_count * 2;
|
uint32_t count = (flags & MONO_DATA) ? sample_count : sample_count * 2;
|
||||||
int sent_bits = wps->int32_sent_bits, zeros = wps->int32_zeros;
|
int sent_bits = wps->int32_sent_bits, zeros = wps->int32_zeros;
|
||||||
int ones = wps->int32_ones, dups = wps->int32_dups;
|
int ones = wps->int32_ones, dups = wps->int32_dups;
|
||||||
int32_t *dptr = buffer;
|
int32_t *dptr = buffer;
|
||||||
|
@ -721,7 +732,7 @@ static void fixup_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shift > 0) {
|
if (shift > 0) {
|
||||||
if (!(flags & MONO_FLAG))
|
if (!(flags & MONO_DATA))
|
||||||
sample_count *= 2;
|
sample_count *= 2;
|
||||||
|
|
||||||
while (sample_count--)
|
while (sample_count--)
|
||||||
|
@ -730,7 +741,7 @@ static void fixup_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_
|
||||||
else if (shift < 0) {
|
else if (shift < 0) {
|
||||||
shift = -shift;
|
shift = -shift;
|
||||||
|
|
||||||
if (!(flags & MONO_FLAG))
|
if (!(flags & MONO_DATA))
|
||||||
sample_count *= 2;
|
sample_count *= 2;
|
||||||
|
|
||||||
while (sample_count--)
|
while (sample_count--)
|
||||||
|
|
|
@ -76,11 +76,19 @@ typedef struct {
|
||||||
#define SRATE_LSB 23
|
#define SRATE_LSB 23
|
||||||
#define SRATE_MASK (0xfL << SRATE_LSB)
|
#define SRATE_MASK (0xfL << SRATE_LSB)
|
||||||
|
|
||||||
|
#define FALSE_STEREO 0x40000000 // block is stereo, but data is mono
|
||||||
|
|
||||||
#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
|
#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
|
||||||
#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
|
#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
|
||||||
#define UNKNOWN_FLAGS 0xC0000000 // also reserved, but refuse decode if
|
#define UNKNOWN_FLAGS 0x80000000 // also reserved, but refuse decode if
|
||||||
// encountered
|
// encountered
|
||||||
|
|
||||||
|
#define MONO_DATA (MONO_FLAG | FALSE_STEREO)
|
||||||
|
|
||||||
|
#define MIN_STREAM_VERS 0x402 // lowest stream version we'll decode
|
||||||
|
#define MAX_STREAM_VERS 0x410 // highest stream version we'll decode
|
||||||
|
#define CUR_STREAM_VERS 0x403 // stream version we are writing now
|
||||||
|
|
||||||
//////////////////////////// WavPack Metadata /////////////////////////////////
|
//////////////////////////// WavPack Metadata /////////////////////////////////
|
||||||
|
|
||||||
// This is an internal representation of metadata.
|
// This is an internal representation of metadata.
|
||||||
|
@ -426,5 +434,6 @@ void WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
|
||||||
int WavpackStartBlock (WavpackContext *wpc, uchar *begin, uchar *end);
|
int WavpackStartBlock (WavpackContext *wpc, uchar *begin, uchar *end);
|
||||||
int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
|
int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
|
||||||
uint32_t WavpackFinishBlock (WavpackContext *wpc);
|
uint32_t WavpackFinishBlock (WavpackContext *wpc);
|
||||||
|
void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block);
|
||||||
|
void *WavpackGetWrapperLocation (void *first_block);
|
||||||
|
|
||||||
|
|
|
@ -151,14 +151,14 @@ int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
{
|
{
|
||||||
uchar *byteptr = wpmd->data;
|
uchar *byteptr = wpmd->data;
|
||||||
|
|
||||||
if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12))
|
if (wpmd->byte_length != ((wps->wphdr.flags & MONO_DATA) ? 6 : 12))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
wps->w.c [0].median [0] = exp2s (byteptr [0] + (byteptr [1] << 8));
|
wps->w.c [0].median [0] = exp2s (byteptr [0] + (byteptr [1] << 8));
|
||||||
wps->w.c [0].median [1] = exp2s (byteptr [2] + (byteptr [3] << 8));
|
wps->w.c [0].median [1] = exp2s (byteptr [2] + (byteptr [3] << 8));
|
||||||
wps->w.c [0].median [2] = exp2s (byteptr [4] + (byteptr [5] << 8));
|
wps->w.c [0].median [2] = exp2s (byteptr [4] + (byteptr [5] << 8));
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG)) {
|
if (!(wps->wphdr.flags & MONO_DATA)) {
|
||||||
wps->w.c [1].median [0] = exp2s (byteptr [6] + (byteptr [7] << 8));
|
wps->w.c [1].median [0] = exp2s (byteptr [6] + (byteptr [7] << 8));
|
||||||
wps->w.c [1].median [1] = exp2s (byteptr [8] + (byteptr [9] << 8));
|
wps->w.c [1].median [1] = exp2s (byteptr [8] + (byteptr [9] << 8));
|
||||||
wps->w.c [1].median [2] = exp2s (byteptr [10] + (byteptr [11] << 8));
|
wps->w.c [1].median [2] = exp2s (byteptr [10] + (byteptr [11] << 8));
|
||||||
|
@ -215,7 +215,7 @@ int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
wps->w.c [0].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
|
wps->w.c [0].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG)) {
|
if (!(wps->wphdr.flags & MONO_DATA)) {
|
||||||
wps->w.c [1].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
|
wps->w.c [1].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
wps->w.bitrate_acc [0] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
|
wps->w.bitrate_acc [0] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG)) {
|
if (!(wps->wphdr.flags & MONO_DATA)) {
|
||||||
wps->w.bitrate_acc [1] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
|
wps->w.bitrate_acc [1] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||||
wps->w.bitrate_delta [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
wps->w.bitrate_delta [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
|
|
||||||
if (!(wps->wphdr.flags & MONO_FLAG)) {
|
if (!(wps->wphdr.flags & MONO_DATA)) {
|
||||||
wps->w.bitrate_delta [1] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
wps->w.bitrate_delta [1] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
|
||||||
byteptr += 2;
|
byteptr += 2;
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ void update_error_limit (struct words_data *w, uint32_t flags)
|
||||||
{
|
{
|
||||||
int bitrate_0 = (w->bitrate_acc [0] += w->bitrate_delta [0]) >> 16;
|
int bitrate_0 = (w->bitrate_acc [0] += w->bitrate_delta [0]) >> 16;
|
||||||
|
|
||||||
if (flags & MONO_FLAG) {
|
if (flags & MONO_DATA) {
|
||||||
if (flags & HYBRID_BITRATE) {
|
if (flags & HYBRID_BITRATE) {
|
||||||
int slow_log_0 = (w->c [0].slow_level + SLO) >> SLS;
|
int slow_log_0 = (w->c [0].slow_level + SLO) >> SLS;
|
||||||
|
|
||||||
|
@ -326,13 +326,13 @@ int32_t get_words (int32_t *buffer, int nsamples, uint32_t flags,
|
||||||
register struct entropy_data *c = w->c;
|
register struct entropy_data *c = w->c;
|
||||||
int csamples;
|
int csamples;
|
||||||
|
|
||||||
if (!(flags & MONO_FLAG))
|
if (!(flags & MONO_DATA))
|
||||||
nsamples *= 2;
|
nsamples *= 2;
|
||||||
|
|
||||||
for (csamples = 0; csamples < nsamples; ++csamples) {
|
for (csamples = 0; csamples < nsamples; ++csamples) {
|
||||||
uint32_t ones_count, low, mid, high;
|
uint32_t ones_count, low, mid, high;
|
||||||
|
|
||||||
if (!(flags & MONO_FLAG))
|
if (!(flags & MONO_DATA))
|
||||||
c = w->c + (csamples & 1);
|
c = w->c + (csamples & 1);
|
||||||
|
|
||||||
if (!(w->c [0].median [0] & ~1) && !w->holding_zero && !w->holding_one && !(w->c [1].median [0] & ~1)) {
|
if (!(w->c [0].median [0] & ~1) && !w->holding_zero && !w->holding_one && !(w->c [1].median [0] & ~1)) {
|
||||||
|
@ -435,7 +435,7 @@ int32_t get_words (int32_t *buffer, int nsamples, uint32_t flags,
|
||||||
w->holding_zero = ~w->holding_one & 1;
|
w->holding_zero = ~w->holding_one & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & HYBRID_FLAG) && ((flags & MONO_FLAG) || !(csamples & 1)))
|
if ((flags & HYBRID_FLAG) && ((flags & MONO_DATA) || !(csamples & 1)))
|
||||||
update_error_limit (w, flags);
|
update_error_limit (w, flags);
|
||||||
|
|
||||||
if (ones_count == 0) {
|
if (ones_count == 0) {
|
||||||
|
@ -484,7 +484,7 @@ int32_t get_words (int32_t *buffer, int nsamples, uint32_t flags,
|
||||||
c->slow_level = c->slow_level - ((c->slow_level + SLO) >> SLS) + mylog2 (mid);
|
c->slow_level = c->slow_level - ((c->slow_level + SLO) >> SLS) + mylog2 (mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (flags & MONO_FLAG) ? csamples : (csamples / 2);
|
return (flags & MONO_DATA) ? csamples : (csamples / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a single unsigned value from the specified bitstream with a value
|
// Read a single unsigned value from the specified bitstream with a value
|
||||||
|
|
|
@ -69,9 +69,10 @@ WavpackContext *WavpackOpenFileInput (read_stream infile, char *error)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((wps->wphdr.flags & UNKNOWN_FLAGS) || wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) {
|
if ((wps->wphdr.flags & UNKNOWN_FLAGS) || wps->wphdr.version < MIN_STREAM_VERS ||
|
||||||
strcpy_loc (error, "invalid WavPack file!");
|
wps->wphdr.version > MAX_STREAM_VERS) {
|
||||||
return NULL;
|
strcpy_loc (error, "invalid WavPack file!");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wps->wphdr.block_samples && wps->wphdr.total_samples != (uint32_t) -1)
|
if (wps->wphdr.block_samples && wps->wphdr.total_samples != (uint32_t) -1)
|
||||||
|
@ -170,7 +171,7 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
||||||
if (bcount == (uint32_t) -1)
|
if (bcount == (uint32_t) -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (wps->wphdr.version < 0x402 || wps->wphdr.version > 0x40f) {
|
if (wps->wphdr.version < MIN_STREAM_VERS || wps->wphdr.version > MAX_STREAM_VERS) {
|
||||||
strcpy_loc (wpc->error_message, "invalid WavPack file!");
|
strcpy_loc (wpc->error_message, "invalid WavPack file!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -341,7 +342,8 @@ static uint32_t read_next_header (read_stream infile, WavpackHeader *wphdr)
|
||||||
sp = buffer;
|
sp = buffer;
|
||||||
|
|
||||||
if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' &&
|
if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' &&
|
||||||
!(*++sp & 1) && sp [2] < 16 && !sp [3] && sp [5] == 4 && sp [4] >= 2 && sp [4] <= 0xf) {
|
!(*++sp & 1) && sp [2] < 16 && !sp [3] && sp [5] == 4 &&
|
||||||
|
sp [4] >= (MIN_STREAM_VERS & 0xff) && sp [4] <= (MAX_STREAM_VERS & 0xff)) {
|
||||||
memcpy (wphdr, buffer, sizeof (*wphdr));
|
memcpy (wphdr, buffer, sizeof (*wphdr));
|
||||||
little_endian_to_native (wphdr, WavpackHeaderFormat);
|
little_endian_to_native (wphdr, WavpackHeaderFormat);
|
||||||
return bytes_skipped;
|
return bytes_skipped;
|
||||||
|
@ -452,7 +454,7 @@ int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_
|
||||||
memcpy (wps->wphdr.ckID, "wvpk", 4);
|
memcpy (wps->wphdr.ckID, "wvpk", 4);
|
||||||
wps->wphdr.ckSize = sizeof (WavpackHeader) - 8;
|
wps->wphdr.ckSize = sizeof (WavpackHeader) - 8;
|
||||||
wps->wphdr.total_samples = wpc->total_samples;
|
wps->wphdr.total_samples = wpc->total_samples;
|
||||||
wps->wphdr.version = 0x403;
|
wps->wphdr.version = CUR_STREAM_VERS;
|
||||||
wps->wphdr.flags = flags;
|
wps->wphdr.flags = flags;
|
||||||
|
|
||||||
pack_init (wpc);
|
pack_init (wpc);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue