summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Bryant <bryant@rockbox.org>2007-01-08 04:24:32 +0000
committerDave Bryant <bryant@rockbox.org>2007-01-08 04:24:32 +0000
commit2446b22db971668f8d6ba5cb2361aabbda286da1 (patch)
tree3b9bcf9c273783a1ee0b273f7f56d72f92077754
parent5693622cd4de1d3dff162295690ecb25d29a2937 (diff)
downloadrockbox-2446b22db971668f8d6ba5cb2361aabbda286da1.tar.gz
rockbox-2446b22db971668f8d6ba5cb2361aabbda286da1.zip
Update libwavpack with latest changes from the tiny_encoder. This allows
playback of floating-point audio files, fixes a obscure decoding bug, and improves encoding speed somewhat. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11944 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libwavpack/float.c70
-rw-r--r--apps/codecs/libwavpack/unpack.c4
-rw-r--r--apps/codecs/libwavpack/wavpack.h41
-rw-r--r--apps/metadata.c8
4 files changed, 43 insertions, 80 deletions
diff --git a/apps/codecs/libwavpack/float.c b/apps/codecs/libwavpack/float.c
index 9d3a82c001..6e5c4e4f61 100644
--- a/apps/codecs/libwavpack/float.c
+++ b/apps/codecs/libwavpack/float.c
@@ -25,59 +25,23 @@ int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
25 return TRUE; 25 return TRUE;
26} 26}
27 27
28void float_values (WavpackStream *wps, int32_t *values, int32_t num_values) 28/* This function converts WavPack floating point data into standard Rockbox
29{ 29 * 28-bit integers. It is assumed that clipping will be taken care of later.
30 while (num_values--) { 30 */
31 int shift_count = 0, exp = wps->float_max_exp;
32 f32 outval = { 0, 0, 0 };
33
34 if (*values) {
35 *values <<= wps->float_shift;
36
37 if (*values < 0) {
38 *values = -*values;
39 outval.sign = 1;
40 }
41
42 if (*values == 0x1000000)
43 outval.exponent = 255;
44 else {
45 if (exp)
46 while (!(*values & 0x800000) && --exp) {
47 shift_count++;
48 *values <<= 1;
49 }
50
51 if (shift_count && (wps->float_flags & FLOAT_SHIFT_ONES))
52 *values |= ((1 << shift_count) - 1);
53
54 outval.mantissa = *values;
55 outval.exponent = exp;
56 }
57 }
58 31
59 * (f32 *) values++ = outval; 32void float_values (WavpackStream *wps, int32_t *values, int32_t num_values)
60 }
61}
62
63void float_normalize (int32_t *values, int32_t num_values, int delta_exp)
64{ 33{
65 f32 *fvalues = (f32 *) values, fzero = { 0, 0, 0 }; 34 int shift = wps->float_max_exp - wps->float_norm_exp + wps->float_shift + 5;
66 int exp; 35
67 36 if (shift > 32)
68 if (!delta_exp) 37 shift = 32;
69 return; 38 else if (shift < -32)
70 39 shift = -32;
71 while (num_values--) { 40
72 if ((exp = fvalues->exponent) == 0 || exp + delta_exp <= 0) 41 if (shift > 0)
73 *fvalues = fzero; 42 while (num_values--)
74 else if (exp == 255 || (exp += delta_exp) >= 255) { 43 *values++ <<= shift;
75 fvalues->exponent = 255; 44 else if (shift < 0)
76 fvalues->mantissa = 0; 45 while (num_values--)
77 } 46 *values++ >>= -shift;
78 else
79 fvalues->exponent = exp;
80
81 fvalues++;
82 }
83} 47}
diff --git a/apps/codecs/libwavpack/unpack.c b/apps/codecs/libwavpack/unpack.c
index 5bb4467440..daf88718c8 100644
--- a/apps/codecs/libwavpack/unpack.c
+++ b/apps/codecs/libwavpack/unpack.c
@@ -393,10 +393,6 @@ int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_co
393 393
394 fixup_samples (wps, buffer, i); 394 fixup_samples (wps, buffer, i);
395 395
396 if (flags & FLOAT_DATA)
397 float_normalize (buffer, (flags & MONO_DATA) ? i : i * 2,
398 127 - wps->float_norm_exp + wpc->norm_offset);
399
400 if (flags & FALSE_STEREO) { 396 if (flags & FALSE_STEREO) {
401 int32_t *dptr = buffer + i * 2; 397 int32_t *dptr = buffer + i * 2;
402 int32_t *sptr = buffer + i; 398 int32_t *sptr = buffer + i;
diff --git a/apps/codecs/libwavpack/wavpack.h b/apps/codecs/libwavpack/wavpack.h
index 3128328e49..a000438081 100644
--- a/apps/codecs/libwavpack/wavpack.h
+++ b/apps/codecs/libwavpack/wavpack.h
@@ -18,17 +18,6 @@ typedef unsigned char uchar;
18typedef unsigned short ushort; 18typedef unsigned short ushort;
19typedef unsigned int uint; 19typedef unsigned int uint;
20 20
21// This structure is used to access the individual fields of 32-bit ieee
22// floating point numbers. This will not be compatible with compilers that
23// allocate bit fields from the most significant bits, although I'm not sure
24// how common that is.
25
26typedef struct {
27 unsigned mantissa : 23;
28 unsigned exponent : 8;
29 unsigned sign : 1;
30} f32;
31
32#include <stdio.h> 21#include <stdio.h>
33 22
34#define FALSE 0 23#define FALSE 0
@@ -281,8 +270,14 @@ uint32_t bs_close_write (Bitstream *bs);
281 (bs)->bc += 8; \ 270 (bs)->bc += 8; \
282 } \ 271 } \
283 *(value) = (bs)->sr; \ 272 *(value) = (bs)->sr; \
284 (bs)->sr >>= (nbits); \ 273 if ((bs)->bc > 32) { \
285 (bs)->bc -= (nbits); \ 274 (bs)->bc -= (nbits); \
275 (bs)->sr = *((bs)->ptr) >> (8 - (bs)->bc); \
276 } \
277 else { \
278 (bs)->bc -= (nbits); \
279 (bs)->sr >>= (nbits); \
280 } \
286} 281}
287 282
288#define putbit(bit, bs) { if (bit) (bs)->sr |= (1 << (bs)->bc); \ 283#define putbit(bit, bs) { if (bit) (bs)->sr |= (1 << (bs)->bc); \
@@ -319,10 +314,15 @@ uint32_t bs_close_write (Bitstream *bs);
319void little_endian_to_native (void *data, char *format); 314void little_endian_to_native (void *data, char *format);
320void native_to_little_endian (void *data, char *format); 315void native_to_little_endian (void *data, char *format);
321 316
322// these macros implement the weight application and update operations 317// These macros implement the weight application and update operations
323// that are at the heart of the decorrelation loops 318// that are at the heart of the decorrelation loops. Note that when there
319// are several alternative versions of the same macro (marked with PERFCOND)
320// then the versions are functionally equivalent with respect to WavPack
321// decoding and the user should choose the one that provides the best
322// performance. This may be easier to check when NOT using the assembly
323// language optimizations.
324 324
325#if 0 // PERFCOND 325#if 1 // PERFCOND
326#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10) 326#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10)
327#else 327#else
328#define apply_weight_i(weight, sample) ((((weight * sample) >> 8) + 2) >> 2) 328#define apply_weight_i(weight, sample) ((((weight * sample) >> 8) + 2) >> 2)
@@ -340,15 +340,18 @@ void native_to_little_endian (void *data, char *format);
340 340
341#if 0 // PERFCOND 341#if 0 // PERFCOND
342#define update_weight(weight, delta, source, result) \ 342#define update_weight(weight, delta, source, result) \
343 if (source && result) weight -= ((((source ^ result) >> 30) & 2) - 1) * delta; 343 if (source && result) { int32_t s = (int32_t) (source ^ result) >> 31; weight = (delta ^ s) + (weight - s); }
344#elif 1
345#define update_weight(weight, delta, source, result) \
346 if (source && result) weight += (((source ^ result) >> 30) | 1) * delta
344#else 347#else
345#define update_weight(weight, delta, source, result) \ 348#define update_weight(weight, delta, source, result) \
346 if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta); 349 if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta)
347#endif 350#endif
348 351
349#define update_weight_clip(weight, delta, source, result) \ 352#define update_weight_clip(weight, delta, source, result) \
350 if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \ 353 if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \
351 weight = weight < 0 ? -1024 : 1024; 354 weight = weight < 0 ? -1024 : 1024
352 355
353// unpack.c 356// unpack.c
354 357
diff --git a/apps/metadata.c b/apps/metadata.c
index 1f61e98498..acd8de38e3 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -1867,9 +1867,9 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname,
1867 1867
1868 case AFMT_WAVPACK: 1868 case AFMT_WAVPACK:
1869 /* A simple parser to read basic information from a WavPack file. This 1869 /* A simple parser to read basic information from a WavPack file. This
1870 * now works with self-extrating WavPack files and also will fail on 1870 * now works with self-extrating WavPack files. This no longer fails on
1871 * WavPack files containing floating-point audio data (although these 1871 * WavPack files containing floating-point audio data because these are
1872 * should be possible to play in theory). 1872 * now converted to standard Rockbox format in the decoder.
1873 */ 1873 */
1874 1874
1875 /* Use the trackname part of the id3 structure as a temporary buffer */ 1875 /* Use the trackname part of the id3 structure as a temporary buffer */
@@ -1887,7 +1887,7 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname,
1887 /* if valid WavPack 4 header version & not floating data, break */ 1887 /* if valid WavPack 4 header version & not floating data, break */
1888 1888
1889 if (memcmp (buf, "wvpk", 4) == 0 && buf [9] == 4 && 1889 if (memcmp (buf, "wvpk", 4) == 0 && buf [9] == 4 &&
1890 (buf [8] >= 2 && buf [8] <= 0x10) && !(buf [24] & 0x80)) 1890 (buf [8] >= 2 && buf [8] <= 0x10))
1891 { 1891 {
1892 break; 1892 break;
1893 } 1893 }