diff options
author | Thom Johansen <thomj@rockbox.org> | 2005-06-09 09:26:05 +0000 |
---|---|---|
committer | Thom Johansen <thomj@rockbox.org> | 2005-06-09 09:26:05 +0000 |
commit | 614f0a333a6263def7e6cd053abfc222dae2ced5 (patch) | |
tree | 85661bc01ed5dd0f5d4d79ac0a86ea78c0d38c1b /apps/codecs/libwavpack/words.c | |
parent | 3ca164549624cc3a107d326a759e40456cedfc21 (diff) | |
download | rockbox-614f0a333a6263def7e6cd053abfc222dae2ced5.tar.gz rockbox-614f0a333a6263def7e6cd053abfc222dae2ced5.zip |
WavPack optimisation by David Bryant.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6635 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwavpack/words.c')
-rw-r--r-- | apps/codecs/libwavpack/words.c | 91 |
1 files changed, 46 insertions, 45 deletions
diff --git a/apps/codecs/libwavpack/words.c b/apps/codecs/libwavpack/words.c index 370c0d4857..8e2fc427a6 100644 --- a/apps/codecs/libwavpack/words.c +++ b/apps/codecs/libwavpack/words.c | |||
@@ -42,19 +42,19 @@ | |||
42 | #define DIV2 32 // 20/343 of samples | 42 | #define DIV2 32 // 20/343 of samples |
43 | 43 | ||
44 | // this macro retrieves the specified median breakpoint (without frac; min = 1) | 44 | // this macro retrieves the specified median breakpoint (without frac; min = 1) |
45 | #define GET_MED(med) (((wps->w.median [med] [chan]) >> 4) + 1) | 45 | #define GET_MED(med) (((c->median [med]) >> 4) + 1) |
46 | 46 | ||
47 | // These macros update the specified median breakpoints. Note that the median | 47 | // These macros update the specified median breakpoints. Note that the median |
48 | // is incremented when the sample is higher than the median, else decremented. | 48 | // is incremented when the sample is higher than the median, else decremented. |
49 | // They are designed so that the median will never drop below 1 and the value | 49 | // They are designed so that the median will never drop below 1 and the value |
50 | // is essentially stationary if there are 2 increments for every 5 decrements. | 50 | // is essentially stationary if there are 2 increments for every 5 decrements. |
51 | 51 | ||
52 | #define INC_MED0() (wps->w.median [0] [chan] += ((wps->w.median [0] [chan] + DIV0) / DIV0) * 5) | 52 | #define INC_MED0() (c->median [0] += ((c->median [0] + DIV0) / DIV0) * 5) |
53 | #define DEC_MED0() (wps->w.median [0] [chan] -= ((wps->w.median [0] [chan] + (DIV0-2)) / DIV0) * 2) | 53 | #define DEC_MED0() (c->median [0] -= ((c->median [0] + (DIV0-2)) / DIV0) * 2) |
54 | #define INC_MED1() (wps->w.median [1] [chan] += ((wps->w.median [1] [chan] + DIV1) / DIV1) * 5) | 54 | #define INC_MED1() (c->median [1] += ((c->median [1] + DIV1) / DIV1) * 5) |
55 | #define DEC_MED1() (wps->w.median [1] [chan] -= ((wps->w.median [1] [chan] + (DIV1-2)) / DIV1) * 2) | 55 | #define DEC_MED1() (c->median [1] -= ((c->median [1] + (DIV1-2)) / DIV1) * 2) |
56 | #define INC_MED2() (wps->w.median [2] [chan] += ((wps->w.median [2] [chan] + DIV2) / DIV2) * 5) | 56 | #define INC_MED2() (c->median [2] += ((c->median [2] + DIV2) / DIV2) * 5) |
57 | #define DEC_MED2() (wps->w.median [2] [chan] -= ((wps->w.median [2] [chan] + (DIV2-2)) / DIV2) * 2) | 57 | #define DEC_MED2() (c->median [2] -= ((c->median [2] + (DIV2-2)) / DIV2) * 2) |
58 | 58 | ||
59 | #define count_bits(av) ( \ | 59 | #define count_bits(av) ( \ |
60 | (av) < (1 << 8) ? nbits_table [av] : \ | 60 | (av) < (1 << 8) ? nbits_table [av] : \ |
@@ -149,14 +149,14 @@ int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd) | |||
149 | if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12)) | 149 | if (wpmd->byte_length != ((wps->wphdr.flags & MONO_FLAG) ? 6 : 12)) |
150 | return FALSE; | 150 | return FALSE; |
151 | 151 | ||
152 | wps->w.median [0] [0] = exp2s (byteptr [0] + (byteptr [1] << 8)); | 152 | wps->w.c [0].median [0] = exp2s (byteptr [0] + (byteptr [1] << 8)); |
153 | wps->w.median [1] [0] = exp2s (byteptr [2] + (byteptr [3] << 8)); | 153 | wps->w.c [0].median [1] = exp2s (byteptr [2] + (byteptr [3] << 8)); |
154 | wps->w.median [2] [0] = exp2s (byteptr [4] + (byteptr [5] << 8)); | 154 | wps->w.c [0].median [2] = exp2s (byteptr [4] + (byteptr [5] << 8)); |
155 | 155 | ||
156 | if (!(wps->wphdr.flags & MONO_FLAG)) { | 156 | if (!(wps->wphdr.flags & MONO_FLAG)) { |
157 | wps->w.median [0] [1] = exp2s (byteptr [6] + (byteptr [7] << 8)); | 157 | wps->w.c [1].median [0] = exp2s (byteptr [6] + (byteptr [7] << 8)); |
158 | wps->w.median [1] [1] = exp2s (byteptr [8] + (byteptr [9] << 8)); | 158 | wps->w.c [1].median [1] = exp2s (byteptr [8] + (byteptr [9] << 8)); |
159 | wps->w.median [2] [1] = exp2s (byteptr [10] + (byteptr [11] << 8)); | 159 | wps->w.c [1].median [2] = exp2s (byteptr [10] + (byteptr [11] << 8)); |
160 | } | 160 | } |
161 | 161 | ||
162 | return TRUE; | 162 | return TRUE; |
@@ -173,11 +173,11 @@ int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd) | |||
173 | uchar *endptr = byteptr + wpmd->byte_length; | 173 | uchar *endptr = byteptr + wpmd->byte_length; |
174 | 174 | ||
175 | if (wps->wphdr.flags & HYBRID_BITRATE) { | 175 | if (wps->wphdr.flags & HYBRID_BITRATE) { |
176 | wps->w.slow_level [0] = exp2s (byteptr [0] + (byteptr [1] << 8)); | 176 | wps->w.c [0].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8)); |
177 | byteptr += 2; | 177 | byteptr += 2; |
178 | 178 | ||
179 | if (!(wps->wphdr.flags & MONO_FLAG)) { | 179 | if (!(wps->wphdr.flags & MONO_FLAG)) { |
180 | wps->w.slow_level [1] = exp2s (byteptr [0] + (byteptr [1] << 8)); | 180 | wps->w.c [1].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8)); |
181 | byteptr += 2; | 181 | byteptr += 2; |
182 | } | 182 | } |
183 | } | 183 | } |
@@ -220,22 +220,22 @@ static void update_error_limit (WavpackStream *wps) | |||
220 | 220 | ||
221 | if (wps->wphdr.flags & MONO_FLAG) { | 221 | if (wps->wphdr.flags & MONO_FLAG) { |
222 | if (wps->wphdr.flags & HYBRID_BITRATE) { | 222 | if (wps->wphdr.flags & HYBRID_BITRATE) { |
223 | int slow_log_0 = (wps->w.slow_level [0] + SLO) >> SLS; | 223 | int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS; |
224 | 224 | ||
225 | if (slow_log_0 - bitrate_0 > -0x100) | 225 | if (slow_log_0 - bitrate_0 > -0x100) |
226 | wps->w.error_limit [0] = exp2s (slow_log_0 - bitrate_0 + 0x100); | 226 | wps->w.c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100); |
227 | else | 227 | else |
228 | wps->w.error_limit [0] = 0; | 228 | wps->w.c [0].error_limit = 0; |
229 | } | 229 | } |
230 | else | 230 | else |
231 | wps->w.error_limit [0] = exp2s (bitrate_0); | 231 | wps->w.c [0].error_limit = exp2s (bitrate_0); |
232 | } | 232 | } |
233 | else { | 233 | else { |
234 | int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16; | 234 | int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16; |
235 | 235 | ||
236 | if (wps->wphdr.flags & HYBRID_BITRATE) { | 236 | if (wps->wphdr.flags & HYBRID_BITRATE) { |
237 | int slow_log_0 = (wps->w.slow_level [0] + SLO) >> SLS; | 237 | int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS; |
238 | int slow_log_1 = (wps->w.slow_level [1] + SLO) >> SLS; | 238 | int slow_log_1 = (wps->w.c [1].slow_level + SLO) >> SLS; |
239 | 239 | ||
240 | if (wps->wphdr.flags & HYBRID_BALANCE) { | 240 | if (wps->wphdr.flags & HYBRID_BALANCE) { |
241 | int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1; | 241 | int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1; |
@@ -255,18 +255,18 @@ static void update_error_limit (WavpackStream *wps) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | if (slow_log_0 - bitrate_0 > -0x100) | 257 | if (slow_log_0 - bitrate_0 > -0x100) |
258 | wps->w.error_limit [0] = exp2s (slow_log_0 - bitrate_0 + 0x100); | 258 | wps->w.c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100); |
259 | else | 259 | else |
260 | wps->w.error_limit [0] = 0; | 260 | wps->w.c [0].error_limit = 0; |
261 | 261 | ||
262 | if (slow_log_1 - bitrate_1 > -0x100) | 262 | if (slow_log_1 - bitrate_1 > -0x100) |
263 | wps->w.error_limit [1] = exp2s (slow_log_1 - bitrate_1 + 0x100); | 263 | wps->w.c [1].error_limit = exp2s (slow_log_1 - bitrate_1 + 0x100); |
264 | else | 264 | else |
265 | wps->w.error_limit [1] = 0; | 265 | wps->w.c [1].error_limit = 0; |
266 | } | 266 | } |
267 | else { | 267 | else { |
268 | wps->w.error_limit [0] = exp2s (bitrate_0); | 268 | wps->w.c [0].error_limit = exp2s (bitrate_0); |
269 | wps->w.error_limit [1] = exp2s (bitrate_1); | 269 | wps->w.c [1].error_limit = exp2s (bitrate_1); |
270 | } | 270 | } |
271 | } | 271 | } |
272 | } | 272 | } |
@@ -283,21 +283,23 @@ static ulong read_code (Bitstream *bs, ulong maxcode); | |||
283 | 283 | ||
284 | long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) | 284 | long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) |
285 | { | 285 | { |
286 | ulong tsamples = nsamples * nchans, ones_count, low, mid, high; | 286 | ulong ones_count, low, mid, high; |
287 | int next8, sign, chan; | 287 | register struct entropy_data *c; |
288 | long *bptr = buffer; | 288 | long *bptr = buffer; |
289 | 289 | ||
290 | while (tsamples--) { | 290 | nsamples *= nchans; |
291 | 291 | ||
292 | chan = (nchans == 1) ? 0 : (~tsamples & 1); | 292 | while (nsamples--) { |
293 | 293 | ||
294 | if (!(wps->w.median [0] [0] & ~1) && !wps->w.holding_zero && !wps->w.holding_one && !(wps->w.median [0] [1] & ~1)) { | 294 | c = wps->w.c + ((nchans == 1) ? 0 : (~nsamples & 1)); |
295 | |||
296 | if (!(wps->w.c [0].median [0] & ~1) && !wps->w.holding_zero && !wps->w.holding_one && !(wps->w.c [1].median [0] & ~1)) { | ||
295 | ulong mask; | 297 | ulong mask; |
296 | int cbits; | 298 | int cbits; |
297 | 299 | ||
298 | if (wps->w.zeros_acc) { | 300 | if (wps->w.zeros_acc) { |
299 | if (--wps->w.zeros_acc) { | 301 | if (--wps->w.zeros_acc) { |
300 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | 302 | c->slow_level -= (c->slow_level + SLO) >> SLS; |
301 | *bptr++ = 0; | 303 | *bptr++ = 0; |
302 | continue; | 304 | continue; |
303 | } | 305 | } |
@@ -319,8 +321,9 @@ long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) | |||
319 | } | 321 | } |
320 | 322 | ||
321 | if (wps->w.zeros_acc) { | 323 | if (wps->w.zeros_acc) { |
322 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | 324 | c->slow_level -= (c->slow_level + SLO) >> SLS; |
323 | CLEAR (wps->w.median); | 325 | CLEAR (wps->w.c [0].median); |
326 | CLEAR (wps->w.c [1].median); | ||
324 | *bptr++ = 0; | 327 | *bptr++ = 0; |
325 | continue; | 328 | continue; |
326 | } | 329 | } |
@@ -330,6 +333,8 @@ long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) | |||
330 | if (wps->w.holding_zero) | 333 | if (wps->w.holding_zero) |
331 | ones_count = wps->w.holding_zero = 0; | 334 | ones_count = wps->w.holding_zero = 0; |
332 | else { | 335 | else { |
336 | int next8; | ||
337 | |||
333 | if (wps->wvbits.bc < 8) { | 338 | if (wps->wvbits.bc < 8) { |
334 | if (++(wps->wvbits.ptr) == wps->wvbits.end) | 339 | if (++(wps->wvbits.ptr) == wps->wvbits.end) |
335 | wps->wvbits.wrap (&wps->wvbits); | 340 | wps->wvbits.wrap (&wps->wvbits); |
@@ -388,7 +393,7 @@ long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) | |||
388 | wps->w.holding_zero = ~wps->w.holding_one & 1; | 393 | wps->w.holding_zero = ~wps->w.holding_one & 1; |
389 | } | 394 | } |
390 | 395 | ||
391 | if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) | 396 | if ((wps->wphdr.flags & HYBRID_FLAG) && (nchans == 1 || (nsamples & 1))) |
392 | update_error_limit (wps); | 397 | update_error_limit (wps); |
393 | 398 | ||
394 | if (ones_count == 0) { | 399 | if (ones_count == 0) { |
@@ -422,23 +427,19 @@ long get_words (WavpackStream *wps, int nchans, int nsamples, long *buffer) | |||
422 | 427 | ||
423 | mid = (high + low + 1) >> 1; | 428 | mid = (high + low + 1) >> 1; |
424 | 429 | ||
425 | if (!wps->w.error_limit [chan]) | 430 | if (!c->error_limit) |
426 | mid = read_code (&wps->wvbits, high - low) + low; | 431 | mid = read_code (&wps->wvbits, high - low) + low; |
427 | else while (high - low > wps->w.error_limit [chan]) { | 432 | else while (high - low > c->error_limit) { |
428 | if (getbit (&wps->wvbits)) | 433 | if (getbit (&wps->wvbits)) |
429 | mid = (high + (low = mid) + 1) >> 1; | 434 | mid = (high + (low = mid) + 1) >> 1; |
430 | else | 435 | else |
431 | mid = ((high = mid - 1) + low + 1) >> 1; | 436 | mid = ((high = mid - 1) + low + 1) >> 1; |
432 | } | 437 | } |
433 | 438 | ||
434 | sign = getbit (&wps->wvbits); | 439 | *bptr++ = getbit (&wps->wvbits) ? ~mid : mid; |
435 | |||
436 | if (wps->wphdr.flags & HYBRID_BITRATE) { | ||
437 | wps->w.slow_level [chan] -= (wps->w.slow_level [chan] + SLO) >> SLS; | ||
438 | wps->w.slow_level [chan] += mylog2 (mid); | ||
439 | } | ||
440 | 440 | ||
441 | *bptr++ = sign ? ~mid : mid; | 441 | if (wps->wphdr.flags & HYBRID_BITRATE) |
442 | c->slow_level = c->slow_level - ((c->slow_level + SLO) >> SLS) + mylog2 (mid); | ||
442 | } | 443 | } |
443 | 444 | ||
444 | return nchans == 1 ? (bptr - buffer) : ((bptr - buffer) / 2); | 445 | return nchans == 1 ? (bptr - buffer) : ((bptr - buffer) / 2); |