summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libwavpack
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libwavpack')
-rw-r--r--lib/rbcodec/codecs/libwavpack/LICENSE25
-rw-r--r--lib/rbcodec/codecs/libwavpack/README52
-rw-r--r--lib/rbcodec/codecs/libwavpack/README.rockbox15
-rw-r--r--lib/rbcodec/codecs/libwavpack/SOURCES15
-rw-r--r--lib/rbcodec/codecs/libwavpack/arm.S477
-rw-r--r--lib/rbcodec/codecs/libwavpack/arml.S506
-rw-r--r--lib/rbcodec/codecs/libwavpack/bits.c170
-rw-r--r--lib/rbcodec/codecs/libwavpack/coldfire.S537
-rw-r--r--lib/rbcodec/codecs/libwavpack/float.c47
-rw-r--r--lib/rbcodec/codecs/libwavpack/libwavpack.make18
-rw-r--r--lib/rbcodec/codecs/libwavpack/make.bat1
-rw-r--r--lib/rbcodec/codecs/libwavpack/metadata.c171
-rw-r--r--lib/rbcodec/codecs/libwavpack/pack.c470
-rw-r--r--lib/rbcodec/codecs/libwavpack/unpack.c780
-rw-r--r--lib/rbcodec/codecs/libwavpack/wavpack.h447
-rw-r--r--lib/rbcodec/codecs/libwavpack/words.c786
-rw-r--r--lib/rbcodec/codecs/libwavpack/wputils.c555
17 files changed, 5072 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libwavpack/LICENSE b/lib/rbcodec/codecs/libwavpack/LICENSE
new file mode 100644
index 0000000000..3ee485817d
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/LICENSE
@@ -0,0 +1,25 @@
1 Copyright (c) 1998 - 2004 Conifer Software
2 All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice,
8 this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright notice,
10 this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of Conifer Software nor the names of its contributors
13 may be used to endorse or promote products derived from this software
14 without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
20ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/lib/rbcodec/codecs/libwavpack/README b/lib/rbcodec/codecs/libwavpack/README
new file mode 100644
index 0000000000..b373235e1c
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/README
@@ -0,0 +1,52 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9This package contains a tiny version of the WavPack 4.0 decoder that might
10be used in a "resource limited" CPU environment or form the basis for a
11hardware decoding implementation. It is packaged with a demo command-line
12program that accepts a WavPack audio file on stdin and outputs a RIFF wav
13file to stdout. The program is standard C, and a win32 executable is
14included which was compiled under MS Visual C++ 6.0 using this command:
15
16cl /O1 /DWIN32 wvfilter.c wputils.c unpack.c float.c metadata.c words.c bits.c
17
18WavPack data is read with a stream reading callback. No direct seeking is
19provided for, but it is possible to start decoding anywhere in a WavPack
20stream. In this case, WavPack will be able to provide the sample-accurate
21position when it synchs with the data and begins decoding.
22
23For demonstration purposes this uses a single static copy of the
24WavpackContext structure, so obviously it cannot be used for more than one
25file at a time. Also, this decoder will not handle "correction" files, plays
26only the first two channels of multi-channel files, and is limited in
27resolution in some large integer or floating point files (but always
28provides at least 24 bits of resolution). It also will not accept WavPack
29files from before version 4.0.
30
31To make this code viable on the greatest number of hardware platforms, the
32following are true:
33
34 speed is about 4x realtime on an AMD K6 300 MHz
35 ("high" mode 16/44 stereo; normal mode is about twice that fast)
36
37 no floating-point math required; just 32b * 32b = 32b int multiply
38
39 large data areas are static and less than 4K total
40 executable code and tables are less than 32K
41 no malloc / free usage
42
43To maintain compatibility on various platforms, the following conventions
44are used:
45
46 a "short" must be 16-bits
47 a "long" must be 32-bits
48 an "int" must be at least 16-bits, but may be larger
49 a "char" must default to signed
50
51
52Questions or comments should be directed to david@wavpack.com
diff --git a/lib/rbcodec/codecs/libwavpack/README.rockbox b/lib/rbcodec/codecs/libwavpack/README.rockbox
new file mode 100644
index 0000000000..a74b0c511c
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/README.rockbox
@@ -0,0 +1,15 @@
1Library: wavpack - Release 4.1 - September 14, 2004
2Imported: 2005-02-25 by Christian Gmeiner
3
4
5This directory contains a "tiny" decoder version of wavpack for version 4.x.
6
7LICENSING INFORMATION
8
9wavpack is released under the BSD License as described
10in the LICENSE file in this directory.
11
12
13IMPORT DETAILS
14
15Excluded is wvfilter.c, because it is only a test programm.
diff --git a/lib/rbcodec/codecs/libwavpack/SOURCES b/lib/rbcodec/codecs/libwavpack/SOURCES
new file mode 100644
index 0000000000..b2518e59e0
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/SOURCES
@@ -0,0 +1,15 @@
1bits.c
2float.c
3metadata.c
4unpack.c
5pack.c
6words.c
7wputils.c
8#if defined(CPU_COLDFIRE)
9coldfire.S
10#endif
11#if defined(CPU_ARM)
12arm.S
13arml.S
14#endif
15
diff --git a/lib/rbcodec/codecs/libwavpack/arm.S b/lib/rbcodec/codecs/libwavpack/arm.S
new file mode 100644
index 0000000000..32de1df7de
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/arm.S
@@ -0,0 +1,477 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by David Bryant
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/* This is an assembly optimized version of the following WavPack function:
23 *
24 * void decorr_stereo_pass_cont_arm (struct decorr_pass *dpp,
25 * long *buffer, long sample_count);
26 *
27 * It performs a single pass of stereo decorrelation on the provided buffer.
28 * Note that this version of the function requires that the 8 previous stereo
29 * samples are visible and correct. In other words, it ignores the "samples_*"
30 * fields in the decorr_pass structure and gets the history data directly
31 * from the buffer. It does, however, return the appropriate history samples
32 * to the decorr_pass structure before returning.
33 *
34 * This is written to work on a ARM7TDMI processor. This version only uses the
35 * 32-bit multiply-accumulate instruction and so will overflow with 24-bit
36 * WavPack files.
37 */
38
39#include "config.h"
40
41 .text
42 .align
43 .global decorr_stereo_pass_cont_arm
44
45/*
46 * on entry:
47 *
48 * r0 = struct decorr_pass *dpp
49 * r1 = long *buffer
50 * r2 = long sample_count
51 */
52
53decorr_stereo_pass_cont_arm:
54
55 stmfd sp!, {r4 - r8, r10, r11, lr}
56 mov r5, r0 @ r5 = dpp
57 mov r11, #512 @ r11 = 512 for rounding
58 ldrsh r6, [r0, #2] @ r6 = dpp->delta
59 ldrsh r4, [r0, #4] @ r4 = dpp->weight_A
60 ldrsh r0, [r0, #6] @ r0 = dpp->weight_B
61 cmp r2, #0 @ exit if no samples to process
62 beq common_exit
63
64 add r7, r1, r2, asl #3 @ r7 = buffer ending position
65 ldrsh r2, [r5, #0] @ r2 = dpp->term
66 cmp r2, #0
67 bmi minus_term
68
69 ldr lr, [r1, #-16] @ load 2 sample history from buffer
70 ldr r10, [r1, #-12] @ for terms 2, 17, and 18
71 ldr r8, [r1, #-8]
72 ldr r3, [r1, #-4]
73 cmp r2, #17
74 beq term_17_loop
75 cmp r2, #18
76 beq term_18_loop
77 cmp r2, #2
78 beq term_2_loop
79 b term_default_loop @ else handle default (1-8, except 2)
80
81minus_term:
82 mov r10, #1024 @ r10 = -1024 for weight clipping
83 rsb r10, r10, #0 @ (only used for negative terms)
84 cmn r2, #1
85 beq term_minus_1
86 cmn r2, #2
87 beq term_minus_2
88 cmn r2, #3
89 beq term_minus_3
90 b common_exit
91
92/*
93 ******************************************************************************
94 * Loop to handle term = 17 condition
95 *
96 * r0 = dpp->weight_B r8 = previous left sample
97 * r1 = bptr r9 =
98 * r2 = current sample r10 = second previous left sample
99 * r3 = previous right sample r11 = 512 (for rounding)
100 * r4 = dpp->weight_A ip = current decorrelation value
101 * r5 = dpp sp =
102 * r6 = dpp->delta lr = second previous right sample
103 * r7 = eptr pc =
104 *******************************************************************************
105 */
106
107term_17_loop:
108 rsbs ip, lr, r8, asl #1 @ decorr value = (2 * prev) - 2nd prev
109 mov lr, r8 @ previous becomes 2nd previous
110 ldr r2, [r1], #4 @ get sample & update pointer
111 mla r8, ip, r4, r11 @ mult decorr value by weight, round,
112 add r8, r2, r8, asr #10 @ shift, and add to new sample
113 strne r8, [r1, #-4] @ if change possible, store sample back
114 cmpne r2, #0
115 beq .L325
116 teq ip, r2 @ update weight based on signs
117 submi r4, r4, r6
118 addpl r4, r4, r6
119
120.L325: rsbs ip, r10, r3, asl #1 @ do same thing for right channel
121 mov r10, r3
122 ldr r2, [r1], #4
123 mla r3, ip, r0, r11
124 add r3, r2, r3, asr #10
125 strne r3, [r1, #-4]
126 cmpne r2, #0
127 beq .L329
128 teq ip, r2
129 submi r0, r0, r6
130 addpl r0, r0, r6
131
132.L329: cmp r7, r1 @ loop back if more samples to do
133 bhi term_17_loop
134 b store_1718 @ common exit for terms 17 & 18
135
136/*
137 ******************************************************************************
138 * Loop to handle term = 18 condition
139 *
140 * r0 = dpp->weight_B r8 = previous left sample
141 * r1 = bptr r9 =
142 * r2 = current sample r10 = second previous left sample
143 * r3 = previous right sample r11 = 512 (for rounding)
144 * r4 = dpp->weight_A ip = decorrelation value
145 * r5 = dpp sp =
146 * r6 = dpp->delta lr = second previous right sample
147 * r7 = eptr pc =
148 *******************************************************************************
149 */
150
151term_18_loop:
152 sub ip, r8, lr @ decorr value =
153 mov lr, r8 @ ((3 * prev) - 2nd prev) >> 1
154 adds ip, r8, ip, asr #1
155 ldr r2, [r1], #4 @ get sample & update pointer
156 mla r8, ip, r4, r11 @ mult decorr value by weight, round,
157 add r8, r2, r8, asr #10 @ shift, and add to new sample
158 strne r8, [r1, #-4] @ if change possible, store sample back
159 cmpne r2, #0
160 beq .L337
161 teq ip, r2 @ update weight based on signs
162 submi r4, r4, r6
163 addpl r4, r4, r6
164
165.L337: sub ip, r3, r10 @ do same thing for right channel
166 mov r10, r3
167 adds ip, r3, ip, asr #1
168 ldr r2, [r1], #4
169 mla r3, ip, r0, r11
170 add r3, r2, r3, asr #10
171 strne r3, [r1, #-4]
172 cmpne r2, #0
173 beq .L341
174 teq ip, r2
175 submi r0, r0, r6
176 addpl r0, r0, r6
177
178.L341: cmp r7, r1 @ loop back if more samples to do
179 bhi term_18_loop
180
181/* common exit for terms 17 & 18 */
182
183store_1718:
184 str r3, [r5, #40] @ store sample history into struct
185 str r8, [r5, #8]
186 str r10, [r5, #44]
187 str lr, [r5, #12]
188 b common_exit @ and return
189
190/*
191 ******************************************************************************
192 * Loop to handle term = 2 condition
193 * (note that this case can be handled by the default term handler (1-8), but
194 * this special case is faster because it doesn't have to read memory twice)
195 *
196 * r0 = dpp->weight_B r8 = previous left sample
197 * r1 = bptr r9 =
198 * r2 = current sample r10 = second previous left sample
199 * r3 = previous right sample r11 = 512 (for rounding)
200 * r4 = dpp->weight_A ip = decorrelation value
201 * r5 = dpp sp =
202 * r6 = dpp->delta lr = second previous right sample
203 * r7 = eptr pc =
204 *******************************************************************************
205 */
206
207term_2_loop:
208 movs ip, lr @ get decorrelation value & test
209 mov lr, r8 @ previous becomes 2nd previous
210 ldr r2, [r1], #4 @ get sample & update pointer
211 mla r8, ip, r4, r11 @ mult decorr value by weight, round,
212 add r8, r2, r8, asr #10 @ shift, and add to new sample
213 strne r8, [r1, #-4] @ if change possible, store sample back
214 cmpne r2, #0
215 beq .L225
216 teq ip, r2 @ update weight based on signs
217 submi r4, r4, r6
218 addpl r4, r4, r6
219
220.L225: movs ip, r10 @ do same thing for right channel
221 mov r10, r3
222 ldr r2, [r1], #4
223 mla r3, ip, r0, r11
224 add r3, r2, r3, asr #10
225 strne r3, [r1, #-4]
226 cmpne r2, #0
227 beq .L229
228 teq ip, r2
229 submi r0, r0, r6
230 addpl r0, r0, r6
231
232.L229: cmp r7, r1 @ loop back if more samples to do
233 bhi term_2_loop
234 b default_term_exit @ this exit updates all dpp->samples
235
236/*
237 ******************************************************************************
238 * Loop to handle default term condition
239 *
240 * r0 = dpp->weight_B r8 = result accumulator
241 * r1 = bptr r9 =
242 * r2 = dpp->term r10 =
243 * r3 = decorrelation value r11 = 512 (for rounding)
244 * r4 = dpp->weight_A ip = current sample
245 * r5 = dpp sp =
246 * r6 = dpp->delta lr =
247 * r7 = eptr pc =
248 *******************************************************************************
249 */
250
251term_default_loop:
252 ldr ip, [r1] @ get original sample
253 ldr r3, [r1, -r2, asl #3] @ get decorrelation value based on term
254 mla r8, r3, r4, r11 @ mult decorr value by weight, round,
255 add r8, ip, r8, asr #10 @ shift and add to new sample
256 str r8, [r1], #4 @ store update sample
257 cmp r3, #0
258 cmpne ip, #0
259 beq .L350
260 teq ip, r3 @ update weight based on signs
261 submi r4, r4, r6
262 addpl r4, r4, r6
263
264.L350: ldr ip, [r1] @ do the same thing for right channel
265 ldr r3, [r1, -r2, asl #3]
266 mla r8, r3, r0, r11
267 add r8, ip, r8, asr #10
268 str r8, [r1], #4
269 cmp r3, #0
270 cmpne ip, #0
271 beq .L354
272 teq ip, r3
273 submi r0, r0, r6
274 addpl r0, r0, r6
275
276.L354: cmp r7, r1 @ loop back if more samples to do
277 bhi term_default_loop
278
279/*
280 * This exit is used by terms 1-8 to store the previous 8 samples into the decorr
281 * structure (even if they are not all used for the given term)
282 */
283
284default_term_exit:
285 ldrsh r3, [r5, #0]
286 sub ip, r3, #1
287 mov lr, #7
288
289.L358: and r3, ip, #7
290 add r3, r5, r3, asl #2
291 ldr r2, [r1, #-4]
292 str r2, [r3, #40]
293 ldr r2, [r1, #-8]!
294 str r2, [r3, #8]
295 sub ip, ip, #1
296 sub lr, lr, #1
297 cmn lr, #1
298 bne .L358
299 b common_exit
300
301/*
302 ******************************************************************************
303 * Loop to handle term = -1 condition
304 *
305 * r0 = dpp->weight_B r8 =
306 * r1 = bptr r9 =
307 * r2 = intermediate result r10 = -1024 (for clipping)
308 * r3 = previous right sample r11 = 512 (for rounding)
309 * r4 = dpp->weight_A ip = current sample
310 * r5 = dpp sp =
311 * r6 = dpp->delta lr = updated left sample
312 * r7 = eptr pc =
313 *******************************************************************************
314 */
315
316term_minus_1:
317 ldr r3, [r1, #-4]
318
319term_minus_1_loop:
320 ldr ip, [r1] @ for left channel the decorrelation value
321 mla r2, r3, r4, r11 @ is the previous right sample (in r3)
322 add lr, ip, r2, asr #10
323 str lr, [r1], #8
324 cmp r3, #0
325 cmpne ip, #0
326 beq .L361
327 teq ip, r3 @ update weight based on signs
328 submi r4, r4, r6
329 addpl r4, r4, r6
330 cmp r4, #1024
331 movgt r4, #1024
332 cmp r4, r10
333 movlt r4, r10
334
335.L361: ldr r2, [r1, #-4] @ for right channel the decorrelation value
336 mla r3, lr, r0, r11 @ is the just updated right sample (in lr)
337 add r3, r2, r3, asr #10
338 str r3, [r1, #-4]
339 cmp lr, #0
340 cmpne r2, #0
341 beq .L369
342 teq r2, lr
343 submi r0, r0, r6
344 addpl r0, r0, r6
345 cmp r0, #1024 @ then clip weight to +/-1024
346 movgt r0, #1024
347 cmp r0, r10
348 movlt r0, r10
349
350.L369: cmp r7, r1 @ loop back if more samples to do
351 bhi term_minus_1_loop
352
353 str r3, [r5, #8] @ else store right sample and exit
354 b common_exit
355
356/*
357 ******************************************************************************
358 * Loop to handle term = -2 condition
359 * (note that the channels are processed in the reverse order here)
360 *
361 * r0 = dpp->weight_B r8 =
362 * r1 = bptr r9 =
363 * r2 = intermediate result r10 = -1024 (for clipping)
364 * r3 = previous left sample r11 = 512 (for rounding)
365 * r4 = dpp->weight_A ip = current sample
366 * r5 = dpp sp =
367 * r6 = dpp->delta lr = updated right sample
368 * r7 = eptr pc =
369 *******************************************************************************
370 */
371
372term_minus_2:
373 ldr r3, [r1, #-8]
374
375term_minus_2_loop:
376 ldr ip, [r1, #4] @ for right channel the decorrelation value
377 mla r2, r3, r0, r11 @ is the previous left sample (in r3)
378 add lr, ip, r2, asr #10
379 str lr, [r1, #4]
380 cmp r3, #0
381 cmpne ip, #0
382 beq .L380
383 teq ip, r3 @ update weight based on signs
384 submi r0, r0, r6
385 addpl r0, r0, r6
386 cmp r0, #1024 @ then clip weight to +/-1024
387 movgt r0, #1024
388 cmp r0, r10
389 movlt r0, r10
390
391.L380: ldr r2, [r1, #0] @ for left channel the decorrelation value
392 mla r3, lr, r4, r11 @ is the just updated left sample (in lr)
393 add r3, r2, r3, asr #10
394 str r3, [r1], #8
395 cmp lr, #0
396 cmpne r2, #0
397 beq .L388
398 teq r2, lr
399 submi r4, r4, r6
400 addpl r4, r4, r6
401 cmp r4, #1024
402 movgt r4, #1024
403 cmp r4, r10
404 movlt r4, r10
405
406.L388: cmp r7, r1 @ loop back if more samples to do
407 bhi term_minus_2_loop
408
409 str r3, [r5, #40] @ else store left channel and exit
410 b common_exit
411
412/*
413 ******************************************************************************
414 * Loop to handle term = -3 condition
415 *
416 * r0 = dpp->weight_B r8 = previous left sample
417 * r1 = bptr r9 =
418 * r2 = current left sample r10 = -1024 (for clipping)
419 * r3 = previous right sample r11 = 512 (for rounding)
420 * r4 = dpp->weight_A ip = intermediate result
421 * r5 = dpp sp =
422 * r6 = dpp->delta lr =
423 * r7 = eptr pc =
424 *******************************************************************************
425 */
426
427term_minus_3:
428 ldr r3, [r1, #-4] @ load previous samples
429 ldr r8, [r1, #-8]
430
431term_minus_3_loop:
432 ldr ip, [r1]
433 mla r2, r3, r4, r11
434 add r2, ip, r2, asr #10
435 str r2, [r1], #4
436 cmp r3, #0
437 cmpne ip, #0
438 beq .L399
439 teq ip, r3 @ update weight based on signs
440 submi r4, r4, r6
441 addpl r4, r4, r6
442 cmp r4, #1024 @ then clip weight to +/-1024
443 movgt r4, #1024
444 cmp r4, r10
445 movlt r4, r10
446
447.L399: movs ip, r8 @ ip = previous left we use now
448 mov r8, r2 @ r8 = current left we use next time
449 ldr r2, [r1], #4
450 mla r3, ip, r0, r11
451 add r3, r2, r3, asr #10
452 strne r3, [r1, #-4]
453 cmpne r2, #0
454 beq .L407
455 teq ip, r2
456 submi r0, r0, r6
457 addpl r0, r0, r6
458 cmp r0, #1024
459 movgt r0, #1024
460 cmp r0, r10
461 movlt r0, r10
462
463.L407: cmp r7, r1 @ loop back if more samples to do
464 bhi term_minus_3_loop
465
466 str r3, [r5, #8] @ else store previous samples & exit
467 str r8, [r5, #40]
468
469/*
470 * Before finally exiting we must store weights back for next time
471 */
472
473common_exit:
474 strh r4, [r5, #4]
475 strh r0, [r5, #6]
476 ldmpc regs="r4-r8, r10-r11"
477
diff --git a/lib/rbcodec/codecs/libwavpack/arml.S b/lib/rbcodec/codecs/libwavpack/arml.S
new file mode 100644
index 0000000000..60818aa1e6
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/arml.S
@@ -0,0 +1,506 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by David Bryant
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/* This is an assembly optimized version of the following WavPack function:
23 *
24 * void decorr_stereo_pass_cont_arml (struct decorr_pass *dpp,
25 * long *buffer, long sample_count);
26 *
27 * It performs a single pass of stereo decorrelation on the provided buffer.
28 * Note that this version of the function requires that the 8 previous stereo
29 * samples are visible and correct. In other words, it ignores the "samples_*"
30 * fields in the decorr_pass structure and gets the history data directly
31 * from the buffer. It does, however, return the appropriate history samples
32 * to the decorr_pass structure before returning.
33 *
34 * This is written to work on a ARM7TDMI processor. This version uses the
35 * 64-bit multiply-accumulate instruction and so can be used with all
36 * WavPack files. However, for optimum performance with 16-bit WavPack
37 * files, there is a faster version that only uses the 32-bit MLA
38 * instruction.
39 */
40
41#include "config.h"
42
43 .text
44 .align
45 .global decorr_stereo_pass_cont_arml
46
47/*
48 * on entry:
49 *
50 * r0 = struct decorr_pass *dpp
51 * r1 = long *buffer
52 * r2 = long sample_count
53 */
54
55decorr_stereo_pass_cont_arml:
56
57 stmfd sp!, {r4 - r8, r10, r11, lr}
58 mov r5, r0 @ r5 = dpp
59 mov r11, #512 @ r11 = 512 for rounding
60 ldrsh r6, [r0, #2] @ r6 = dpp->delta
61 ldrsh r4, [r0, #4] @ r4 = dpp->weight_A
62 ldrsh r0, [r0, #6] @ r0 = dpp->weight_B
63 cmp r2, #0 @ exit if no samples to process
64 beq common_exit
65
66 mov r0, r0, asl #18 @ for 64-bit math we use weights << 18
67 mov r4, r4, asl #18
68 mov r6, r6, asl #18
69 add r7, r1, r2, asl #3 @ r7 = buffer ending position
70 ldrsh r2, [r5, #0] @ r2 = dpp->term
71 cmp r2, #0
72 blt minus_term
73
74 ldr lr, [r1, #-16] @ load 2 sample history from buffer
75 ldr r10, [r1, #-12] @ for terms 2, 17, and 18
76 ldr r8, [r1, #-8]
77 ldr r3, [r1, #-4]
78
79 cmp r2, #18
80 beq term_18_loop
81 mov lr, lr, asl #4
82 mov r10, r10, asl #4
83 cmp r2, #2
84 beq term_2_loop
85 cmp r2, #17
86 beq term_17_loop
87 b term_default_loop
88
89minus_term:
90 mov r10, #(1024 << 18) @ r10 = -1024 << 18 for weight clipping
91 rsb r10, r10, #0 @ (only used for negative terms)
92 cmn r2, #1
93 beq term_minus_1
94 cmn r2, #2
95 beq term_minus_2
96 cmn r2, #3
97 beq term_minus_3
98 b common_exit
99
100/*
101 ******************************************************************************
102 * Loop to handle term = 17 condition
103 *
104 * r0 = dpp->weight_B r8 = previous left sample
105 * r1 = bptr r9 =
106 * r2 = current sample r10 = second previous left sample << 4
107 * r3 = previous right sample r11 = lo accumulator (for rounding)
108 * r4 = dpp->weight_A ip = current decorrelation value
109 * r5 = dpp sp =
110 * r6 = dpp->delta lr = second previous right sample << 4
111 * r7 = eptr pc =
112 *******************************************************************************
113 */
114
115term_17_loop:
116 rsbs ip, lr, r8, asl #5 @ decorr value = (2 * prev) - 2nd prev
117 mov lr, r8, asl #4 @ previous becomes 2nd previous
118 ldr r2, [r1], #4 @ get sample & update pointer
119 mov r11, #0x80000000
120 mov r8, r2
121 smlalne r11, r8, r4, ip
122 strne r8, [r1, #-4] @ if change possible, store sample back
123 cmpne r2, #0
124 beq .L325
125 teq ip, r2 @ update weight based on signs
126 submi r4, r4, r6
127 addpl r4, r4, r6
128
129.L325: rsbs ip, r10, r3, asl #5 @ do same thing for right channel
130 mov r10, r3, asl #4
131 ldr r2, [r1], #4
132 mov r11, #0x80000000
133 mov r3, r2
134 smlalne r11, r3, r0, ip
135 strne r3, [r1, #-4]
136 cmpne r2, #0
137 beq .L329
138 teq ip, r2
139 submi r0, r0, r6
140 addpl r0, r0, r6
141
142.L329: cmp r7, r1 @ loop back if more samples to do
143 bhi term_17_loop
144 mov lr, lr, asr #4
145 mov r10, r10, asr #4
146 b store_1718 @ common exit for terms 17 & 18
147
148/*
149 ******************************************************************************
150 * Loop to handle term = 18 condition
151 *
152 * r0 = dpp->weight_B r8 = previous left sample
153 * r1 = bptr r9 =
154 * r2 = current sample r10 = second previous left sample
155 * r3 = previous right sample r11 = lo accumulator (for rounding)
156 * r4 = dpp->weight_A ip = decorrelation value
157 * r5 = dpp sp =
158 * r6 = dpp->delta lr = second previous right sample
159 * r7 = eptr pc =
160 *******************************************************************************
161 */
162
163term_18_loop:
164 rsb ip, lr, r8 @ decorr value =
165 mov lr, r8 @ ((3 * prev) - 2nd prev) >> 1
166 add ip, lr, ip, asr #1
167 movs ip, ip, asl #4
168 ldr r2, [r1], #4 @ get sample & update pointer
169 mov r11, #0x80000000
170 mov r8, r2
171 smlalne r11, r8, r4, ip
172 strne r8, [r1, #-4] @ if change possible, store sample back
173 cmpne r2, #0
174 beq .L337
175 teq ip, r2 @ update weight based on signs
176 submi r4, r4, r6
177 addpl r4, r4, r6
178
179.L337: rsb ip, r10, r3 @ do same thing for right channel
180 mov r10, r3
181 add ip, r10, ip, asr #1
182 movs ip, ip, asl #4
183 ldr r2, [r1], #4
184 mov r11, #0x80000000
185 mov r3, r2
186 smlalne r11, r3, r0, ip
187 strne r3, [r1, #-4]
188 cmpne r2, #0
189 beq .L341
190 teq ip, r2
191 submi r0, r0, r6
192 addpl r0, r0, r6
193
194.L341: cmp r7, r1 @ loop back if more samples to do
195 bhi term_18_loop
196
197/* common exit for terms 17 & 18 */
198
199store_1718:
200 str r3, [r5, #40] @ store sample history into struct
201 str r8, [r5, #8]
202 str r10, [r5, #44]
203 str lr, [r5, #12]
204 b common_exit @ and return
205
206/*
207 ******************************************************************************
208 * Loop to handle term = 2 condition
209 * (note that this case can be handled by the default term handler (1-8), but
210 * this special case is faster because it doesn't have to read memory twice)
211 *
212 * r0 = dpp->weight_B r8 = previous left sample
213 * r1 = bptr r9 =
214 * r2 = current sample r10 = second previous left sample << 4
215 * r3 = previous right sample r11 = lo accumulator (for rounding)
216 * r4 = dpp->weight_A ip = decorrelation value
217 * r5 = dpp sp =
218 * r6 = dpp->delta lr = second previous right sample << 4
219 * r7 = eptr pc =
220 *******************************************************************************
221 */
222
223term_2_loop:
224 movs ip, lr @ get decorrelation value & test
225 ldr r2, [r1], #4 @ get sample & update pointer
226 mov lr, r8, asl #4 @ previous becomes 2nd previous
227 mov r11, #0x80000000
228 mov r8, r2
229 smlalne r11, r8, r4, ip
230 strne r8, [r1, #-4] @ if change possible, store sample back
231 cmpne r2, #0
232 beq .L225
233 teq ip, r2 @ update weight based on signs
234 submi r4, r4, r6
235 addpl r4, r4, r6
236
237.L225: movs ip, r10 @ do same thing for right channel
238 ldr r2, [r1], #4
239 mov r10, r3, asl #4
240 mov r11, #0x80000000
241 mov r3, r2
242 smlalne r11, r3, r0, ip
243 strne r3, [r1, #-4]
244 cmpne r2, #0
245 beq .L229
246 teq ip, r2
247 submi r0, r0, r6
248 addpl r0, r0, r6
249
250.L229: cmp r7, r1 @ loop back if more samples to do
251 bhi term_2_loop
252
253 b default_term_exit @ this exit updates all dpp->samples
254
255/*
256 ******************************************************************************
257 * Loop to handle default term condition
258 *
259 * r0 = dpp->weight_B r8 = result accumulator
260 * r1 = bptr r9 =
261 * r2 = dpp->term r10 =
262 * r3 = decorrelation value r11 = lo accumulator (for rounding)
263 * r4 = dpp->weight_A ip = current sample
264 * r5 = dpp sp =
265 * r6 = dpp->delta lr =
266 * r7 = eptr pc =
267 *******************************************************************************
268 */
269
270term_default_loop:
271 ldr r3, [r1, -r2, asl #3] @ get decorrelation value based on term
272 ldr ip, [r1], #4 @ get original sample and bump ptr
273 movs r3, r3, asl #4
274 mov r11, #0x80000000
275 mov r8, ip
276 smlalne r11, r8, r4, r3
277 strne r8, [r1, #-4] @ if possibly changed, store updated sample
278 cmpne ip, #0
279 beq .L350
280 teq ip, r3 @ update weight based on signs
281 submi r4, r4, r6
282 addpl r4, r4, r6
283
284.L350: ldr r3, [r1, -r2, asl #3] @ do the same thing for right channel
285 ldr ip, [r1], #4
286 movs r3, r3, asl #4
287 mov r11, #0x80000000
288 mov r8, ip
289 smlalne r11, r8, r0, r3
290 strne r8, [r1, #-4]
291 cmpne ip, #0
292 beq .L354
293 teq ip, r3
294 submi r0, r0, r6
295 addpl r0, r0, r6
296
297.L354: cmp r7, r1 @ loop back if more samples to do
298 bhi term_default_loop
299
300/*
301 * This exit is used by terms 1-8 to store the previous 8 samples into the decorr
302 * structure (even if they are not all used for the given term)
303 */
304
305default_term_exit:
306 ldrsh r3, [r5, #0]
307 sub ip, r3, #1
308 mov lr, #7
309
310.L358: and r3, ip, #7
311 add r3, r5, r3, asl #2
312 ldr r2, [r1, #-4]
313 str r2, [r3, #40]
314 ldr r2, [r1, #-8]!
315 str r2, [r3, #8]
316 sub ip, ip, #1
317 sub lr, lr, #1
318 cmn lr, #1
319 bne .L358
320 b common_exit
321
322/*
323 ******************************************************************************
324 * Loop to handle term = -1 condition
325 *
326 * r0 = dpp->weight_B r8 =
327 * r1 = bptr r9 =
328 * r2 = intermediate result r10 = -1024 (for clipping)
329 * r3 = previous right sample r11 = lo accumulator (for rounding)
330 * r4 = dpp->weight_A ip = current sample
331 * r5 = dpp sp =
332 * r6 = dpp->delta lr = updated left sample
333 * r7 = eptr pc =
334 *******************************************************************************
335 */
336
337term_minus_1:
338 ldr r3, [r1, #-4]
339
340term_minus_1_loop:
341 ldr ip, [r1], #8 @ for left channel the decorrelation value
342 movs r3, r3, asl #4 @ is the previous right sample (in r3)
343 mov r11, #0x80000000
344 mov lr, ip
345 smlalne r11, lr, r4, r3
346 strne lr, [r1, #-8]
347 cmpne ip, #0
348 beq .L361
349 teq ip, r3 @ update weight based on signs
350 submi r4, r4, r6
351 addpl r4, r4, r6
352 cmp r4, #(1024 << 18)
353 movgt r4, #(1024 << 18)
354 cmp r4, r10
355 movlt r4, r10
356
357.L361: ldr r2, [r1, #-4] @ for right channel the decorrelation value
358 movs lr, lr, asl #4
359 mov r11, #0x80000000
360 mov r3, r2
361 smlalne r11, r3, r0, lr
362 strne r3, [r1, #-4]
363 cmpne r2, #0
364 beq .L369
365 teq r2, lr
366 submi r0, r0, r6
367 addpl r0, r0, r6
368 cmp r0, #(1024 << 18) @ then clip weight to +/-1024
369 movgt r0, #(1024 << 18)
370 cmp r0, r10
371 movlt r0, r10
372
373.L369: cmp r7, r1 @ loop back if more samples to do
374 bhi term_minus_1_loop
375
376 str r3, [r5, #8] @ else store right sample and exit
377 b common_exit
378
379/*
380 ******************************************************************************
381 * Loop to handle term = -2 condition
382 * (note that the channels are processed in the reverse order here)
383 *
384 * r0 = dpp->weight_B r8 =
385 * r1 = bptr r9 =
386 * r2 = intermediate result r10 = -1024 (for clipping)
387 * r3 = previous left sample r11 = lo accumulator (for rounding)
388 * r4 = dpp->weight_A ip = current sample
389 * r5 = dpp sp =
390 * r6 = dpp->delta lr = updated right sample
391 * r7 = eptr pc =
392 *******************************************************************************
393 */
394
395term_minus_2:
396 ldr r3, [r1, #-8]
397
398term_minus_2_loop:
399 ldr ip, [r1, #4] @ for right channel the decorrelation value
400 movs r3, r3, asl #4 @ is the previous left sample (in r3)
401 mov r11, #0x80000000
402 mov lr, ip
403 smlalne r11, lr, r0, r3
404 strne lr, [r1, #4]
405 cmpne ip, #0
406 beq .L380
407 teq ip, r3 @ update weight based on signs
408 submi r0, r0, r6
409 addpl r0, r0, r6
410 cmp r0, #(1024 << 18) @ then clip weight to +/-1024
411 movgt r0, #(1024 << 18)
412 cmp r0, r10
413 movlt r0, r10
414
415.L380: ldr r2, [r1], #8 @ for left channel the decorrelation value
416 movs lr, lr, asl #4
417 mov r11, #0x80000000
418 mov r3, r2
419 smlalne r11, r3, r4, lr
420 strne r3, [r1, #-8]
421 cmpne r2, #0
422 beq .L388
423 teq r2, lr
424 submi r4, r4, r6
425 addpl r4, r4, r6
426 cmp r4, #(1024 << 18)
427 movgt r4, #(1024 << 18)
428 cmp r4, r10
429 movlt r4, r10
430
431.L388: cmp r7, r1 @ loop back if more samples to do
432 bhi term_minus_2_loop
433
434 str r3, [r5, #40] @ else store left channel and exit
435 b common_exit
436
437/*
438 ******************************************************************************
439 * Loop to handle term = -3 condition
440 *
441 * r0 = dpp->weight_B r8 = previous left sample
442 * r1 = bptr r9 =
443 * r2 = current left sample r10 = -1024 (for clipping)
444 * r3 = previous right sample r11 = lo accumulator (for rounding)
445 * r4 = dpp->weight_A ip = intermediate result
446 * r5 = dpp sp =
447 * r6 = dpp->delta lr =
448 * r7 = eptr pc =
449 *******************************************************************************
450 */
451
452term_minus_3:
453 ldr r3, [r1, #-4] @ load previous samples
454 ldr r8, [r1, #-8]
455
456term_minus_3_loop:
457 ldr ip, [r1], #4
458 movs r3, r3, asl #4
459 mov r11, #0x80000000
460 mov r2, ip
461 smlalne r11, r2, r4, r3
462 strne r2, [r1, #-4]
463 cmpne ip, #0
464 beq .L399
465 teq ip, r3 @ update weight based on signs
466 submi r4, r4, r6
467 addpl r4, r4, r6
468 cmp r4, #(1024 << 18) @ then clip weight to +/-1024
469 movgt r4, #(1024 << 18)
470 cmp r4, r10
471 movlt r4, r10
472
473.L399: movs ip, r8, asl #4 @ ip = previous left we use now
474 mov r8, r2 @ r8 = current left we use next time
475 ldr r2, [r1], #4
476 mov r11, #0x80000000
477 mov r3, r2
478 smlalne r11, r3, r0, ip
479 strne r3, [r1, #-4]
480 cmpne r2, #0
481 beq .L407
482 teq ip, r2
483 submi r0, r0, r6
484 addpl r0, r0, r6
485 cmp r0, #(1024 << 18)
486 movgt r0, #(1024 << 18)
487 cmp r0, r10
488 movlt r0, r10
489
490.L407: cmp r7, r1 @ loop back if more samples to do
491 bhi term_minus_3_loop
492
493 str r3, [r5, #8] @ else store previous samples & exit
494 str r8, [r5, #40]
495
496/*
497 * Before finally exiting we must store weights back for next time
498 */
499
500common_exit:
501 mov r0, r0, asr #18 @ restore weights to real magnitude
502 mov r4, r4, asr #18
503 strh r4, [r5, #4]
504 strh r0, [r5, #6]
505 ldmpc regs="r4-r8, r10-r11"
506
diff --git a/lib/rbcodec/codecs/libwavpack/bits.c b/lib/rbcodec/codecs/libwavpack/bits.c
new file mode 100644
index 0000000000..0f0e79c292
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/bits.c
@@ -0,0 +1,170 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// bits.c
10
11// This module provides utilities to support the BitStream structure which is
12// used to read and write all WavPack audio data streams. It also contains a
13// wrapper for the stream I/O functions and a set of functions dealing with
14// endian-ness, both for enhancing portability. Finally, a debug wrapper for
15// the malloc() system is provided.
16
17#include "wavpack.h"
18#include "system.h"
19
20#include <string.h>
21
22////////////////////////// Bitstream functions ////////////////////////////////
23
24// Open the specified BitStream and associate with the specified buffer.
25
26static void bs_read (Bitstream *bs);
27
28void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, uint32_t file_bytes)
29{
30 CLEAR (*bs);
31 bs->buf = buffer_start;
32 bs->end = buffer_end;
33
34 if (file) {
35 bs->ptr = bs->end - 1;
36 bs->file_bytes = file_bytes;
37 bs->file = file;
38 }
39 else
40 bs->ptr = bs->buf - 1;
41
42 bs->wrap = bs_read;
43}
44
45// This function is only called from the getbit() and getbits() macros when
46// the BitStream has been exhausted and more data is required. Sinve these
47// bistreams no longer access files, this function simple sets an error and
48// resets the buffer.
49
50static void bs_read (Bitstream *bs)
51{
52 if (bs->file && bs->file_bytes) {
53 uint32_t bytes_read, bytes_to_read = bs->end - bs->buf;
54
55 if (bytes_to_read > bs->file_bytes)
56 bytes_to_read = bs->file_bytes;
57
58 bytes_read = bs->file (bs->buf, bytes_to_read);
59
60 if (bytes_read) {
61 bs->end = bs->buf + bytes_read;
62 bs->file_bytes -= bytes_read;
63 }
64 else {
65 memset (bs->buf, -1, bs->end - bs->buf);
66 bs->error = 1;
67 }
68 }
69 else
70 bs->error = 1;
71
72 if (bs->error)
73 memset (bs->buf, -1, bs->end - bs->buf);
74
75 bs->ptr = bs->buf;
76}
77
78// Open the specified BitStream using the specified buffer pointers. It is
79// assumed that enough buffer space has been allocated for all data that will
80// be written, otherwise an error will be generated.
81
82static void bs_write (Bitstream *bs);
83
84void bs_open_write (Bitstream *bs, uchar *buffer_start, uchar *buffer_end)
85{
86 bs->error = bs->sr = bs->bc = 0;
87 bs->ptr = bs->buf = buffer_start;
88 bs->end = buffer_end;
89 bs->wrap = bs_write;
90}
91
92// This function is only called from the putbit() and putbits() macros when
93// the buffer is full, which is now flagged as an error.
94
95static void bs_write (Bitstream *bs)
96{
97 bs->ptr = bs->buf;
98 bs->error = 1;
99}
100
101// This function forces a flushing write of the specified BitStream, and
102// returns the total number of bytes written into the buffer.
103
104uint32_t bs_close_write (Bitstream *bs)
105{
106 uint32_t bytes_written;
107
108 if (bs->error)
109 return (uint32_t) -1;
110
111 while (bs->bc || ((bs->ptr - bs->buf) & 1)) putbit_1 (bs);
112 bytes_written = bs->ptr - bs->buf;
113 CLEAR (*bs);
114 return bytes_written;
115}
116
117/////////////////////// Endian Correction Routines ////////////////////////////
118
119void little_endian_to_native (void *data, char *format)
120{
121 uchar *cp = (uchar *) data;
122
123 while (*format) {
124 switch (*format) {
125 case 'L':
126 *(long *)cp = letoh32(*(long *)cp);
127 cp += 4;
128 break;
129
130 case 'S':
131 *(short *)cp = letoh16(*(short *)cp);
132 cp += 2;
133 break;
134
135 default:
136 if (*format >= '0' && *format <= '9')
137 cp += *format - '0';
138
139 break;
140 }
141
142 format++;
143 }
144}
145
146void native_to_little_endian (void *data, char *format)
147{
148 uchar *cp = (uchar *) data;
149
150 while (*format) {
151 switch (*format) {
152 case 'L':
153 *(long *)cp = htole32(*(long *)cp);
154 cp += 4;
155 break;
156
157 case 'S':
158 *(short *)cp = htole16(*(short *)cp);
159 cp += 2;
160 break;
161
162 default:
163 if (*format >= '0' && *format <= '9')
164 cp += *format - '0';
165 break;
166 }
167
168 format++;
169 }
170}
diff --git a/lib/rbcodec/codecs/libwavpack/coldfire.S b/lib/rbcodec/codecs/libwavpack/coldfire.S
new file mode 100644
index 0000000000..884a0ac90f
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/coldfire.S
@@ -0,0 +1,537 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by David Bryant
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/* This is an assembly optimized version of the following WavPack function:
23 *
24 * void decorr_stereo_pass_cont_mcf5249 (struct decorr_pass *dpp,
25 * long *buffer, long sample_count);
26 *
27 * It performs a single pass of stereo decorrelation on the provided buffer.
28 * Note that this version of the function requires that the 8 previous stereo
29 * samples are visible and correct. In other words, it ignores the "samples_*"
30 * fields in the decorr_pass structure and gets the history data directly
31 * from the buffer. It does, however, return the appropriate history samples
32 * to the decorr_pass structure before returning.
33 *
34 * This is written to work on a MCF5249 processor, or any processor based on
35 * the ColdFire V2 core with an EMAC unit. The EMAC is perfectly suited for
36 * the "apply_weight" function of WavPack decorrelation because it provides
37 * the requires 40-bit product. The fractional rounding mode of the EMAC is not
38 * configurable and uses "round to even" while WavPack uses "round to larger",
39 * so the rounding has to be done manually.
40 */
41
42 .text
43 .align 2
44 .global decorr_stereo_pass_cont_mcf5249
45
46decorr_stereo_pass_cont_mcf5249:
47
48 lea (-44, %sp), %sp
49 movem.l %d2-%d7/%a2-%a6, (%sp)
50 move.l 44+4(%sp), %a2 | a2 = dpp->
51 move.l 44+8(%sp), %a1 | a1 = bptr
52 move.w 2(%a2), %a3 | a3 = dpp->delta
53 move.w 4(%a2), %d3 | d3 = dpp->weight_A (sign extended)
54 ext.l %d3
55 move.w 6(%a2), %d4 | d4 = dpp->weight_B (sign extended)
56 ext.l %d4
57 move.l 44+12(%sp), %d0 | d0 = sample_count
58 jbeq return_only | if zero, nothing to do
59
60 lsl.l #3, %d0 | d5 = bptr + (sample_count * 8)
61 move.l %d0, %d5
62 add.l %a1, %d5
63
64 moveq.l #17, %d0 | left shift weights & delta 17 places
65 asl.l %d0, %d3
66 asl.l %d0, %d4
67 move.l %a3, %d1
68 asl.l %d0, %d1
69 move.l %d1, %a3
70
71 moveq.l #0x20, %d6
72 move.l %d6, %macsr | set fractional mode for MAC
73 move.l #0x800000, %accext01 | acc1 = 0x00 0000 80 (for rounding)
74
75 move.l #1024<<17, %d6 | d6 & d7 are weight clipping limits
76 move.l #-1024<<17, %d7 | (only used by negative terms)
77
78 move.w (%a2), %d0 | d0 = term
79 ext.l %d0
80 cmp.l #17, %d0
81 jbeq term_17 | term = 17
82 cmp.l #18, %d0
83 jbeq term_18 | term = 18
84 addq.l #1, %d0
85 jbeq term_minus_1 | term = -1
86 addq.l #1, %d0
87 jbeq term_minus_2 | term = -2
88 addq.l #1, %d0
89 jbeq term_minus_3 | term = -3
90 jbra term_default | default term = 1 - 8
91
92|------------------------------------------------------------------------------
93| Loop to handle term = 17 condition
94|
95| a0 = d0 = (2 * bptr [-1]) - bptr [-2]
96| a1 = bptr d1 = initial bptr [0]
97| a2 = dpp-> d2 = updated bptr [0]
98| a3 = dpp->delta << 17 d3 = dpp->weight_A << 17
99| a4 = d4 = dpp->weight_B << 17
100| a5 = d5 = eptr
101| macsr = 0x20 acc1 = 0x00 0000 80
102|------------------------------------------------------------------------------
103
104term_17:
105 move.l -8(%a1), %d0 | d0 = 2 * bptr [-1] - bptr [-2]
106 add.l %d0, %d0
107 sub.l -16(%a1), %d0
108 beq .L251 | if zero, skip calculation
109 move.l %acc1, %acc0
110 asl.l #4, %d0 | acc0 = acc1 + (d0 << 4) * weight_A
111 mac.l %d0, %d3, %acc0
112 move.l (%a1), %d1
113 beq .L255
114 eor.l %d1, %d0 | else compare signs
115 bge .L256 | if same, add delta to weight
116 sub.l %a3, %d3 | else subtract delta from weight
117 sub.l %a3, %d3 | subtract again instead of branch
118.L256: add.l %a3, %d3 | add delta to weight
119
120.L255: move.l %acc0, %d2 | d2 = rounded product
121 add.l %d1, %d2 | update bptr [0] and store
122 move.l %d2, (%a1)+
123
124.L253: move.l -8(%a1), %d0 | d0 = 2 * bptr [-1] - bptr [-2]
125 add.l %d0, %d0
126 sub.l -16(%a1), %d0
127 beq .L257 | if zero, skip calculations
128 move.l %acc1, %acc0
129 asl.l #4, %d0 | acc0 = acc1 + (d0 << 4) * weight_B
130 mac.l %d0, %d4, %acc0
131 move.l (%a1), %d1
132 beq .L254
133 eor.l %d1, %d0 | else compare signs
134 bge .L259 | if same, add delta to weight
135 sub.l %a3, %d4 | else subtract delta from weight
136 sub.l %a3, %d4 | subtract again instead of branch
137.L259: add.l %a3, %d4 | add delta to weight
138
139.L254: move.l %acc0, %d2 | d2 = rounded product
140 add.l %d1, %d2 | update bptr [0] and store
141 move.l %d2, (%a1)+
142
143.L252: cmp.l %a1, %d5 | loop if bptr < eptr
144 jbhi term_17
145 bra term_17_18_finish | exit through common path
146
147.L251: addq.l #4, %a1 | update point and jump back into loop
148 bra .L253
149
150.L257: addq.l #4, %a1 | update point and jump back into loop
151 bra .L252
152
153|------------------------------------------------------------------------------
154| Loop to handle term = 18 condition
155|
156| a0 = d0 = ((3 * bptr [-1]) - bptr [-2]) >> 1
157| a1 = bptr d1 = initial bptr [0]
158| a2 = dpp-> d2 = updated bptr [0]
159| a3 = dpp->delta << 17 d3 = dpp->weight_A << 17
160| a4 = d4 = dpp->weight_B << 17
161| a5 = d5 = eptr
162| macsr = 0x20 acc1 = 0x00 0000 80
163|------------------------------------------------------------------------------
164
165term_18:
166 move.l -8(%a1), %a0 | d0 = (3 * bptr [-1] - bptr [-2]) >> 1
167 lea (%a0,%a0.l*2), %a0
168 move.l %a0, %d0
169 sub.l -16(%a1), %d0
170 asr.l #1, %d0
171 beq .L260
172 move.l %acc1, %acc0
173 asl.l #4, %d0 | acc0 = acc1 + (d0 << 4) * weight_A
174 mac.l %d0, %d3, %acc0
175 move.l (%a1), %d1
176 beq .L266
177 eor.l %d1, %d0 | else compare signs
178 bge .L267 | if same, add delta to weight
179 sub.l %a3, %d3 | else subtract delta from weight
180 sub.l %a3, %d3 | subtract again instead of branch
181.L267: add.l %a3, %d3 | add delta to weight
182
183.L266: move.l %acc0, %d2 | d2 = rounded product
184 add.l %d1, %d2 | add applied weight to bptr [0], store
185 move.l %d2, (%a1)+
186
187.L268: move.l -8(%a1), %a0 | d0 = (3 * bptr [-1] - bptr [-2]) >> 1
188 lea (%a0,%a0.l*2), %a0
189 move.l %a0, %d0
190 sub.l -16(%a1), %d0
191 asr.l #1, %d0
192 beq .L261
193 move.l %acc1, %acc0
194 asl.l #4, %d0 | acc0 = acc1 + (d0 << 4) * weight_B
195 mac.l %d0, %d4, %acc0
196 move.l (%a1), %d1
197 beq .L265
198 eor.l %d1, %d0 | else compare signs
199 bge .L270 | if same, add delta to weight
200 sub.l %a3, %d4 | else subtract delta from weight
201 sub.l %a3, %d4 | subtract again instead of branch
202.L270: add.l %a3, %d4 | add delta to weight
203
204.L265: move.l %acc0, %d2 | d2 = rounded product
205 add.l %d1, %d2 | add applied weight to bptr [0], store
206 move.l %d2, (%a1)+
207
208.L269: cmp.l %a1, %d5 | loop if bptr < eptr
209 jbhi term_18
210 bra term_17_18_finish | exit through common path
211
212.L260: addq.l #4, %a1 | bump pointer and jump back into loop
213 bra .L268
214
215.L261: addq.l #4, %a1 | bump pointer and jump back into loop
216 bra .L269
217
218term_17_18_finish:
219 move.l -4(%a1), 40(%a2) | restore dpp->samples_A [0-1], B [0-1]
220 move.l -8(%a1), 8(%a2)
221 move.l -12(%a1), 44(%a2)
222 move.l -16(%a1), 12(%a2)
223 jbra finish_up
224
225|------------------------------------------------------------------------------
226| Loop to handle default terms (i.e. 1 - 8)
227|
228| a0 = tptr d0 = tptr [0]
229| a1 = bptr d1 = initial bptr [0]
230| a2 = dpp-> d2 = updated bptr [0]
231| a3 = dpp->delta << 17 d3 = dpp->weight_A << 17
232| a4 = d4 = dpp->weight_B << 17
233| a5 = d5 = eptr
234| macsr = 0x20 acc1 = 0x00 0000 80
235|------------------------------------------------------------------------------
236
237term_default:
238 move.w (%a2), %d0 | a0 = a1 - (dpp->term * 8)
239 ext.l %d0
240 lsl.l #3, %d0
241 move.l %a1, %a0
242 sub.l %d0, %a0
243
244term_default_loop:
245 move.l (%a0)+, %d0 | d0 = tptr [0], skip ahead if zero
246 beq .L271
247 move.l %acc1, %acc0
248 asl.l #4, %d0 | acc0 = acc1 + (d0 << 4) * weight_A
249 mac.l %d0, %d3, %acc0
250 move.l (%a1), %d1
251 beq .L277
252 eor.l %d1, %d0 | else compare signs
253 bge .L278 | if same, add delta to weight
254 sub.l %a3, %d3 | else subtract delta from weight
255 sub.l %a3, %d3 | subtract again instead of branch
256.L278: add.l %a3, %d3 | add delta to weight
257
258.L277: move.l %acc0, %d2 | d2 = rounded product
259 add.l %d1, %d2 | add applied weight to bptr [0], store
260 move.l %d2, (%a1)+
261
262.L275: move.l (%a0)+, %d0 | d0 = tptr [0], skip ahead if zero
263 beq .L272
264 move.l %acc1, %acc0
265 asl.l #4, %d0 | acc0 = acc1 + (d0 << 4) * weight_B
266 mac.l %d0, %d4, %acc0
267 move.l (%a1), %d1
268 beq .L276
269 eor.l %d1, %d0 | else compare signs
270 bge .L281 | if same, add delta to weight
271 sub.l %a3, %d4 | else subtract delta from weight
272 sub.l %a3, %d4 | subtract again instead of branch
273.L281: add.l %a3, %d4 | add delta to weight
274
275.L276: move.l %acc0, %d2 | d2 = rounded product
276 add.l %d1, %d2 | add applied weight to bptr [0], store
277 move.l %d2, (%a1)+
278
279.L274: cmp.l %a1, %d5 | loop back if bptr < eptr
280 jbhi term_default_loop
281 move.w (%a2), %d0 | d0 = term - 1
282 moveq.l #8, %d1 | d1 = loop counter
283
284.L323: subq.l #1, %d0 | back up & mask index
285 and.l #7, %d0
286 move.l -(%a1), 40(%a2,%d0.l*4) | store dpp->samples_B [d0]
287 move.l -(%a1), 8(%a2,%d0.l*4) | store dpp->samples_A [d0]
288 subq.l #1, %d1 | loop on count
289 jbne .L323
290 jbra finish_up
291
292.L271: addq.l #4, %a1 | bump pointer and jump back into loop
293 bra .L275
294
295.L272: addq.l #4, %a1 | bump pointer and jump back into loop
296 bra .L274
297
298
299|------------------------------------------------------------------------------
300| Loop to handle term = -1 condition
301|
302| a0 = d0 = decorrelation sample
303| a1 = bptr d1 = initial bptr [0]
304| a2 = dpp-> d2 = updated bptr [0]
305| a3 = dpp->delta << 17 d3 = dpp->weight_A << 17
306| a4 = d4 = dpp->weight_B << 17
307| a5 = d5 = eptr
308| a6 = d6 = 1024 << 17
309| a7 = d7 = -1024 << 17
310| macsr = 0x20 acc1 = 0x00 0000 80
311|------------------------------------------------------------------------------
312
313term_minus_1:
314 move.l -4(%a1), %d0 | d0 = bptr [-1]
315 beq .L402
316 move.l %acc1, %acc0
317 asl.l #4, %d0 | acc0 = acc1 + ((d0 << 4) * weight_A)
318 mac.l %d0, %d3, %acc0
319 move.l (%a1), %d1
320 beq .L405
321 eor.l %d1, %d0 | else compare signs
322 bge .L404 | if same, add delta to weight
323 sub.l %a3, %d3 | else subtract delta from weight
324 cmp.l %d7, %d3 | check for negative clip limit
325 bge .L405
326 move.l %d7, %d3
327 bra .L405
328
329.L404: add.l %a3, %d3 | add delta to weight
330 cmp.l %d6, %d3 | check for positive clip limit
331 ble .L405
332 move.l %d6, %d3
333
334.L405: move.l %acc0, %d0 | d2 = rounded product
335 add.l %d1, %d0 | add applied weight to bptr [0], store
336 move.l %d0, (%a1)+
337 beq .L401
338
339.L410: move.l %acc1, %acc0
340 asl.l #4, %d0 | acc0 = acc1 + ((d0 << 4) * weight_B)
341 mac.l %d0, %d4, %acc0
342 move.l (%a1), %d1
343 beq .L403
344 eor.l %d1, %d0 | else compare signs
345 bge .L407 | if same, add delta to weight
346 sub.l %a3, %d4 | else subtract delta from weight
347 cmp.l %d7, %d4 | check for negative clip limit
348 bge .L403
349 move.l %d7, %d4
350 bra .L403
351
352.L407: add.l %a3, %d4 | add delta to weight
353 cmp.l %d6, %d4 | check for positive clip limit
354 ble .L403
355 move.l %d6, %d4
356
357.L403: move.l %acc0, %d2 | d2 = rounded product
358 add.l %d1, %d2 | add applied weight to bptr [1], store
359 move.l %d2, (%a1)+
360
361.L411: cmp.l %a1, %d5 | loop back if bptr < eptr
362 jbhi term_minus_1
363 move.l -4(%a1), 8(%a2) | dpp->samples_A [0] = bptr [-1]
364 jbra finish_up
365
366.L402: move.l (%a1)+, %d0
367 bne .L410
368
369.L401: addq.l #4, %a1
370 bra .L411
371
372
373|------------------------------------------------------------------------------
374| Loop to handle term = -2 condition
375|
376| a0 = d0 = decorrelation sample
377| a1 = bptr d1 = initial bptr [0]
378| a2 = dpp-> d2 = updated bptr [0]
379| a3 = dpp->delta << 17 d3 = dpp->weight_A << 17
380| a4 = d4 = dpp->weight_B << 17
381| a5 = d5 = eptr
382| a6 = d6 = 1024 << 17
383| a7 = d7 = -1024 << 17
384| macsr = 0x20 acc1 = 0x00 0000 80
385|------------------------------------------------------------------------------
386
387term_minus_2:
388 move.l -8(%a1), %d0 | d0 = bptr [-2]
389 beq .L511
390 move.l %acc1, %acc0
391 asl.l #4, %d0 | acc0 = acc1 + ((d0 << 4) * weight_B)
392 mac.l %d0, %d4, %acc0
393 move.l 4(%a1), %d1
394 beq .L505
395 eor.l %d1, %d0 | else compare signs
396 bge .L504 | if same, add delta to weight
397 sub.l %a3, %d4 | else subtract delta from weight
398 cmp.l %d7, %d4 | ckeck for negative clip limit
399 bge .L505
400 move.l %d7, %d4
401 bra .L505
402
403.L504: add.l %a3, %d4 | add delta to weight
404 cmp.l %d6, %d4 | check for positive clip limit
405 ble .L505
406 move.l %d6, %d4
407
408.L505: move.l %acc0, %d0 | d2 = rounded product
409 add.l %d1, %d0 | add applied weight to bptr [0], store
410 move.l %d0, 4(%a1)
411 beq .L512
412
413.L510: move.l %acc1, %acc0
414 asl.l #4, %d0 | acc0 = acc1 + ((d0 << 4) * weight_A)
415 mac.l %d0, %d3, %acc0
416 move.l (%a1), %d1
417 beq .L503
418 eor.l %d1, %d0 | else compare signs
419 bge .L507 | if same, add delta to weight
420 sub.l %a3, %d3 | else subtract delta from weight
421 cmp.l %d7, %d3 | check for negative clip limit
422 bge .L503
423 move.l %d7, %d3
424 bra .L503
425
426.L507: add.l %a3, %d3 | add delta to weight
427 cmp.l %d6, %d3 | check for negative clip limit
428 ble .L503
429 move.l %d6, %d3
430
431.L503: move.l %acc0, %d2 | d2 = rounded product
432 add.l %d1, %d2 | add applied weight to bptr [1], store
433 move.l %d2, (%a1)
434
435.L512: addq.l #8, %a1
436 cmp.l %a1, %d5 | loop if bptr < eptr
437 jbhi term_minus_2
438 move.l -8(%a1), 40(%a2) | dpp->samples_B [0] = bptr [-4]
439 jbra finish_up
440
441.L511: move.l 4(%a1), %d0
442 beq .L512
443 bra .L510
444
445
446|------------------------------------------------------------------------------
447| Loop to handle term = -3 condition
448|
449| a0 = d0 = decorrelation sample
450| a1 = bptr d1 = initial bptr [0]
451| a2 = dpp-> d2 = updated bptr [0]
452| a3 = dpp->delta << 17 d3 = dpp->weight_A << 17
453| a4 = d4 = dpp->weight_B << 17
454| a5 = d5 = eptr
455| a6 = d6 = 1024 << 17
456| a7 = d7 = -1024 << 17
457| macsr = 0x20 acc1 = 0x00 0000 80
458|------------------------------------------------------------------------------
459
460term_minus_3:
461 move.l -4(%a1), %d0 | d0 = bptr [-1]
462 beq .L301
463 move.l %acc1, %acc0
464 asl.l #4, %d0 | acc0 = acc1 + ((d0 << 4) * weight_A)
465 mac.l %d0, %d3, %acc0
466 move.l (%a1), %d1
467 beq .L320
468 eor.l %d1, %d0 | else compare signs
469 bge .L319 | if same, add delta to weight
470 sub.l %a3, %d3 | else subtract delta from weight
471 cmp.l %d7, %d3 | check for negative clip limit
472 bge .L320
473 move.l %d7, %d3
474 bra .L320
475
476.L319: add.l %a3, %d3 | add delta to weight
477 cmp.l %d6, %d3 | check for positive clip limit
478 ble .L320
479 move.l %d6, %d3
480
481.L320: move.l %acc0, %d2 | d2 = rounded product
482 add.l %d1, %d2 | add applied weight to bptr [0], store
483 move.l %d2, (%a1)+
484
485.L330: move.l -12(%a1), %d0 | d0 = bptr [-2]
486 beq .L302
487 move.l %acc1, %acc0
488 asl.l #4, %d0 | acc0 = acc1 + ((d0 << 4) * weight_B)
489 mac.l %d0, %d4, %acc0
490 move.l (%a1), %d1
491 beq .L318
492 eor.l %d1, %d0 | else compare signs
493 bge .L322 | if same, add delta to weight
494 sub.l %a3, %d4 | else subtract delta from weight
495 cmp.l %d7, %d4 | check for negative clip limit
496 bge .L318
497 move.l %d7, %d4
498 bra .L318
499
500.L322: add.l %a3, %d4 | add delta to weight
501 cmp.l %d6, %d4 | check for positive clip limit
502 ble .L318
503 move.l %d6, %d4
504
505.L318: move.l %acc0, %d2 | d2 = rounded product
506 add.l %d1, %d2 | add applied weight to bptr [1], store
507 move.l %d2, (%a1)+
508
509.L331: cmp.l %a1, %d5 | bptr, eptr
510 jbhi term_minus_3
511 move.l -4(%a1), 8(%a2) | dpp->samples_A [0] = bptr [-1]
512 move.l -8(%a1), 40(%a2) | dpp->samples_B [0] = bptr [-2]
513 jbra finish_up
514
515.L301: addq.l #4, %a1
516 bra .L330
517
518.L302: addq.l #4, %a1
519 bra .L331
520
521| finish and return
522
523finish_up:
524 moveq.l #17, %d0
525 asr.l %d0, %d3
526 asr.l %d0, %d4
527 move.w %d3, 4(%a2) | weight_A, dpp->weight_A
528 move.w %d4, 6(%a2) | weight_B, dpp->weight_B
529
530 clr.l %d0 | clear up EMAC
531 move.l %d0, %acc0
532 move.l %d0, %acc1
533
534return_only:
535 movem.l (%sp), %d2-%d7/%a2-%a6
536 lea (44,%sp), %sp
537 rts
diff --git a/lib/rbcodec/codecs/libwavpack/float.c b/lib/rbcodec/codecs/libwavpack/float.c
new file mode 100644
index 0000000000..6e5c4e4f61
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/float.c
@@ -0,0 +1,47 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// float.c
10
11#include "wavpack.h"
12
13int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
14{
15 int bytecnt = wpmd->byte_length;
16 char *byteptr = wpmd->data;
17
18 if (bytecnt != 4)
19 return FALSE;
20
21 wps->float_flags = *byteptr++;
22 wps->float_shift = *byteptr++;
23 wps->float_max_exp = *byteptr++;
24 wps->float_norm_exp = *byteptr;
25 return TRUE;
26}
27
28/* This function converts WavPack floating point data into standard Rockbox
29 * 28-bit integers. It is assumed that clipping will be taken care of later.
30 */
31
32void float_values (WavpackStream *wps, int32_t *values, int32_t num_values)
33{
34 int shift = wps->float_max_exp - wps->float_norm_exp + wps->float_shift + 5;
35
36 if (shift > 32)
37 shift = 32;
38 else if (shift < -32)
39 shift = -32;
40
41 if (shift > 0)
42 while (num_values--)
43 *values++ <<= shift;
44 else if (shift < 0)
45 while (num_values--)
46 *values++ >>= -shift;
47}
diff --git a/lib/rbcodec/codecs/libwavpack/libwavpack.make b/lib/rbcodec/codecs/libwavpack/libwavpack.make
new file mode 100644
index 0000000000..27a2d214a1
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/libwavpack.make
@@ -0,0 +1,18 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10# libwavpack
11WAVPACKLIB := $(CODECDIR)/libwavpack.a
12WAVPACKLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libwavpack/SOURCES)
13WAVPACKLIB_OBJ := $(call c2obj, $(WAVPACKLIB_SRC))
14OTHER_SRC += $(WAVPACKLIB_SRC)
15
16$(WAVPACKLIB): $(WAVPACKLIB_OBJ)
17 $(SILENT)$(shell rm -f $@)
18 $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
diff --git a/lib/rbcodec/codecs/libwavpack/make.bat b/lib/rbcodec/codecs/libwavpack/make.bat
new file mode 100644
index 0000000000..0ca72d7e55
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/make.bat
@@ -0,0 +1 @@
cl /O1 /DWIN32 wvfilter.c wputils.c unpack.c float.c metadata.c words.c bits.c
diff --git a/lib/rbcodec/codecs/libwavpack/metadata.c b/lib/rbcodec/codecs/libwavpack/metadata.c
new file mode 100644
index 0000000000..4dce10100f
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/metadata.c
@@ -0,0 +1,171 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2003 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// metadata.c
10
11// This module handles the metadata structure introduced in WavPack 4.0
12
13#include "wavpack.h"
14
15#include <string.h>
16
17int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd)
18{
19 uint32_t bytes_to_read;
20 uchar tchar;
21
22 if (wpc->stream.block_bytes_left < 2 || !wpc->infile (&wpmd->id, 1) || !wpc->infile (&tchar, 1))
23 return FALSE;
24
25 wpmd->byte_length = tchar << 1;
26 wpc->stream.block_bytes_left -= 2;
27
28 if (wpmd->id & ID_LARGE) {
29 wpmd->id &= ~ID_LARGE;
30
31 if (wpc->stream.block_bytes_left < 2 || !wpc->infile (&tchar, 1))
32 return FALSE;
33
34 wpmd->byte_length += (int32_t) tchar << 9;
35
36 if (!wpc->infile (&tchar, 1))
37 return FALSE;
38
39 wpmd->byte_length += (int32_t) tchar << 17;
40 wpc->stream.block_bytes_left -= 2;
41 }
42
43 if ((wpc->stream.block_bytes_left -= wpmd->byte_length) < 0)
44 return FALSE;
45
46 if (wpmd->id & ID_ODD_SIZE) {
47 wpmd->id &= ~ID_ODD_SIZE;
48 wpmd->byte_length--;
49 }
50
51 if (!wpmd->byte_length || wpmd->id == ID_WV_BITSTREAM) {
52 wpmd->data = NULL;
53 return TRUE;
54 }
55
56 bytes_to_read = wpmd->byte_length + (wpmd->byte_length & 1);
57
58 if (bytes_to_read > sizeof (wpc->read_buffer)) {
59 wpmd->data = NULL;
60
61 while (bytes_to_read > sizeof (wpc->read_buffer))
62 if (wpc->infile (wpc->read_buffer, sizeof (wpc->read_buffer)) == sizeof (wpc->read_buffer))
63 bytes_to_read -= sizeof (wpc->read_buffer);
64 else
65 return FALSE;
66 }
67 else
68 wpmd->data = wpc->read_buffer;
69
70 if (bytes_to_read && wpc->infile (wpc->read_buffer, bytes_to_read) != (int32_t) bytes_to_read) {
71 wpmd->data = NULL;
72 return FALSE;
73 }
74
75 return TRUE;
76}
77
78int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd)
79{
80 WavpackStream *wps = &wpc->stream;
81
82 switch (wpmd->id) {
83 case ID_DUMMY:
84 return TRUE;
85
86 case ID_DECORR_TERMS:
87 return read_decorr_terms (wps, wpmd);
88
89 case ID_DECORR_WEIGHTS:
90 return read_decorr_weights (wps, wpmd);
91
92 case ID_DECORR_SAMPLES:
93 return read_decorr_samples (wps, wpmd);
94
95 case ID_ENTROPY_VARS:
96 return read_entropy_vars (wps, wpmd);
97
98 case ID_HYBRID_PROFILE:
99 return read_hybrid_profile (wps, wpmd);
100
101 case ID_FLOAT_INFO:
102 return read_float_info (wps, wpmd);
103
104 case ID_INT32_INFO:
105 return read_int32_info (wps, wpmd);
106
107 case ID_CHANNEL_INFO:
108 return read_channel_info (wpc, wpmd);
109
110 case ID_SAMPLE_RATE:
111 return read_sample_rate (wpc, wpmd);
112
113 case ID_CONFIG_BLOCK:
114 return read_config_info (wpc, wpmd);
115
116 case ID_WV_BITSTREAM:
117 return init_wv_bitstream (wpc, wpmd);
118
119 case ID_SHAPING_WEIGHTS:
120 case ID_WVC_BITSTREAM:
121 case ID_WVX_BITSTREAM:
122 return TRUE;
123
124 default:
125 return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE;
126 }
127}
128
129int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end)
130{
131 uint32_t mdsize = wpmd->byte_length + (wpmd->byte_length & 1);
132 WavpackHeader *wphdr = (WavpackHeader *) buffer_start;
133
134 if (wpmd->byte_length & 1)
135 ((char *) wpmd->data) [wpmd->byte_length] = 0;
136
137 mdsize += (wpmd->byte_length > 510) ? 4 : 2;
138 buffer_start += wphdr->ckSize + 8;
139
140 if (buffer_start + mdsize >= buffer_end)
141 return FALSE;
142
143 buffer_start [0] = wpmd->id | (wpmd->byte_length & 1 ? ID_ODD_SIZE : 0);
144 buffer_start [1] = (wpmd->byte_length + 1) >> 1;
145
146 if (wpmd->byte_length > 510) {
147 buffer_start [0] |= ID_LARGE;
148 buffer_start [2] = (wpmd->byte_length + 1) >> 9;
149 buffer_start [3] = (wpmd->byte_length + 1) >> 17;
150 }
151
152 if (wpmd->data && wpmd->byte_length) {
153 if (wpmd->byte_length > 510) {
154 buffer_start [0] |= ID_LARGE;
155 buffer_start [2] = (wpmd->byte_length + 1) >> 9;
156 buffer_start [3] = (wpmd->byte_length + 1) >> 17;
157 memcpy (buffer_start + 4, wpmd->data, mdsize - 4);
158 }
159 else
160 memcpy (buffer_start + 2, wpmd->data, mdsize - 2);
161 }
162
163 wphdr->ckSize += mdsize;
164 return TRUE;
165}
166
167void free_metadata (WavpackMetadata *wpmd)
168{
169 wpmd->data = NULL;
170}
171
diff --git a/lib/rbcodec/codecs/libwavpack/pack.c b/lib/rbcodec/codecs/libwavpack/pack.c
new file mode 100644
index 0000000000..a46d05fe14
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/pack.c
@@ -0,0 +1,470 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2005 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// pack.c
10
11// This module actually handles the compression of the audio data, except for
12// the entropy coding which is handled by the words? modules. For efficiency,
13// the conversion is isolated to tight loops that handle an entire buffer.
14
15#include "wavpack.h"
16
17#include <string.h>
18
19// This flag provides faster encoding speed at the expense of more code. The
20// improvement applies to 16-bit stereo lossless only.
21
22//////////////////////////////// local tables ///////////////////////////////
23
24// These two tables specify the characteristics of the decorrelation filters.
25// Each term represents one layer of the sequential filter, where positive
26// values indicate the relative sample involved from the same channel (1=prev),
27// 17 & 18 are special functions using the previous 2 samples, and negative
28// values indicate cross channel decorrelation (in stereo only).
29
30static const signed char default_terms [] = { 18,18,2,3,-2,0 };
31static const signed char high_terms [] = { 18,18,2,3,-2,18,2,4,7,5,3,6,0 };
32static const signed char fast_terms [] = { 17,17,0 };
33
34///////////////////////////// executable code ////////////////////////////////
35
36// This function initializes everything required to pack WavPack bitstreams
37// and must be called BEFORE any other function in this module.
38
39void pack_init (WavpackContext *wpc)
40{
41 WavpackStream *wps = &wpc->stream;
42 uint32_t flags = wps->wphdr.flags;
43 struct decorr_pass *dpp;
44 const signed char *term_string;
45 int ti;
46
47 wps->sample_index = 0;
48 CLEAR (wps->decorr_passes);
49
50 if (wpc->config.flags & CONFIG_HIGH_FLAG)
51 term_string = high_terms;
52 else if (wpc->config.flags & CONFIG_FAST_FLAG)
53 term_string = fast_terms;
54 else
55 term_string = default_terms;
56
57 for (dpp = wps->decorr_passes, ti = 0; term_string [ti]; ti++)
58 if (term_string [ti] >= 0 || (flags & CROSS_DECORR)) {
59 dpp->term = term_string [ti];
60 dpp++->delta = 2;
61 }
62 else if (!(flags & MONO_FLAG)) {
63 dpp->term = -3;
64 dpp++->delta = 2;
65 }
66
67 wps->num_terms = dpp - wps->decorr_passes;
68 init_words (wps);
69}
70
71// Allocate room for and copy the decorrelation terms from the decorr_passes
72// array into the specified metadata structure. Both the actual term id and
73// the delta are packed into single characters.
74
75static void write_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
76{
77 int tcount = wps->num_terms;
78 struct decorr_pass *dpp;
79 char *byteptr;
80
81 byteptr = wpmd->data = wpmd->temp_data;
82 wpmd->id = ID_DECORR_TERMS;
83
84 for (dpp = wps->decorr_passes; tcount--; ++dpp)
85 *byteptr++ = ((dpp->term + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0);
86
87 wpmd->byte_length = byteptr - (char *) wpmd->data;
88}
89
90// Allocate room for and copy the decorrelation term weights from the
91// decorr_passes array into the specified metadata structure. The weights
92// range +/-1024, but are rounded and truncated to fit in signed chars for
93// metadata storage. Weights are separate for the two channels
94
95static void write_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
96{
97 int tcount = wps->num_terms;
98 struct decorr_pass *dpp;
99 signed char *byteptr;
100
101 byteptr = wpmd->data = wpmd->temp_data;
102 wpmd->id = ID_DECORR_WEIGHTS;
103
104 for (dpp = wps->decorr_passes; tcount--; ++dpp) {
105 dpp->weight_A = restore_weight (*byteptr++ = store_weight (dpp->weight_A));
106
107 if (!(wps->wphdr.flags & MONO_FLAG))
108 dpp->weight_B = restore_weight (*byteptr++ = store_weight (dpp->weight_B));
109 }
110
111 wpmd->byte_length = byteptr - (signed char *) wpmd->data;
112}
113
114// Allocate room for and copy the decorrelation samples from the decorr_passes
115// array into the specified metadata structure. The samples are signed 32-bit
116// values, but are converted to signed log2 values for storage in metadata.
117// Values are stored for both channels and are specified from the first term
118// with unspecified samples set to zero. The number of samples stored varies
119// with the actual term value, so those must obviously be specified before
120// these in the metadata list. Any number of terms can have their samples
121// specified from no terms to all the terms, however I have found that
122// sending more than the first term's samples is a waste. The "wcount"
123// variable can be set to the number of terms to have their samples stored.
124
125static void write_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
126{
127 int tcount = wps->num_terms, wcount = 1, temp;
128 struct decorr_pass *dpp;
129 uchar *byteptr;
130
131 byteptr = wpmd->data = wpmd->temp_data;
132 wpmd->id = ID_DECORR_SAMPLES;
133
134 for (dpp = wps->decorr_passes; tcount--; ++dpp)
135 if (wcount) {
136 if (dpp->term > MAX_TERM) {
137 dpp->samples_A [0] = exp2s (temp = log2s (dpp->samples_A [0]));
138 *byteptr++ = temp;
139 *byteptr++ = temp >> 8;
140 dpp->samples_A [1] = exp2s (temp = log2s (dpp->samples_A [1]));
141 *byteptr++ = temp;
142 *byteptr++ = temp >> 8;
143
144 if (!(wps->wphdr.flags & MONO_FLAG)) {
145 dpp->samples_B [0] = exp2s (temp = log2s (dpp->samples_B [0]));
146 *byteptr++ = temp;
147 *byteptr++ = temp >> 8;
148 dpp->samples_B [1] = exp2s (temp = log2s (dpp->samples_B [1]));
149 *byteptr++ = temp;
150 *byteptr++ = temp >> 8;
151 }
152 }
153 else if (dpp->term < 0) {
154 dpp->samples_A [0] = exp2s (temp = log2s (dpp->samples_A [0]));
155 *byteptr++ = temp;
156 *byteptr++ = temp >> 8;
157 dpp->samples_B [0] = exp2s (temp = log2s (dpp->samples_B [0]));
158 *byteptr++ = temp;
159 *byteptr++ = temp >> 8;
160 }
161 else {
162 int m = 0, cnt = dpp->term;
163
164 while (cnt--) {
165 dpp->samples_A [m] = exp2s (temp = log2s (dpp->samples_A [m]));
166 *byteptr++ = temp;
167 *byteptr++ = temp >> 8;
168
169 if (!(wps->wphdr.flags & MONO_FLAG)) {
170 dpp->samples_B [m] = exp2s (temp = log2s (dpp->samples_B [m]));
171 *byteptr++ = temp;
172 *byteptr++ = temp >> 8;
173 }
174
175 m++;
176 }
177 }
178
179 wcount--;
180 }
181 else {
182 CLEAR (dpp->samples_A);
183 CLEAR (dpp->samples_B);
184 }
185
186 wpmd->byte_length = byteptr - (uchar *) wpmd->data;
187}
188
189// Allocate room for and copy the configuration information into the specified
190// metadata structure. Currently, we just store the upper 3 bytes of
191// config.flags and only in the first block of audio data. Note that this is
192// for informational purposes not required for playback or decoding (like
193// whether high or fast mode was specified).
194
195static void write_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
196{
197 char *byteptr;
198
199 byteptr = wpmd->data = wpmd->temp_data;
200 wpmd->id = ID_CONFIG_BLOCK;
201 *byteptr++ = (char) (wpc->config.flags >> 8);
202 *byteptr++ = (char) (wpc->config.flags >> 16);
203 *byteptr++ = (char) (wpc->config.flags >> 24);
204 wpmd->byte_length = byteptr - (char *) wpmd->data;
205}
206
207// Pack an entire block of samples (either mono or stereo) into a completed
208// WavPack block. It is assumed that there is sufficient space for the
209// completed block at "wps->blockbuff" and that "wps->blockend" points to the
210// end of the available space. A return value of FALSE indicates an error.
211// Any unsent metadata is transmitted first, then required metadata for this
212// block is sent, and finally the compressed integer data is sent. If a "wpx"
213// stream is required for floating point data or large integer data, then this
214// must be handled outside this function. To find out how much data was written
215// the caller must look at the ckSize field of the written WavpackHeader, NOT
216// the one in the WavpackStream.
217
218int pack_start_block (WavpackContext *wpc)
219{
220 WavpackStream *wps = &wpc->stream;
221 WavpackMetadata wpmd;
222
223 memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader));
224
225 ((WavpackHeader *) wps->blockbuff)->ckSize = sizeof (WavpackHeader) - 8;
226 ((WavpackHeader *) wps->blockbuff)->block_index = wps->sample_index;
227 ((WavpackHeader *) wps->blockbuff)->block_samples = 0;
228 ((WavpackHeader *) wps->blockbuff)->crc = 0xffffffff;
229
230 if (wpc->wrapper_bytes) {
231 wpmd.id = ID_RIFF_HEADER;
232 wpmd.byte_length = wpc->wrapper_bytes;
233 wpmd.data = wpc->wrapper_data;
234 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
235 free_metadata (&wpmd);
236 wpc->wrapper_data = NULL;
237 wpc->wrapper_bytes = 0;
238 }
239
240 write_decorr_terms (wps, &wpmd);
241 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
242 free_metadata (&wpmd);
243
244 write_decorr_weights (wps, &wpmd);
245 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
246 free_metadata (&wpmd);
247
248 write_decorr_samples (wps, &wpmd);
249 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
250 free_metadata (&wpmd);
251
252 write_entropy_vars (wps, &wpmd);
253 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
254 free_metadata (&wpmd);
255
256 if ((wps->wphdr.flags & INITIAL_BLOCK) && !wps->sample_index) {
257 write_config_info (wpc, &wpmd);
258 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
259 free_metadata (&wpmd);
260 }
261
262 bs_open_write (&wps->wvbits, wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 12, wps->blockend);
263
264 return TRUE;
265}
266
267static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr, int m);
268static void decorr_stereo_pass_18 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr);
269static void decorr_stereo_pass_17 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr);
270static void decorr_stereo_pass_m2 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr);
271
272int pack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count)
273{
274 WavpackStream *wps = &wpc->stream;
275 uint32_t flags = wps->wphdr.flags;
276 struct decorr_pass *dpp;
277 int32_t *bptr, *eptr;
278 int tcount, m;
279 uint32_t crc;
280
281 if (!sample_count)
282 return TRUE;
283
284 eptr = buffer + sample_count * ((flags & MONO_FLAG) ? 1 : 2);
285 m = ((WavpackHeader *) wps->blockbuff)->block_samples & (MAX_TERM - 1);
286 crc = ((WavpackHeader *) wps->blockbuff)->crc;
287
288 /////////////////////// handle lossless mono mode /////////////////////////
289
290 if (!(flags & HYBRID_FLAG) && (flags & MONO_FLAG))
291 for (bptr = buffer; bptr < eptr;) {
292 int32_t code;
293
294 crc = crc * 3 + (code = *bptr);
295
296 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
297 int32_t sam;
298
299 if (dpp->term > MAX_TERM) {
300 if (dpp->term & 1)
301 sam = 2 * dpp->samples_A [0] - dpp->samples_A [1];
302 else
303 sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
304
305 dpp->samples_A [1] = dpp->samples_A [0];
306 dpp->samples_A [0] = code;
307 }
308 else {
309 sam = dpp->samples_A [m];
310 dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = code;
311 }
312
313 code -= apply_weight_i (dpp->weight_A, sam);
314 update_weight (dpp->weight_A, 2, sam, code);
315 }
316
317 m = (m + 1) & (MAX_TERM - 1);
318 *bptr++ = code;
319 }
320
321 //////////////////// handle the lossless stereo mode //////////////////////
322
323 else if (!(flags & HYBRID_FLAG) && !(flags & MONO_FLAG)) {
324 if (flags & JOINT_STEREO)
325 for (bptr = buffer; bptr < eptr; bptr += 2) {
326 crc = crc * 9 + (bptr [0] * 3) + bptr [1];
327 bptr [1] += ((bptr [0] -= bptr [1]) >> 1);
328 }
329 else
330 for (bptr = buffer; bptr < eptr; bptr += 2)
331 crc = crc * 9 + (bptr [0] * 3) + bptr [1];
332
333 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) {
334 if (dpp->term == 17)
335 decorr_stereo_pass_17 (dpp, buffer, eptr);
336 else if (dpp->term == 18)
337 decorr_stereo_pass_18 (dpp, buffer, eptr);
338 else if (dpp->term >= 1 && dpp->term <= 7)
339 decorr_stereo_pass (dpp, buffer, eptr, m);
340 else if (dpp->term == -2)
341 decorr_stereo_pass_m2 (dpp, buffer, eptr);
342 }
343 }
344
345 send_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
346 ((WavpackHeader *) wps->blockbuff)->crc = crc;
347 ((WavpackHeader *) wps->blockbuff)->block_samples += sample_count;
348 wps->sample_index += sample_count;
349
350 return TRUE;
351}
352
353static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr, int m)
354{
355 int k = (m + dpp->term) & (MAX_TERM - 1);
356 int32_t sam;
357
358 while (bptr < eptr) {
359 dpp->samples_A [k] = bptr [0];
360 bptr [0] -= apply_weight_i (dpp->weight_A, (sam = dpp->samples_A [m]));
361 update_weight (dpp->weight_A, 2, sam, bptr [0]);
362 bptr++;
363 dpp->samples_B [k] = bptr [0];
364 bptr [0] -= apply_weight_i (dpp->weight_B, (sam = dpp->samples_B [m]));
365 update_weight (dpp->weight_B, 2, sam, bptr [0]);
366 bptr++;
367 m = (m + 1) & (MAX_TERM - 1);
368 k = (k + 1) & (MAX_TERM - 1);
369 }
370}
371
372static void decorr_stereo_pass_18 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr)
373{
374 int32_t sam;
375
376 while (bptr < eptr) {
377 sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
378 dpp->samples_A [1] = dpp->samples_A [0];
379 dpp->samples_A [0] = bptr [0];
380 bptr [0] -= apply_weight_i (dpp->weight_A, sam);
381 update_weight (dpp->weight_A, 2, sam, bptr [0]);
382 bptr++;
383 sam = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
384 dpp->samples_B [1] = dpp->samples_B [0];
385 dpp->samples_B [0] = bptr [0];
386 bptr [0] -= apply_weight_i (dpp->weight_B, sam);
387 update_weight (dpp->weight_B, 2, sam, bptr [0]);
388 bptr++;
389 }
390}
391
392static void decorr_stereo_pass_m2 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr)
393{
394 int32_t sam_A, sam_B;
395
396 for (; bptr < eptr; bptr += 2) {
397 sam_A = bptr [1];
398 sam_B = dpp->samples_B [0];
399 dpp->samples_B [0] = bptr [0];
400 bptr [0] -= apply_weight_i (dpp->weight_A, sam_A);
401 update_weight_clip (dpp->weight_A, 2, sam_A, bptr [0]);
402 bptr [1] -= apply_weight_i (dpp->weight_B, sam_B);
403 update_weight_clip (dpp->weight_B, 2, sam_B, bptr [1]);
404 }
405}
406
407static void decorr_stereo_pass_17 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr)
408{
409 int32_t sam;
410
411 while (bptr < eptr) {
412 sam = 2 * dpp->samples_A [0] - dpp->samples_A [1];
413 dpp->samples_A [1] = dpp->samples_A [0];
414 dpp->samples_A [0] = bptr [0];
415 bptr [0] -= apply_weight_i (dpp->weight_A, sam);
416 update_weight (dpp->weight_A, 2, sam, bptr [0]);
417 bptr++;
418 sam = 2 * dpp->samples_B [0] - dpp->samples_B [1];
419 dpp->samples_B [1] = dpp->samples_B [0];
420 dpp->samples_B [0] = bptr [0];
421 bptr [0] -= apply_weight_i (dpp->weight_B, sam);
422 update_weight (dpp->weight_B, 2, sam, bptr [0]);
423 bptr++;
424 }
425}
426
427int pack_finish_block (WavpackContext *wpc)
428{
429 WavpackStream *wps = &wpc->stream;
430 struct decorr_pass *dpp;
431 uint32_t data_count;
432 int tcount, m;
433
434 m = ((WavpackHeader *) wps->blockbuff)->block_samples & (MAX_TERM - 1);
435
436 if (m)
437 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
438 if (dpp->term > 0 && dpp->term <= MAX_TERM) {
439 int32_t temp_A [MAX_TERM], temp_B [MAX_TERM];
440 int k;
441
442 memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A));
443 memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B));
444
445 for (k = 0; k < MAX_TERM; k++) {
446 dpp->samples_A [k] = temp_A [m];
447 dpp->samples_B [k] = temp_B [m];
448 m = (m + 1) & (MAX_TERM - 1);
449 }
450 }
451
452 flush_word (&wps->w, &wps->wvbits);
453 data_count = bs_close_write (&wps->wvbits);
454
455 if (data_count) {
456 if (data_count != (uint32_t) -1) {
457 uchar *cptr = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 8;
458
459 *cptr++ = ID_WV_BITSTREAM | ID_LARGE;
460 *cptr++ = data_count >> 1;
461 *cptr++ = data_count >> 9;
462 *cptr++ = data_count >> 17;
463 ((WavpackHeader *) wps->blockbuff)->ckSize += data_count + 4;
464 }
465 else
466 return FALSE;
467 }
468
469 return TRUE;
470}
diff --git a/lib/rbcodec/codecs/libwavpack/unpack.c b/lib/rbcodec/codecs/libwavpack/unpack.c
new file mode 100644
index 0000000000..69252f24ad
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/unpack.c
@@ -0,0 +1,780 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// unpack.c
10
11// This module actually handles the decompression of the audio data, except
12// for the entropy decoding which is handled by the words.c module. For
13// maximum efficiency, the conversion is isolated to tight loops that handle
14// an entire buffer.
15
16#include "wavpack.h"
17
18#include <stdlib.h>
19#include <string.h>
20
21static void strcpy_loc (char *dst, char *src) { while ((*dst++ = *src++) != 0); }
22
23#define LOSSY_MUTE
24
25///////////////////////////// executable code ////////////////////////////////
26
27// This function initializes everything required to unpack a WavPack block
28// and must be called before unpack_samples() is called to obtain audio data.
29// It is assumed that the WavpackHeader has been read into the wps->wphdr
30// (in the current WavpackStream). This is where all the metadata blocks are
31// scanned up to the one containing the audio bitstream.
32
33int unpack_init (WavpackContext *wpc)
34{
35 WavpackStream *wps = &wpc->stream;
36 WavpackMetadata wpmd;
37
38 if (wps->wphdr.block_samples && wps->wphdr.block_index != (uint32_t) -1)
39 wps->sample_index = wps->wphdr.block_index;
40
41 wps->mute_error = FALSE;
42 wps->crc = 0xffffffff;
43 CLEAR (wps->wvbits);
44 CLEAR (wps->decorr_passes);
45 CLEAR (wps->w);
46
47 while (read_metadata_buff (wpc, &wpmd)) {
48 if (!process_metadata (wpc, &wpmd)) {
49 strcpy_loc (wpc->error_message, "invalid metadata!");
50 return FALSE;
51 }
52
53 if (wpmd.id == ID_WV_BITSTREAM)
54 break;
55 }
56
57 if (wps->wphdr.block_samples && !bs_is_open (&wps->wvbits)) {
58 strcpy_loc (wpc->error_message, "invalid WavPack file!");
59 return FALSE;
60 }
61
62 if (wps->wphdr.block_samples) {
63 if ((wps->wphdr.flags & INT32_DATA) && wps->int32_sent_bits)
64 wpc->lossy_blocks = TRUE;
65
66 if ((wps->wphdr.flags & FLOAT_DATA) &&
67 wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME))
68 wpc->lossy_blocks = TRUE;
69 }
70
71 return TRUE;
72}
73
74// This function initialzes the main bitstream for audio samples, which must
75// be in the "wv" file.
76
77int init_wv_bitstream (WavpackContext *wpc, WavpackMetadata *wpmd)
78{
79 WavpackStream *wps = &wpc->stream;
80
81 if (wpmd->data)
82 bs_open_read (&wps->wvbits, wpmd->data, (unsigned char *) wpmd->data + wpmd->byte_length, NULL, 0);
83 else if (wpmd->byte_length)
84 bs_open_read (&wps->wvbits, wpc->read_buffer, wpc->read_buffer + sizeof (wpc->read_buffer),
85 wpc->infile, wpmd->byte_length + (wpmd->byte_length & 1));
86
87 return TRUE;
88}
89
90// Read decorrelation terms from specified metadata block into the
91// decorr_passes array. The terms range from -3 to 8, plus 17 & 18;
92// other values are reserved and generate errors for now. The delta
93// ranges from 0 to 7 with all values valid. Note that the terms are
94// stored in the opposite order in the decorr_passes array compared
95// to packing.
96
97int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
98{
99 int termcnt = wpmd->byte_length;
100 uchar *byteptr = wpmd->data;
101 struct decorr_pass *dpp;
102
103 if (termcnt > MAX_NTERMS)
104 return FALSE;
105
106 wps->num_terms = termcnt;
107
108 for (dpp = wps->decorr_passes + termcnt - 1; termcnt--; dpp--) {
109 dpp->term = (int)(*byteptr & 0x1f) - 5;
110 dpp->delta = (*byteptr++ >> 5) & 0x7;
111
112 if (!dpp->term || dpp->term < -3 || (dpp->term > MAX_TERM && dpp->term < 17) || dpp->term > 18)
113 return FALSE;
114 }
115
116 return TRUE;
117}
118
119// Read decorrelation weights from specified metadata block into the
120// decorr_passes array. The weights range +/-1024, but are rounded and
121// truncated to fit in signed chars for metadata storage. Weights are
122// separate for the two channels and are specified from the "last" term
123// (first during encode). Unspecified weights are set to zero.
124
125int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
126{
127 int termcnt = wpmd->byte_length, tcount;
128 signed char *byteptr = wpmd->data;
129 struct decorr_pass *dpp;
130
131 if (!(wps->wphdr.flags & MONO_DATA))
132 termcnt /= 2;
133
134 if (termcnt > wps->num_terms)
135 return FALSE;
136
137 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
138 dpp->weight_A = dpp->weight_B = 0;
139
140 while (--dpp >= wps->decorr_passes && termcnt--) {
141 dpp->weight_A = restore_weight (*byteptr++);
142
143 if (!(wps->wphdr.flags & MONO_DATA))
144 dpp->weight_B = restore_weight (*byteptr++);
145 }
146
147 return TRUE;
148}
149
150// Read decorrelation samples from specified metadata block into the
151// decorr_passes array. The samples are signed 32-bit values, but are
152// converted to signed log2 values for storage in metadata. Values are
153// stored for both channels and are specified from the "last" term
154// (first during encode) with unspecified samples set to zero. The
155// number of samples stored varies with the actual term value, so
156// those must obviously come first in the metadata.
157
158int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
159{
160 uchar *byteptr = wpmd->data;
161 uchar *endptr = byteptr + wpmd->byte_length;
162 struct decorr_pass *dpp;
163 int tcount;
164
165 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
166 CLEAR (dpp->samples_A);
167 CLEAR (dpp->samples_B);
168 }
169
170 if (wps->wphdr.version == 0x402 && (wps->wphdr.flags & HYBRID_FLAG)) {
171 byteptr += 2;
172
173 if (!(wps->wphdr.flags & MONO_DATA))
174 byteptr += 2;
175 }
176
177 while (dpp-- > wps->decorr_passes && byteptr < endptr)
178 if (dpp->term > MAX_TERM) {
179 dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
180 dpp->samples_A [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
181 byteptr += 4;
182
183 if (!(wps->wphdr.flags & MONO_DATA)) {
184 dpp->samples_B [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
185 dpp->samples_B [1] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
186 byteptr += 4;
187 }
188 }
189 else if (dpp->term < 0) {
190 dpp->samples_A [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
191 dpp->samples_B [0] = exp2s ((short)(byteptr [2] + (byteptr [3] << 8)));
192 byteptr += 4;
193 }
194 else {
195 int m = 0, cnt = dpp->term;
196
197 while (cnt--) {
198 dpp->samples_A [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
199 byteptr += 2;
200
201 if (!(wps->wphdr.flags & MONO_DATA)) {
202 dpp->samples_B [m] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
203 byteptr += 2;
204 }
205
206 m++;
207 }
208 }
209
210 return byteptr == endptr;
211}
212
213// Read the int32 data from the specified metadata into the specified stream.
214// This data is used for integer data that has more than 24 bits of magnitude
215// or, in some cases, used to eliminate redundant bits from any audio stream.
216
217int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd)
218{
219 int bytecnt = wpmd->byte_length;
220 char *byteptr = wpmd->data;
221
222 if (bytecnt != 4)
223 return FALSE;
224
225 wps->int32_sent_bits = *byteptr++;
226 wps->int32_zeros = *byteptr++;
227 wps->int32_ones = *byteptr++;
228 wps->int32_dups = *byteptr;
229 return TRUE;
230}
231
232// Read multichannel information from metadata. The first byte is the total
233// number of channels and the following bytes represent the channel_mask
234// as described for Microsoft WAVEFORMATEX.
235
236int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd)
237{
238 int bytecnt = wpmd->byte_length, shift = 0;
239 char *byteptr = wpmd->data;
240 uint32_t mask = 0;
241
242 if (!bytecnt || bytecnt > 5)
243 return FALSE;
244
245 wpc->config.num_channels = *byteptr++;
246
247 while (--bytecnt) {
248 mask |= (uint32_t) *byteptr++ << shift;
249 shift += 8;
250 }
251
252 wpc->config.channel_mask = mask;
253 return TRUE;
254}
255
256// Read configuration information from metadata.
257
258int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
259{
260 int bytecnt = wpmd->byte_length;
261 uchar *byteptr = wpmd->data;
262
263 if (bytecnt >= 3) {
264 wpc->config.flags &= 0xff;
265 wpc->config.flags |= (int32_t) *byteptr++ << 8;
266 wpc->config.flags |= (int32_t) *byteptr++ << 16;
267 wpc->config.flags |= (int32_t) *byteptr << 24;
268 }
269
270 return TRUE;
271}
272
273// Read non-standard sampling rate from metadata.
274
275int read_sample_rate (WavpackContext *wpc, WavpackMetadata *wpmd)
276{
277 int bytecnt = wpmd->byte_length;
278 uchar *byteptr = wpmd->data;
279
280 if (bytecnt == 3) {
281 wpc->config.sample_rate = (int32_t) *byteptr++;
282 wpc->config.sample_rate |= (int32_t) *byteptr++ << 8;
283 wpc->config.sample_rate |= (int32_t) *byteptr++ << 16;
284 }
285
286 return TRUE;
287}
288
289// This monster actually unpacks the WavPack bitstream(s) into the specified
290// buffer as 32-bit integers or floats (depending on orignal data). Lossy
291// samples will be clipped to their original limits (i.e. 8-bit samples are
292// clipped to -128/+127) but are still returned in int32_ts. It is up to the
293// caller to potentially reformat this for the final output including any
294// multichannel distribution, block alignment or endian compensation. The
295// function unpack_init() must have been called and the entire WavPack block
296// must still be visible (although wps->blockbuff will not be accessed again).
297// For maximum clarity, the function is broken up into segments that handle
298// various modes. This makes for a few extra infrequent flag checks, but
299// makes the code easier to follow because the nesting does not become so
300// deep. For maximum efficiency, the conversion is isolated to tight loops
301// that handle an entire buffer. The function returns the total number of
302// samples unpacked, which can be less than the number requested if an error
303// occurs or the end of the block is reached.
304
305#if defined(CPU_COLDFIRE)
306extern void decorr_stereo_pass_cont_mcf5249 (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
307#elif defined(CPU_ARM)
308extern void decorr_stereo_pass_cont_arm (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
309extern void decorr_stereo_pass_cont_arml (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
310#else
311static void decorr_stereo_pass_cont (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
312#endif
313
314static void decorr_mono_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
315static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count);
316static void fixup_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_count);
317
318int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count)
319{
320 WavpackStream *wps = &wpc->stream;
321 uint32_t flags = wps->wphdr.flags, crc = wps->crc, i;
322 int32_t mute_limit = (1L << ((flags & MAG_MASK) >> MAG_LSB)) + 2;
323 struct decorr_pass *dpp;
324 int32_t *bptr, *eptr;
325 int tcount;
326
327 if (wps->sample_index + sample_count > wps->wphdr.block_index + wps->wphdr.block_samples)
328 sample_count = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index;
329
330 if (wps->mute_error) {
331 memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8));
332 wps->sample_index += sample_count;
333 return sample_count;
334 }
335
336 if (flags & HYBRID_FLAG)
337 mute_limit *= 2;
338
339 ///////////////////// handle version 4 mono data /////////////////////////
340
341 if (flags & MONO_DATA) {
342 eptr = buffer + sample_count;
343 i = get_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
344
345 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
346 decorr_mono_pass (dpp, buffer, sample_count);
347
348 for (bptr = buffer; bptr < eptr; ++bptr) {
349 if (labs (bptr [0]) > mute_limit) {
350 i = bptr - buffer;
351 break;
352 }
353
354 crc = crc * 3 + bptr [0];
355 }
356 }
357
358 //////////////////// handle version 4 stereo data ////////////////////////
359
360 else {
361 eptr = buffer + (sample_count * 2);
362 i = get_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
363
364 if (sample_count < 16)
365 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
366 decorr_stereo_pass (dpp, buffer, sample_count);
367 else
368 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
369 decorr_stereo_pass (dpp, buffer, 8);
370#if defined(CPU_COLDFIRE)
371 decorr_stereo_pass_cont_mcf5249 (dpp, buffer + 16, sample_count - 8);
372#elif defined(CPU_ARM)
373 if (((flags & MAG_MASK) >> MAG_LSB) > 15)
374 decorr_stereo_pass_cont_arml (dpp, buffer + 16, sample_count - 8);
375 else
376 decorr_stereo_pass_cont_arm (dpp, buffer + 16, sample_count - 8);
377#else
378 decorr_stereo_pass_cont (dpp, buffer + 16, sample_count - 8);
379#endif
380 }
381
382 if (flags & JOINT_STEREO)
383 for (bptr = buffer; bptr < eptr; bptr += 2) {
384 bptr [0] += (bptr [1] -= (bptr [0] >> 1));
385
386 if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) {
387 i = (bptr - buffer) / 2;
388 break;
389 }
390
391 crc = (crc * 3 + bptr [0]) * 3 + bptr [1];
392 }
393 else
394 for (bptr = buffer; bptr < eptr; bptr += 2) {
395 if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) {
396 i = (bptr - buffer) / 2;
397 break;
398 }
399
400 crc = (crc * 3 + bptr [0]) * 3 + bptr [1];
401 }
402 }
403
404 if (i != sample_count) {
405 memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8));
406 wps->mute_error = TRUE;
407 i = sample_count;
408 }
409
410 fixup_samples (wps, buffer, i);
411
412 if (flags & FALSE_STEREO) {
413 int32_t *dptr = buffer + i * 2;
414 int32_t *sptr = buffer + i;
415 int32_t c = i;
416
417 while (c--) {
418 *--dptr = *--sptr;
419 *--dptr = *sptr;
420 }
421 }
422
423 wps->sample_index += i;
424 wps->crc = crc;
425
426 return i;
427}
428
429static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count)
430{
431 int32_t delta = dpp->delta, weight_A = dpp->weight_A, weight_B = dpp->weight_B;
432 int32_t *bptr, *eptr = buffer + (sample_count * 2), sam_A, sam_B;
433 int m, k;
434
435 switch (dpp->term) {
436
437 case 17:
438 for (bptr = buffer; bptr < eptr; bptr += 2) {
439 sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
440 dpp->samples_A [1] = dpp->samples_A [0];
441 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
442 update_weight (weight_A, delta, sam_A, bptr [0]);
443 bptr [0] = dpp->samples_A [0];
444
445 sam_A = 2 * dpp->samples_B [0] - dpp->samples_B [1];
446 dpp->samples_B [1] = dpp->samples_B [0];
447 dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1];
448 update_weight (weight_B, delta, sam_A, bptr [1]);
449 bptr [1] = dpp->samples_B [0];
450 }
451
452 break;
453
454 case 18:
455 for (bptr = buffer; bptr < eptr; bptr += 2) {
456 sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
457 dpp->samples_A [1] = dpp->samples_A [0];
458 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
459 update_weight (weight_A, delta, sam_A, bptr [0]);
460 bptr [0] = dpp->samples_A [0];
461
462 sam_A = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
463 dpp->samples_B [1] = dpp->samples_B [0];
464 dpp->samples_B [0] = apply_weight (weight_B, sam_A) + bptr [1];
465 update_weight (weight_B, delta, sam_A, bptr [1]);
466 bptr [1] = dpp->samples_B [0];
467 }
468
469 break;
470
471 default:
472 for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) {
473 sam_A = dpp->samples_A [m];
474 dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0];
475 update_weight (weight_A, delta, sam_A, bptr [0]);
476 bptr [0] = dpp->samples_A [k];
477
478 sam_A = dpp->samples_B [m];
479 dpp->samples_B [k] = apply_weight (weight_B, sam_A) + bptr [1];
480 update_weight (weight_B, delta, sam_A, bptr [1]);
481 bptr [1] = dpp->samples_B [k];
482
483 m = (m + 1) & (MAX_TERM - 1);
484 k = (k + 1) & (MAX_TERM - 1);
485 }
486
487 if (m) {
488 int32_t temp_samples [MAX_TERM];
489
490 memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A));
491
492 for (k = 0; k < MAX_TERM; k++, m++)
493 dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)];
494
495 memcpy (temp_samples, dpp->samples_B, sizeof (dpp->samples_B));
496
497 for (k = 0; k < MAX_TERM; k++, m++)
498 dpp->samples_B [k] = temp_samples [m & (MAX_TERM - 1)];
499 }
500
501 break;
502
503 case -1:
504 for (bptr = buffer; bptr < eptr; bptr += 2) {
505 sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]);
506 update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]);
507 bptr [0] = sam_A;
508 dpp->samples_A [0] = bptr [1] + apply_weight (weight_B, sam_A);
509 update_weight_clip (weight_B, delta, sam_A, bptr [1]);
510 bptr [1] = dpp->samples_A [0];
511 }
512
513 break;
514
515 case -2:
516 for (bptr = buffer; bptr < eptr; bptr += 2) {
517 sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]);
518 update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]);
519 bptr [1] = sam_B;
520 dpp->samples_B [0] = bptr [0] + apply_weight (weight_A, sam_B);
521 update_weight_clip (weight_A, delta, sam_B, bptr [0]);
522 bptr [0] = dpp->samples_B [0];
523 }
524
525 break;
526
527 case -3:
528 for (bptr = buffer; bptr < eptr; bptr += 2) {
529 sam_A = bptr [0] + apply_weight (weight_A, dpp->samples_A [0]);
530 update_weight_clip (weight_A, delta, dpp->samples_A [0], bptr [0]);
531 sam_B = bptr [1] + apply_weight (weight_B, dpp->samples_B [0]);
532 update_weight_clip (weight_B, delta, dpp->samples_B [0], bptr [1]);
533 bptr [0] = dpp->samples_B [0] = sam_A;
534 bptr [1] = dpp->samples_A [0] = sam_B;
535 }
536
537 break;
538 }
539
540 dpp->weight_A = weight_A;
541 dpp->weight_B = weight_B;
542}
543
544#if (!defined(CPU_COLDFIRE) && !defined(CPU_ARM))
545
546static void decorr_stereo_pass_cont (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count)
547{
548 int32_t delta = dpp->delta, weight_A = dpp->weight_A, weight_B = dpp->weight_B;
549 int32_t *bptr, *tptr, *eptr = buffer + (sample_count * 2), sam_A, sam_B;
550 int k, i;
551
552 switch (dpp->term) {
553
554 case 17:
555 for (bptr = buffer; bptr < eptr; bptr += 2) {
556 sam_A = 2 * bptr [-2] - bptr [-4];
557 bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]);
558 update_weight (weight_A, delta, sam_A, sam_B);
559
560 sam_A = 2 * bptr [-1] - bptr [-3];
561 bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]);
562 update_weight (weight_B, delta, sam_A, sam_B);
563 }
564
565 dpp->samples_B [0] = bptr [-1];
566 dpp->samples_A [0] = bptr [-2];
567 dpp->samples_B [1] = bptr [-3];
568 dpp->samples_A [1] = bptr [-4];
569 break;
570
571 case 18:
572 for (bptr = buffer; bptr < eptr; bptr += 2) {
573 sam_A = (3 * bptr [-2] - bptr [-4]) >> 1;
574 bptr [0] = apply_weight (weight_A, sam_A) + (sam_B = bptr [0]);
575 update_weight (weight_A, delta, sam_A, sam_B);
576
577 sam_A = (3 * bptr [-1] - bptr [-3]) >> 1;
578 bptr [1] = apply_weight (weight_B, sam_A) + (sam_B = bptr [1]);
579 update_weight (weight_B, delta, sam_A, sam_B);
580 }
581
582 dpp->samples_B [0] = bptr [-1];
583 dpp->samples_A [0] = bptr [-2];
584 dpp->samples_B [1] = bptr [-3];
585 dpp->samples_A [1] = bptr [-4];
586 break;
587
588 default:
589 for (bptr = buffer, tptr = buffer - (dpp->term * 2); bptr < eptr; bptr += 2, tptr += 2) {
590 bptr [0] = apply_weight (weight_A, tptr [0]) + (sam_A = bptr [0]);
591 update_weight (weight_A, delta, tptr [0], sam_A);
592
593 bptr [1] = apply_weight (weight_B, tptr [1]) + (sam_A = bptr [1]);
594 update_weight (weight_B, delta, tptr [1], sam_A);
595 }
596
597 for (k = dpp->term - 1, i = 8; i--; k--) {
598 dpp->samples_B [k & (MAX_TERM - 1)] = *--bptr;
599 dpp->samples_A [k & (MAX_TERM - 1)] = *--bptr;
600 }
601
602 break;
603
604 case -1:
605 for (bptr = buffer; bptr < eptr; bptr += 2) {
606 bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]);
607 update_weight_clip (weight_A, delta, bptr [-1], sam_A);
608 bptr [1] = apply_weight (weight_B, bptr [0]) + (sam_A = bptr [1]);
609 update_weight_clip (weight_B, delta, bptr [0], sam_A);
610 }
611
612 dpp->samples_A [0] = bptr [-1];
613 break;
614
615 case -2:
616 for (bptr = buffer; bptr < eptr; bptr += 2) {
617 bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]);
618 update_weight_clip (weight_B, delta, bptr [-2], sam_A);
619 bptr [0] = apply_weight (weight_A, bptr [1]) + (sam_A = bptr [0]);
620 update_weight_clip (weight_A, delta, bptr [1], sam_A);
621 }
622
623 dpp->samples_B [0] = bptr [-2];
624 break;
625
626 case -3:
627 for (bptr = buffer; bptr < eptr; bptr += 2) {
628 bptr [0] = apply_weight (weight_A, bptr [-1]) + (sam_A = bptr [0]);
629 update_weight_clip (weight_A, delta, bptr [-1], sam_A);
630 bptr [1] = apply_weight (weight_B, bptr [-2]) + (sam_A = bptr [1]);
631 update_weight_clip (weight_B, delta, bptr [-2], sam_A);
632 }
633
634 dpp->samples_A [0] = bptr [-1];
635 dpp->samples_B [0] = bptr [-2];
636 break;
637 }
638
639 dpp->weight_A = weight_A;
640 dpp->weight_B = weight_B;
641}
642
643#endif
644
645static void decorr_mono_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count)
646{
647 int32_t delta = dpp->delta, weight_A = dpp->weight_A;
648 int32_t *bptr, *eptr = buffer + sample_count, sam_A;
649 int m, k;
650
651 switch (dpp->term) {
652
653 case 17:
654 for (bptr = buffer; bptr < eptr; bptr++) {
655 sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1];
656 dpp->samples_A [1] = dpp->samples_A [0];
657 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
658 update_weight (weight_A, delta, sam_A, bptr [0]);
659 bptr [0] = dpp->samples_A [0];
660 }
661
662 break;
663
664 case 18:
665 for (bptr = buffer; bptr < eptr; bptr++) {
666 sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
667 dpp->samples_A [1] = dpp->samples_A [0];
668 dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0];
669 update_weight (weight_A, delta, sam_A, bptr [0]);
670 bptr [0] = dpp->samples_A [0];
671 }
672
673 break;
674
675 default:
676 for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr++) {
677 sam_A = dpp->samples_A [m];
678 dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0];
679 update_weight (weight_A, delta, sam_A, bptr [0]);
680 bptr [0] = dpp->samples_A [k];
681 m = (m + 1) & (MAX_TERM - 1);
682 k = (k + 1) & (MAX_TERM - 1);
683 }
684
685 if (m) {
686 int32_t temp_samples [MAX_TERM];
687
688 memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A));
689
690 for (k = 0; k < MAX_TERM; k++, m++)
691 dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)];
692 }
693
694 break;
695 }
696
697 dpp->weight_A = weight_A;
698}
699
700
701// This is a helper function for unpack_samples() that applies several final
702// operations. First, if the data is 32-bit float data, then that conversion
703// is done in the float.c module (whether lossy or lossless) and we return.
704// Otherwise, if the extended integer data applies, then that operation is
705// executed first. If the unpacked data is lossy (and not corrected) then
706// it is clipped and shifted in a single operation. Otherwise, if it's
707// lossless then the last step is to apply the final shift (if any).
708
709// This function has been modified for RockBox to return all integer samples
710// as 28-bits, and clipping (for lossy mode) has been eliminated because this
711// now happens in the dsp module.
712
713static void fixup_samples (WavpackStream *wps, int32_t *buffer, uint32_t sample_count)
714{
715 uint32_t flags = wps->wphdr.flags;
716 int shift = (flags & SHIFT_MASK) >> SHIFT_LSB;
717
718 shift += 21 - (flags & BYTES_STORED) * 8; // this provides RockBox with 28-bit (+sign)
719
720 if (flags & FLOAT_DATA) {
721 float_values (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2);
722 return;
723 }
724
725 if (flags & INT32_DATA) {
726 uint32_t count = (flags & MONO_DATA) ? sample_count : sample_count * 2;
727 int sent_bits = wps->int32_sent_bits, zeros = wps->int32_zeros;
728 int ones = wps->int32_ones, dups = wps->int32_dups;
729 int32_t *dptr = buffer;
730
731 if (!(flags & HYBRID_FLAG) && !sent_bits && (zeros + ones + dups))
732 while (count--) {
733 if (zeros)
734 *dptr <<= zeros;
735 else if (ones)
736 *dptr = ((*dptr + 1) << ones) - 1;
737 else if (dups)
738 *dptr = ((*dptr + (*dptr & 1)) << dups) - (*dptr & 1);
739
740 dptr++;
741 }
742 else
743 shift += zeros + sent_bits + ones + dups;
744 }
745
746 if (shift > 0) {
747 if (!(flags & MONO_DATA))
748 sample_count *= 2;
749
750 while (sample_count--)
751 *buffer++ <<= shift;
752 }
753 else if (shift < 0) {
754 shift = -shift;
755
756 if (!(flags & MONO_DATA))
757 sample_count *= 2;
758
759 while (sample_count--)
760 *buffer++ >>= shift;
761 }
762}
763
764// This function checks the crc value(s) for an unpacked block, returning the
765// number of actual crc errors detected for the block. The block must be
766// completely unpacked before this test is valid. For losslessly unpacked
767// blocks of float or extended integer data the extended crc is also checked.
768// Note that WavPack's crc is not a CCITT approved polynomial algorithm, but
769// is a much simpler method that is virtually as robust for real world data.
770
771int check_crc_error (WavpackContext *wpc)
772{
773 WavpackStream *wps = &wpc->stream;
774 int result = 0;
775
776 if (wps->crc != wps->wphdr.crc)
777 ++result;
778
779 return result;
780}
diff --git a/lib/rbcodec/codecs/libwavpack/wavpack.h b/lib/rbcodec/codecs/libwavpack/wavpack.h
new file mode 100644
index 0000000000..b15a176f33
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/wavpack.h
@@ -0,0 +1,447 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// wavpack.h
10#ifdef CODEC
11#include "codeclib.h"
12#endif
13#include <inttypes.h>
14
15// This header file contains all the definitions required by WavPack.
16
17typedef unsigned char uchar;
18typedef unsigned short ushort;
19#if 0 // unused and causing compiler errrors
20typedef unsigned int uint;
21#endif
22
23#include <stdio.h>
24
25#define FALSE 0
26#define TRUE 1
27
28////////////////////////////// WavPack Header /////////////////////////////////
29
30// Note that this is the ONLY structure that is written to (or read from)
31// WavPack 4.0 files, and is the preamble to every block in both the .wv
32// and .wvc files.
33
34typedef struct {
35 char ckID [4];
36 uint32_t ckSize;
37 short version;
38 uchar track_no, index_no;
39 uint32_t total_samples, block_index, block_samples, flags, crc;
40} WavpackHeader;
41
42#define WavpackHeaderFormat "4LS2LLLLL"
43
44// or-values for "flags"
45
46#define BYTES_STORED 3 // 1-4 bytes/sample
47#define MONO_FLAG 4 // not stereo
48#define HYBRID_FLAG 8 // hybrid mode
49#define JOINT_STEREO 0x10 // joint stereo
50#define CROSS_DECORR 0x20 // no-delay cross decorrelation
51#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
52#define FLOAT_DATA 0x80 // ieee 32-bit floating point data
53
54#define INT32_DATA 0x100 // special extended int handling
55#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only)
56#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only)
57
58#define INITIAL_BLOCK 0x800 // initial block of multichannel segment
59#define FINAL_BLOCK 0x1000 // final block of multichannel segment
60
61#define SHIFT_LSB 13
62#define SHIFT_MASK (0x1fL << SHIFT_LSB)
63
64#define MAG_LSB 18
65#define MAG_MASK (0x1fL << MAG_LSB)
66
67#define SRATE_LSB 23
68#define SRATE_MASK (0xfL << SRATE_LSB)
69
70#define FALSE_STEREO 0x40000000 // block is stereo, but data is mono
71
72#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
73#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
74#define UNKNOWN_FLAGS 0x80000000 // also reserved, but refuse decode if
75 // encountered
76
77#define MONO_DATA (MONO_FLAG | FALSE_STEREO)
78
79#define MIN_STREAM_VERS 0x402 // lowest stream version we'll decode
80#define MAX_STREAM_VERS 0x410 // highest stream version we'll decode
81#define CUR_STREAM_VERS 0x403 // stream version we are writing now
82
83//////////////////////////// WavPack Metadata /////////////////////////////////
84
85// This is an internal representation of metadata.
86
87typedef struct {
88 uchar temp_data [64];
89 int32_t byte_length;
90 void *data;
91 uchar id;
92} WavpackMetadata;
93
94#define ID_OPTIONAL_DATA 0x20
95#define ID_ODD_SIZE 0x40
96#define ID_LARGE 0x80
97
98#define ID_DUMMY 0x0
99#define ID_ENCODER_INFO 0x1
100#define ID_DECORR_TERMS 0x2
101#define ID_DECORR_WEIGHTS 0x3
102#define ID_DECORR_SAMPLES 0x4
103#define ID_ENTROPY_VARS 0x5
104#define ID_HYBRID_PROFILE 0x6
105#define ID_SHAPING_WEIGHTS 0x7
106#define ID_FLOAT_INFO 0x8
107#define ID_INT32_INFO 0x9
108#define ID_WV_BITSTREAM 0xa
109#define ID_WVC_BITSTREAM 0xb
110#define ID_WVX_BITSTREAM 0xc
111#define ID_CHANNEL_INFO 0xd
112
113#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1)
114#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2)
115#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3)
116#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4)
117#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5)
118#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6)
119#define ID_SAMPLE_RATE (ID_OPTIONAL_DATA | 0x7)
120
121///////////////////////// WavPack Configuration ///////////////////////////////
122
123// This internal structure is used during encode to provide configuration to
124// the encoding engine and during decoding to provide fle information back to
125// the higher level functions. Not all fields are used in both modes.
126
127typedef struct {
128 int bits_per_sample, bytes_per_sample;
129 int flags, num_channels, float_norm_exp;
130 uint32_t sample_rate, channel_mask;
131} WavpackConfig;
132
133#define CONFIG_BYTES_STORED 3 // 1-4 bytes/sample
134#define CONFIG_MONO_FLAG 4 // not stereo
135#define CONFIG_HYBRID_FLAG 8 // hybrid mode
136#define CONFIG_JOINT_STEREO 0x10 // joint stereo
137#define CONFIG_CROSS_DECORR 0x20 // no-delay cross decorrelation
138#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
139#define CONFIG_FLOAT_DATA 0x80 // ieee 32-bit floating point data
140
141#define CONFIG_ADOBE_MODE 0x100 // "adobe" mode for 32-bit floats
142#define CONFIG_FAST_FLAG 0x200 // fast mode
143#define CONFIG_VERY_FAST_FLAG 0x400 // double fast
144#define CONFIG_HIGH_FLAG 0x800 // high quality mode
145#define CONFIG_VERY_HIGH_FLAG 0x1000 // double high (not used yet)
146#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample
147#define CONFIG_AUTO_SHAPING 0x4000 // automatic noise shaping
148#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified
149#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified
150#define CONFIG_COPY_TIME 0x20000 // copy file-time from source
151#define CONFIG_CREATE_EXE 0x40000 // create executable (not yet)
152#define CONFIG_CREATE_WVC 0x80000 // create correction file
153#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression
154#define CONFIG_QUALITY_MODE 0x200000 // psychoacoustic quality mode
155#define CONFIG_RAW_FLAG 0x400000 // raw mode (not implemented yet)
156#define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode
157#define CONFIG_LOSSY_MODE 0x1000000 // obsolete (for information)
158#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode
159#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
160#define CONFIG_MD5_CHECKSUM 0x8000000 // compute & store MD5 signature
161#define CONFIG_QUIET_MODE 0x10000000 // don't report progress %
162
163//////////////////////////////// WavPack Stream ///////////////////////////////
164
165// This internal structure contains everything required to handle a WavPack
166// "stream", which is defined as a stereo or mono stream of audio samples. For
167// multichannel audio several of these would be required. Each stream contains
168// pointers to hold a complete allocated block of WavPack data, although it's
169// possible to decode WavPack blocks without buffering an entire block.
170
171typedef int32_t (*read_stream)(void *, int32_t);
172
173typedef struct bs {
174 uchar *buf, *end, *ptr;
175 void (*wrap)(struct bs *bs);
176 uint32_t file_bytes, sr;
177 int error, bc;
178 read_stream file;
179} Bitstream;
180
181#define MAX_NTERMS 16
182#define MAX_TERM 8
183
184struct decorr_pass {
185 short term, delta, weight_A, weight_B;
186 int32_t samples_A [MAX_TERM], samples_B [MAX_TERM];
187};
188
189struct entropy_data {
190 uint32_t median [3], slow_level, error_limit;
191};
192
193struct words_data {
194 uint32_t bitrate_delta [2], bitrate_acc [2];
195 uint32_t pend_data, holding_one, zeros_acc;
196 int holding_zero, pend_count;
197 struct entropy_data c [2];
198};
199
200typedef struct {
201 WavpackHeader wphdr;
202 Bitstream wvbits;
203
204 struct words_data w;
205
206 int num_terms, mute_error;
207 uint32_t sample_index, crc;
208 int32_t block_bytes_left;
209
210 uchar int32_sent_bits, int32_zeros, int32_ones, int32_dups;
211 uchar float_flags, float_shift, float_max_exp, float_norm_exp;
212 uchar *blockbuff, *blockend;
213
214 struct decorr_pass decorr_passes [MAX_NTERMS];
215
216} WavpackStream;
217
218// flags for float_flags:
219
220#define FLOAT_SHIFT_ONES 1 // bits left-shifted into float = '1'
221#define FLOAT_SHIFT_SAME 2 // bits left-shifted into float are the same
222#define FLOAT_SHIFT_SENT 4 // bits shifted into float are sent literally
223#define FLOAT_ZEROS_SENT 8 // "zeros" are not all real zeros
224#define FLOAT_NEG_ZEROS 0x10 // contains negative zeros
225#define FLOAT_EXCEPTIONS 0x20 // contains exceptions (inf, nan, etc.)
226
227/////////////////////////////// WavPack Context ///////////////////////////////
228
229// This internal structure holds everything required to encode or decode WavPack
230// files. It is recommended that direct access to this structure be minimized
231// and the provided utilities used instead.
232
233typedef struct {
234 WavpackStream stream;
235 WavpackConfig config;
236
237 uchar *wrapper_data;
238 int wrapper_bytes;
239
240 uchar read_buffer [1024];
241 char error_message [80];
242
243 read_stream infile;
244 uint32_t total_samples, crc_errors, first_flags;
245 int open_flags, norm_offset, reduced_channels, lossy_blocks;
246
247} WavpackContext;
248
249//////////////////////// function prototypes and macros //////////////////////
250
251#define CLEAR(destin) memset (&destin, 0, sizeof (destin));
252
253// bits.c
254
255void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, uint32_t file_bytes);
256void bs_open_write (Bitstream *bs, uchar *buffer_start, uchar *buffer_end);
257uint32_t bs_close_write (Bitstream *bs);
258
259#define bs_is_open(bs) ((bs)->ptr != NULL)
260
261#define getbit(bs) ( \
262 (((bs)->bc) ? \
263 ((bs)->bc--, (bs)->sr & 1) : \
264 (((++((bs)->ptr) != (bs)->end) ? (void) 0 : (bs)->wrap (bs)), (bs)->bc = 7, ((bs)->sr = *((bs)->ptr)) & 1) \
265 ) ? \
266 ((bs)->sr >>= 1, 1) : \
267 ((bs)->sr >>= 1, 0) \
268)
269
270#define getbits(value, nbits, bs) { \
271 while ((nbits) > (bs)->bc) { \
272 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
273 (bs)->sr |= (int32_t)*((bs)->ptr) << (bs)->bc; \
274 (bs)->bc += 8; \
275 } \
276 *(value) = (bs)->sr; \
277 if ((bs)->bc > 32) { \
278 (bs)->bc -= (nbits); \
279 (bs)->sr = *((bs)->ptr) >> (8 - (bs)->bc); \
280 } \
281 else { \
282 (bs)->bc -= (nbits); \
283 (bs)->sr >>= (nbits); \
284 } \
285}
286
287#define putbit(bit, bs) { if (bit) (bs)->sr |= (1 << (bs)->bc); \
288 if (++((bs)->bc) == 8) { \
289 *((bs)->ptr) = (bs)->sr; \
290 (bs)->sr = (bs)->bc = 0; \
291 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
292 }}
293
294#define putbit_0(bs) { \
295 if (++((bs)->bc) == 8) { \
296 *((bs)->ptr) = (bs)->sr; \
297 (bs)->sr = (bs)->bc = 0; \
298 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
299 }}
300
301#define putbit_1(bs) { (bs)->sr |= (1 << (bs)->bc); \
302 if (++((bs)->bc) == 8) { \
303 *((bs)->ptr) = (bs)->sr; \
304 (bs)->sr = (bs)->bc = 0; \
305 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
306 }}
307
308#define putbits(value, nbits, bs) { \
309 (bs)->sr |= (int32_t)(value) << (bs)->bc; \
310 if (((bs)->bc += (nbits)) >= 8) \
311 do { \
312 *((bs)->ptr) = (bs)->sr; \
313 (bs)->sr >>= 8; \
314 if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \
315 } while (((bs)->bc -= 8) >= 8); \
316}
317
318void little_endian_to_native (void *data, char *format);
319void native_to_little_endian (void *data, char *format);
320
321// These macros implement the weight application and update operations
322// that are at the heart of the decorrelation loops. Note that when there
323// are several alternative versions of the same macro (marked with PERFCOND)
324// then the versions are functionally equivalent with respect to WavPack
325// decoding and the user should choose the one that provides the best
326// performance. This may be easier to check when NOT using the assembly
327// language optimizations.
328
329#if 1 // PERFCOND
330#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10)
331#else
332#define apply_weight_i(weight, sample) ((((weight * sample) >> 8) + 2) >> 2)
333#endif
334
335#define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \
336 (((sample & ~0xffff) >> 9) * weight) + 1) >> 1)
337
338#if 1 // PERFCOND
339#define apply_weight(weight, sample) (sample != (short) sample ? \
340 apply_weight_f (weight, sample) : apply_weight_i (weight, sample))
341#else
342#define apply_weight(weight, sample) ((int32_t)((weight * (int64_t) sample + 512) >> 10))
343#endif
344
345#if 0 // PERFCOND
346#define update_weight(weight, delta, source, result) \
347 if (source && result) { int32_t s = (int32_t) (source ^ result) >> 31; weight = (delta ^ s) + (weight - s); }
348#elif 1
349#define update_weight(weight, delta, source, result) \
350 if (source && result) weight += (((source ^ result) >> 30) | 1) * delta
351#else
352#define update_weight(weight, delta, source, result) \
353 if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta)
354#endif
355
356#define update_weight_clip(weight, delta, source, result) \
357 if (source && result && ((source ^ result) < 0 ? (weight -= delta) < -1024 : (weight += delta) > 1024)) \
358 weight = weight < 0 ? -1024 : 1024
359
360// unpack.c
361
362int unpack_init (WavpackContext *wpc);
363int init_wv_bitstream (WavpackContext *wpc, WavpackMetadata *wpmd);
364int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd);
365int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd);
366int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd);
367int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd);
368int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd);
369int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd);
370int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd);
371int read_sample_rate (WavpackContext *wpc, WavpackMetadata *wpmd);
372int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count);
373int check_crc_error (WavpackContext *wpc);
374
375// pack.c
376
377void pack_init (WavpackContext *wpc);
378int pack_start_block (WavpackContext *wpc);
379int pack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count);
380int pack_finish_block (WavpackContext *wpc);
381
382// metadata.c stuff
383
384int read_metadata_buff (WavpackContext *wpc, WavpackMetadata *wpmd);
385int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd);
386int copy_metadata (WavpackMetadata *wpmd, uchar *buffer_start, uchar *buffer_end);
387void free_metadata (WavpackMetadata *wpmd);
388
389// words.c stuff
390
391void init_words (WavpackStream *wps);
392int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
393void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd);
394int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd);
395int32_t get_words (int32_t *buffer, int nsamples, uint32_t flags,
396 struct words_data *w, Bitstream *bs);
397void send_word_lossless (int32_t value, int chan,
398 struct words_data *w, Bitstream *bs);
399void send_words (int32_t *buffer, int nsamples, uint32_t flags,
400 struct words_data *w, Bitstream *bs);
401void flush_word (struct words_data *w, Bitstream *bs);
402int log2s (int32_t value);
403int32_t exp2s (int log);
404signed char store_weight (int weight);
405int restore_weight (signed char weight);
406
407#define WORD_EOF (1L << 31)
408
409// float.c
410
411int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd);
412void float_values (WavpackStream *wps, int32_t *values, int32_t num_values);
413void float_normalize (int32_t *values, int32_t num_values, int delta_exp);
414
415// wputils.c
416
417WavpackContext *WavpackOpenFileInput (read_stream infile, char *error);
418
419int WavpackGetMode (WavpackContext *wpc);
420
421#define MODE_WVC 0x1
422#define MODE_LOSSLESS 0x2
423#define MODE_HYBRID 0x4
424#define MODE_FLOAT 0x8
425#define MODE_VALID_TAG 0x10
426#define MODE_HIGH 0x20
427#define MODE_FAST 0x40
428
429uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
430uint32_t WavpackGetNumSamples (WavpackContext *wpc);
431uint32_t WavpackGetSampleIndex (WavpackContext *wpc);
432int WavpackGetNumErrors (WavpackContext *wpc);
433int WavpackLossyBlocks (WavpackContext *wpc);
434uint32_t WavpackGetSampleRate (WavpackContext *wpc);
435int WavpackGetBitsPerSample (WavpackContext *wpc);
436int WavpackGetBytesPerSample (WavpackContext *wpc);
437int WavpackGetNumChannels (WavpackContext *wpc);
438int WavpackGetReducedChannels (WavpackContext *wpc);
439WavpackContext *WavpackOpenFileOutput (void);
440int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
441void WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
442int WavpackStartBlock (WavpackContext *wpc, uchar *begin, uchar *end);
443int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
444uint32_t WavpackFinishBlock (WavpackContext *wpc);
445void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block);
446void *WavpackGetWrapperLocation (void *first_block);
447
diff --git a/lib/rbcodec/codecs/libwavpack/words.c b/lib/rbcodec/codecs/libwavpack/words.c
new file mode 100644
index 0000000000..3d9e753e4b
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/words.c
@@ -0,0 +1,786 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6////////////////////////////////////////////////////////////////////////////
7
8// words.c
9
10// This module provides entropy word encoding and decoding functions using
11// a variation on the Rice method. This was introduced in version 3.93
12// because it allows splitting the data into a "lossy" stream and a
13// "correction" stream in a very efficient manner and is therefore ideal
14// for the "hybrid" mode. For 4.0, the efficiency of this method was
15// significantly improved by moving away from the normal Rice restriction of
16// using powers of two for the modulus divisions and now the method can be
17// used for both hybrid and pure lossless encoding.
18
19// Samples are divided by median probabilities at 5/7 (71.43%), 10/49 (20.41%),
20// and 20/343 (5.83%). Each zone has 3.5 times fewer samples than the
21// previous. Using standard Rice coding on this data would result in 1.4
22// bits per sample average (not counting sign bit). However, there is a
23// very simple encoding that is over 99% efficient with this data and
24// results in about 1.22 bits per sample.
25
26#include "wavpack.h"
27
28#include <string.h>
29
30//////////////////////////////// local macros /////////////////////////////////
31
32#define LIMIT_ONES 16 // maximum consecutive 1s sent for "div" data
33
34// these control the time constant "slow_level" which is used for hybrid mode
35// that controls bitrate as a function of residual level (HYBRID_BITRATE).
36#define SLS 8
37#define SLO ((1 << (SLS - 1)))
38
39// these control the time constant of the 3 median level breakpoints
40#define DIV0 128 // 5/7 of samples
41#define DIV1 64 // 10/49 of samples
42#define DIV2 32 // 20/343 of samples
43
44// this macro retrieves the specified median breakpoint (without frac; min = 1)
45#define GET_MED(med) (((c->median [med]) >> 4) + 1)
46
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.
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.
51
52#define INC_MED0() (c->median [0] += ((c->median [0] + DIV0) / DIV0) * 5)
53#define DEC_MED0() (c->median [0] -= ((c->median [0] + (DIV0-2)) / DIV0) * 2)
54#define INC_MED1() (c->median [1] += ((c->median [1] + DIV1) / DIV1) * 5)
55#define DEC_MED1() (c->median [1] -= ((c->median [1] + (DIV1-2)) / DIV1) * 2)
56#define INC_MED2() (c->median [2] += ((c->median [2] + DIV2) / DIV2) * 5)
57#define DEC_MED2() (c->median [2] -= ((c->median [2] + (DIV2-2)) / DIV2) * 2)
58
59#define count_bits(av) ( \
60 (av) < (1 << 8) ? nbits_table [av] : \
61 ( \
62 (av) < (1L << 16) ? nbits_table [(av) >> 8] + 8 : \
63 ((av) < (1L << 24) ? nbits_table [(av) >> 16] + 16 : nbits_table [(av) >> 24] + 24) \
64 ) \
65)
66
67///////////////////////////// local table storage ////////////////////////////
68
69static const char nbits_table [] ICONST_ATTR = {
70 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 0 - 15
71 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 16 - 31
72 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 32 - 47
73 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 48 - 63
74 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 64 - 79
75 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 80 - 95
76 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 96 - 111
77 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 112 - 127
78 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 128 - 143
79 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 144 - 159
80 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 160 - 175
81 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 176 - 191
82 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 192 - 207
83 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 208 - 223
84 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 224 - 239
85 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 // 240 - 255
86};
87
88static const uchar log2_table [] = {
89 0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15,
90 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a,
91 0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e,
92 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
93 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
94 0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75,
95 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
96 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
97 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
98 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2,
99 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0,
100 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce,
101 0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb,
102 0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7,
103 0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4,
104 0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff
105};
106
107static const uchar exp2_table [] ICONST_ATTR = {
108 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
109 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
110 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
111 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
112 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d,
113 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
114 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
115 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
116 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
117 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a,
118 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
119 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
120 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
121 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
122 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9,
123 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
124};
125
126static const char ones_count_table [] ICONST_ATTR = {
127 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
128 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
129 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
130 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
131 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
132 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
133 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
134 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8
135};
136
137///////////////////////////// executable code ////////////////////////////////
138
139void init_words (WavpackStream *wps)
140{
141 CLEAR (wps->w);
142}
143
144static int mylog2 (uint32_t avalue);
145
146// Read the median log2 values from the specifed metadata structure, convert
147// them back to 32-bit unsigned values and store them. If length is not
148// exactly correct then we flag and return an error.
149
150int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
151{
152 uchar *byteptr = wpmd->data;
153
154 if (wpmd->byte_length != ((wps->wphdr.flags & MONO_DATA) ? 6 : 12))
155 return FALSE;
156
157 wps->w.c [0].median [0] = exp2s (byteptr [0] + (byteptr [1] << 8));
158 wps->w.c [0].median [1] = exp2s (byteptr [2] + (byteptr [3] << 8));
159 wps->w.c [0].median [2] = exp2s (byteptr [4] + (byteptr [5] << 8));
160
161 if (!(wps->wphdr.flags & MONO_DATA)) {
162 wps->w.c [1].median [0] = exp2s (byteptr [6] + (byteptr [7] << 8));
163 wps->w.c [1].median [1] = exp2s (byteptr [8] + (byteptr [9] << 8));
164 wps->w.c [1].median [2] = exp2s (byteptr [10] + (byteptr [11] << 8));
165 }
166
167 return TRUE;
168}
169
170// Allocates the correct space in the metadata structure and writes the
171// current median values to it. Values are converted from 32-bit unsigned
172// to our internal 16-bit mylog2 values, and read_entropy_vars () is called
173// to read the values back because we must compensate for the loss through
174// the log function.
175
176void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
177{
178 uchar *byteptr;
179 int temp;
180
181 byteptr = wpmd->data = wpmd->temp_data;
182 wpmd->id = ID_ENTROPY_VARS;
183
184 *byteptr++ = temp = mylog2 (wps->w.c [0].median [0]);
185 *byteptr++ = temp >> 8;
186 *byteptr++ = temp = mylog2 (wps->w.c [0].median [1]);
187 *byteptr++ = temp >> 8;
188 *byteptr++ = temp = mylog2 (wps->w.c [0].median [2]);
189 *byteptr++ = temp >> 8;
190
191 if (!(wps->wphdr.flags & MONO_FLAG)) {
192 *byteptr++ = temp = mylog2 (wps->w.c [1].median [0]);
193 *byteptr++ = temp >> 8;
194 *byteptr++ = temp = mylog2 (wps->w.c [1].median [1]);
195 *byteptr++ = temp >> 8;
196 *byteptr++ = temp = mylog2 (wps->w.c [1].median [2]);
197 *byteptr++ = temp >> 8;
198 }
199
200 wpmd->byte_length = byteptr - (uchar *) wpmd->data;
201 read_entropy_vars (wps, wpmd);
202}
203
204// Read the hybrid related values from the specifed metadata structure, convert
205// them back to their internal formats and store them. The extended profile
206// stuff is not implemented yet, so return an error if we get more data than
207// we know what to do with.
208
209int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd)
210{
211 uchar *byteptr = wpmd->data;
212 uchar *endptr = byteptr + wpmd->byte_length;
213
214 if (wps->wphdr.flags & HYBRID_BITRATE) {
215 wps->w.c [0].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
216 byteptr += 2;
217
218 if (!(wps->wphdr.flags & MONO_DATA)) {
219 wps->w.c [1].slow_level = exp2s (byteptr [0] + (byteptr [1] << 8));
220 byteptr += 2;
221 }
222 }
223
224 wps->w.bitrate_acc [0] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
225 byteptr += 2;
226
227 if (!(wps->wphdr.flags & MONO_DATA)) {
228 wps->w.bitrate_acc [1] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16;
229 byteptr += 2;
230 }
231
232 if (byteptr < endptr) {
233 wps->w.bitrate_delta [0] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
234 byteptr += 2;
235
236 if (!(wps->wphdr.flags & MONO_DATA)) {
237 wps->w.bitrate_delta [1] = exp2s ((short)(byteptr [0] + (byteptr [1] << 8)));
238 byteptr += 2;
239 }
240
241 if (byteptr < endptr)
242 return FALSE;
243 }
244 else
245 wps->w.bitrate_delta [0] = wps->w.bitrate_delta [1] = 0;
246
247 return TRUE;
248}
249
250// This function is called during both encoding and decoding of hybrid data to
251// update the "error_limit" variable which determines the maximum sample error
252// allowed in the main bitstream. In the HYBRID_BITRATE mode (which is the only
253// currently implemented) this is calculated from the slow_level values and the
254// bitrate accumulators. Note that the bitrate accumulators can be changing.
255
256static void update_error_limit (struct words_data *w, uint32_t flags)
257{
258 int bitrate_0 = (w->bitrate_acc [0] += w->bitrate_delta [0]) >> 16;
259
260 if (flags & MONO_DATA) {
261 if (flags & HYBRID_BITRATE) {
262 int slow_log_0 = (w->c [0].slow_level + SLO) >> SLS;
263
264 if (slow_log_0 - bitrate_0 > -0x100)
265 w->c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100);
266 else
267 w->c [0].error_limit = 0;
268 }
269 else
270 w->c [0].error_limit = exp2s (bitrate_0);
271 }
272 else {
273 int bitrate_1 = (w->bitrate_acc [1] += w->bitrate_delta [1]) >> 16;
274
275 if (flags & HYBRID_BITRATE) {
276 int slow_log_0 = (w->c [0].slow_level + SLO) >> SLS;
277 int slow_log_1 = (w->c [1].slow_level + SLO) >> SLS;
278
279 if (flags & HYBRID_BALANCE) {
280 int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1;
281
282 if (balance > bitrate_0) {
283 bitrate_1 = bitrate_0 * 2;
284 bitrate_0 = 0;
285 }
286 else if (-balance > bitrate_0) {
287 bitrate_0 = bitrate_0 * 2;
288 bitrate_1 = 0;
289 }
290 else {
291 bitrate_1 = bitrate_0 + balance;
292 bitrate_0 = bitrate_0 - balance;
293 }
294 }
295
296 if (slow_log_0 - bitrate_0 > -0x100)
297 w->c [0].error_limit = exp2s (slow_log_0 - bitrate_0 + 0x100);
298 else
299 w->c [0].error_limit = 0;
300
301 if (slow_log_1 - bitrate_1 > -0x100)
302 w->c [1].error_limit = exp2s (slow_log_1 - bitrate_1 + 0x100);
303 else
304 w->c [1].error_limit = 0;
305 }
306 else {
307 w->c [0].error_limit = exp2s (bitrate_0);
308 w->c [1].error_limit = exp2s (bitrate_1);
309 }
310 }
311}
312
313static uint32_t read_code (Bitstream *bs, uint32_t maxcode);
314
315// Read the next word from the bitstream "wvbits" and return the value. This
316// function can be used for hybrid or lossless streams, but since an
317// optimized version is available for lossless this function would normally
318// be used for hybrid only. If a hybrid lossless stream is being read then
319// the "correction" offset is written at the specified pointer. A return value
320// of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or
321// some other error occurred.
322
323int32_t get_words (int32_t *buffer, int nsamples, uint32_t flags,
324 struct words_data *w, Bitstream *bs)
325{
326 register struct entropy_data *c = w->c;
327 int csamples;
328
329 if (!(flags & MONO_DATA))
330 nsamples *= 2;
331
332 for (csamples = 0; csamples < nsamples; ++csamples) {
333 uint32_t ones_count, low, mid, high;
334
335 if (!(flags & MONO_DATA))
336 c = w->c + (csamples & 1);
337
338 if (!(w->c [0].median [0] & ~1) && !w->holding_zero && !w->holding_one && !(w->c [1].median [0] & ~1)) {
339 uint32_t mask;
340 int cbits;
341
342 if (w->zeros_acc) {
343 if (--w->zeros_acc) {
344 c->slow_level -= (c->slow_level + SLO) >> SLS;
345 *buffer++ = 0;
346 continue;
347 }
348 }
349 else {
350 for (cbits = 0; cbits < 33 && getbit (bs); ++cbits);
351
352 if (cbits == 33)
353 break;
354
355 if (cbits < 2)
356 w->zeros_acc = cbits;
357 else {
358 for (mask = 1, w->zeros_acc = 0; --cbits; mask <<= 1)
359 if (getbit (bs))
360 w->zeros_acc |= mask;
361
362 w->zeros_acc |= mask;
363 }
364
365 if (w->zeros_acc) {
366 c->slow_level -= (c->slow_level + SLO) >> SLS;
367 CLEAR (w->c [0].median);
368 CLEAR (w->c [1].median);
369 *buffer++ = 0;
370 continue;
371 }
372 }
373 }
374
375 if (w->holding_zero)
376 ones_count = w->holding_zero = 0;
377 else {
378 int next8;
379
380 if (bs->bc < 8) {
381 if (++(bs->ptr) == bs->end)
382 bs->wrap (bs);
383
384 next8 = (bs->sr |= *(bs->ptr) << bs->bc) & 0xff;
385 bs->bc += 8;
386 }
387 else
388 next8 = bs->sr & 0xff;
389
390 if (next8 == 0xff) {
391 bs->bc -= 8;
392 bs->sr >>= 8;
393
394 for (ones_count = 8; ones_count < (LIMIT_ONES + 1) && getbit (bs); ++ones_count);
395
396 if (ones_count == (LIMIT_ONES + 1))
397 break;
398
399 if (ones_count == LIMIT_ONES) {
400 uint32_t mask;
401 int cbits;
402
403 for (cbits = 0; cbits < 33 && getbit (bs); ++cbits);
404
405 if (cbits == 33)
406 break;
407
408 if (cbits < 2)
409 ones_count = cbits;
410 else {
411 for (mask = 1, ones_count = 0; --cbits; mask <<= 1)
412 if (getbit (bs))
413 ones_count |= mask;
414
415 ones_count |= mask;
416 }
417
418 ones_count += LIMIT_ONES;
419 }
420 }
421 else {
422 bs->bc -= (ones_count = ones_count_table [next8]) + 1;
423 bs->sr >>= ones_count + 1;
424 }
425
426 if (w->holding_one) {
427 w->holding_one = ones_count & 1;
428 ones_count = (ones_count >> 1) + 1;
429 }
430 else {
431 w->holding_one = ones_count & 1;
432 ones_count >>= 1;
433 }
434
435 w->holding_zero = ~w->holding_one & 1;
436 }
437
438 if ((flags & HYBRID_FLAG) && ((flags & MONO_DATA) || !(csamples & 1)))
439 update_error_limit (w, flags);
440
441 if (ones_count == 0) {
442 low = 0;
443 high = GET_MED (0) - 1;
444 DEC_MED0 ();
445 }
446 else {
447 low = GET_MED (0);
448 INC_MED0 ();
449
450 if (ones_count == 1) {
451 high = low + GET_MED (1) - 1;
452 DEC_MED1 ();
453 }
454 else {
455 low += GET_MED (1);
456 INC_MED1 ();
457
458 if (ones_count == 2) {
459 high = low + GET_MED (2) - 1;
460 DEC_MED2 ();
461 }
462 else {
463 low += (ones_count - 2) * GET_MED (2);
464 high = low + GET_MED (2) - 1;
465 INC_MED2 ();
466 }
467 }
468 }
469
470 mid = (high + low + 1) >> 1;
471
472 if (!c->error_limit)
473 mid = read_code (bs, high - low) + low;
474 else while (high - low > c->error_limit) {
475 if (getbit (bs))
476 mid = (high + (low = mid) + 1) >> 1;
477 else
478 mid = ((high = mid - 1) + low + 1) >> 1;
479 }
480
481 *buffer++ = getbit (bs) ? ~mid : mid;
482
483 if (flags & HYBRID_BITRATE)
484 c->slow_level = c->slow_level - ((c->slow_level + SLO) >> SLS) + mylog2 (mid);
485 }
486
487 return (flags & MONO_DATA) ? csamples : (csamples / 2);
488}
489
490// Read a single unsigned value from the specified bitstream with a value
491// from 0 to maxcode. If there are exactly a power of two number of possible
492// codes then this will read a fixed number of bits; otherwise it reads the
493// minimum number of bits and then determines whether another bit is needed
494// to define the code.
495
496static uint32_t read_code (Bitstream *bs, uint32_t maxcode)
497{
498 int bitcount = count_bits (maxcode);
499 uint32_t extras = (1L << bitcount) - maxcode - 1, code;
500
501 if (!bitcount)
502 return 0;
503
504 getbits (&code, bitcount - 1, bs);
505 code &= (1L << (bitcount - 1)) - 1;
506
507 if (code >= extras) {
508 code = (code << 1) - extras;
509
510 if (getbit (bs))
511 ++code;
512 }
513
514 return code;
515}
516
517void send_words (int32_t *buffer, int nsamples, uint32_t flags,
518 struct words_data *w, Bitstream *bs)
519{
520 register struct entropy_data *c = w->c;
521
522 if (!(flags & MONO_FLAG))
523 nsamples *= 2;
524
525 while (nsamples--) {
526 int32_t value = *buffer++;
527 int sign = (value < 0) ? 1 : 0;
528 uint32_t ones_count, low, high;
529
530 if (!(flags & MONO_FLAG))
531 c = w->c + (~nsamples & 1);
532
533 if (!(w->c [0].median [0] & ~1) && !w->holding_zero && !(w->c [1].median [0] & ~1)) {
534 if (w->zeros_acc) {
535 if (value)
536 flush_word (w, bs);
537 else {
538 w->zeros_acc++;
539 continue;
540 }
541 }
542 else if (value) {
543 putbit_0 (bs);
544 }
545 else {
546 CLEAR (w->c [0].median);
547 CLEAR (w->c [1].median);
548 w->zeros_acc = 1;
549 continue;
550 }
551 }
552
553 if (sign)
554 value = ~value;
555
556 if ((uint32_t) value < GET_MED (0)) {
557 ones_count = low = 0;
558 high = GET_MED (0) - 1;
559 DEC_MED0 ();
560 }
561 else {
562 low = GET_MED (0);
563 INC_MED0 ();
564
565 if (value - low < GET_MED (1)) {
566 ones_count = 1;
567 high = low + GET_MED (1) - 1;
568 DEC_MED1 ();
569 }
570 else {
571 low += GET_MED (1);
572 INC_MED1 ();
573
574 if (value - low < GET_MED (2)) {
575 ones_count = 2;
576 high = low + GET_MED (2) - 1;
577 DEC_MED2 ();
578 }
579 else {
580 ones_count = 2 + (value - low) / GET_MED (2);
581 low += (ones_count - 2) * GET_MED (2);
582 high = low + GET_MED (2) - 1;
583 INC_MED2 ();
584 }
585 }
586 }
587
588 if (w->holding_zero) {
589 if (ones_count)
590 w->holding_one++;
591
592 flush_word (w, bs);
593
594 if (ones_count) {
595 w->holding_zero = 1;
596 ones_count--;
597 }
598 else
599 w->holding_zero = 0;
600 }
601 else
602 w->holding_zero = 1;
603
604 w->holding_one = ones_count * 2;
605
606 if (high != low) {
607 uint32_t maxcode = high - low, code = value - low;
608 int bitcount = count_bits (maxcode);
609 uint32_t extras = (1L << bitcount) - maxcode - 1;
610
611 if (code < extras) {
612 w->pend_data |= code << w->pend_count;
613 w->pend_count += bitcount - 1;
614 }
615 else {
616 w->pend_data |= ((code + extras) >> 1) << w->pend_count;
617 w->pend_count += bitcount - 1;
618 w->pend_data |= ((code + extras) & 1) << w->pend_count++;
619 }
620 }
621
622 w->pend_data |= ((int32_t) sign << w->pend_count++);
623
624 if (!w->holding_zero)
625 flush_word (w, bs);
626 }
627}
628
629// Used by send_word() and send_word_lossless() to actually send most the
630// accumulated data onto the bitstream. This is also called directly from
631// clients when all words have been sent.
632
633void flush_word (struct words_data *w, Bitstream *bs)
634{
635 int cbits;
636
637 if (w->zeros_acc) {
638 cbits = count_bits (w->zeros_acc);
639
640 while (cbits--) {
641 putbit_1 (bs);
642 }
643
644 putbit_0 (bs);
645
646 while (w->zeros_acc > 1) {
647 putbit (w->zeros_acc & 1, bs);
648 w->zeros_acc >>= 1;
649 }
650
651 w->zeros_acc = 0;
652 }
653
654 if (w->holding_one) {
655 if (w->holding_one >= LIMIT_ONES) {
656 putbits ((1L << LIMIT_ONES) - 1, LIMIT_ONES + 1, bs);
657 w->holding_one -= LIMIT_ONES;
658 cbits = count_bits (w->holding_one);
659
660 while (cbits--) {
661 putbit_1 (bs);
662 }
663
664 putbit_0 (bs);
665
666 while (w->holding_one > 1) {
667 putbit (w->holding_one & 1, bs);
668 w->holding_one >>= 1;
669 }
670
671 w->holding_zero = 0;
672 }
673 else
674 putbits ((1L << w->holding_one) - 1, w->holding_one, bs);
675
676 w->holding_one = 0;
677 }
678
679 if (w->holding_zero) {
680 putbit_0 (bs);
681 w->holding_zero = 0;
682 }
683
684 if (w->pend_count) {
685
686 while (w->pend_count > 24) {
687 putbit (w->pend_data & 1, bs);
688 w->pend_data >>= 1;
689 w->pend_count--;
690 }
691
692 putbits (w->pend_data, w->pend_count, bs);
693 w->pend_data = w->pend_count = 0;
694 }
695}
696
697// The concept of a base 2 logarithm is used in many parts of WavPack. It is
698// a way of sufficiently accurately representing 32-bit signed and unsigned
699// values storing only 16 bits (actually fewer). It is also used in the hybrid
700// mode for quickly comparing the relative magnitude of large values (i.e.
701// division) and providing smooth exponentials using only addition.
702
703// These are not strict logarithms in that they become linear around zero and
704// can therefore represent both zero and negative values. They have 8 bits
705// of precision and in "roundtrip" conversions the total error never exceeds 1
706// part in 225 except for the cases of +/-115 and +/-195 (which error by 1).
707
708
709// This function returns the log2 for the specified 32-bit unsigned value.
710// The maximum value allowed is about 0xff800000 and returns 8447.
711
712static int mylog2 (uint32_t avalue)
713{
714 int dbits;
715
716 if ((avalue += avalue >> 9) < (1 << 8)) {
717 dbits = nbits_table [avalue];
718 return (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff];
719 }
720 else {
721 if (avalue < (1L << 16))
722 dbits = nbits_table [avalue >> 8] + 8;
723 else if (avalue < (1L << 24))
724 dbits = nbits_table [avalue >> 16] + 16;
725 else
726 dbits = nbits_table [avalue >> 24] + 24;
727
728 return (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff];
729 }
730}
731
732// This function returns the log2 for the specified 32-bit signed value.
733// All input values are valid and the return values are in the range of
734// +/- 8192.
735
736int log2s (int32_t value)
737{
738 return (value < 0) ? -mylog2 (-value) : mylog2 (value);
739}
740
741// This function returns the original integer represented by the supplied
742// logarithm (at least within the provided accuracy). The log is signed,
743// but since a full 32-bit value is returned this can be used for unsigned
744// conversions as well (i.e. the input range is -8192 to +8447).
745
746int32_t exp2s (int log)
747{
748 uint32_t value;
749
750 if (log < 0)
751 return -exp2s (-log);
752
753 value = exp2_table [log & 0xff] | 0x100;
754
755 if ((log >>= 8) <= 9)
756 return value >> (9 - log);
757 else
758 return value << (log - 9);
759}
760
761// These two functions convert internal weights (which are normally +/-1024)
762// to and from an 8-bit signed character version for storage in metadata. The
763// weights are clipped here in the case that they are outside that range.
764
765signed char store_weight (int weight)
766{
767 if (weight > 1024)
768 weight = 1024;
769 else if (weight < -1024)
770 weight = -1024;
771
772 if (weight > 0)
773 weight -= (weight + 64) >> 7;
774
775 return (weight + 4) >> 3;
776}
777
778int restore_weight (signed char weight)
779{
780 int result;
781
782 if ((result = (int) weight << 3) > 0)
783 result += (result + 64) >> 7;
784
785 return result;
786}
diff --git a/lib/rbcodec/codecs/libwavpack/wputils.c b/lib/rbcodec/codecs/libwavpack/wputils.c
new file mode 100644
index 0000000000..b0ccd3ba83
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/wputils.c
@@ -0,0 +1,555 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// wputils.c
10
11// This module provides a high-level interface for decoding WavPack 4.0 audio
12// streams and files. WavPack data is read with a stream reading callback. No
13// direct seeking is provided for, but it is possible to start decoding
14// anywhere in a WavPack stream. In this case, WavPack will be able to provide
15// the sample-accurate position when it synchs with the data and begins
16// decoding.
17
18#include "wavpack.h"
19
20#include <string.h>
21
22static void strcpy_loc (char *dst, char *src) { while ((*dst++ = *src++) != 0); }
23
24///////////////////////////// local table storage ////////////////////////////
25
26const uint32_t sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050,
27 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 };
28
29///////////////////////////// executable code ////////////////////////////////
30
31static uint32_t read_next_header (read_stream infile, WavpackHeader *wphdr);
32
33// This function reads data from the specified stream in search of a valid
34// WavPack 4.0 audio block. If this fails in 1 megabyte (or an invalid or
35// unsupported WavPack block is encountered) then an appropriate message is
36// copied to "error" and NULL is returned, otherwise a pointer to a
37// WavpackContext structure is returned (which is used to call all other
38// functions in this module). This can be initiated at the beginning of a
39// WavPack file, or anywhere inside a WavPack file. To determine the exact
40// position within the file use WavpackGetSampleIndex(). For demonstration
41// purposes this uses a single static copy of the WavpackContext structure,
42// so obviously it cannot be used for more than one file at a time. Also,
43// this function will not handle "correction" files, plays only the first
44// two channels of multi-channel files, and is limited in resolution in some
45// large integer or floating point files (but always provides at least 24 bits
46// of resolution).
47
48static WavpackContext wpc IBSS_ATTR;
49
50WavpackContext *WavpackOpenFileInput (read_stream infile, char *error)
51{
52 WavpackStream *wps = &wpc.stream;
53 uint32_t bcount;
54
55 CLEAR (wpc);
56 wpc.infile = infile;
57 wpc.total_samples = (uint32_t) -1;
58 wpc.norm_offset = 0;
59 wpc.open_flags = 0;
60
61 // open the source file for reading and store the size
62
63 while (!wps->wphdr.block_samples) {
64
65 bcount = read_next_header (wpc.infile, &wps->wphdr);
66
67 if (bcount == (uint32_t) -1) {
68 strcpy_loc (error, "invalid WavPack file!");
69 return NULL;
70 }
71
72 wps->block_bytes_left = wps->wphdr.ckSize - 24;
73
74 if ((wps->wphdr.flags & UNKNOWN_FLAGS) || wps->wphdr.version < MIN_STREAM_VERS ||
75 wps->wphdr.version > MAX_STREAM_VERS) {
76 strcpy_loc (error, "invalid WavPack file!");
77 return NULL;
78 }
79
80 if (wps->wphdr.block_samples && wps->wphdr.total_samples != (uint32_t) -1)
81 wpc.total_samples = wps->wphdr.total_samples;
82
83 if (!unpack_init (&wpc)) {
84 strcpy_loc (error, wpc.error_message [0] ? wpc.error_message :
85 "invalid WavPack file!");
86
87 return NULL;
88 }
89 }
90
91 wpc.config.flags &= ~0xff;
92 wpc.config.flags |= wps->wphdr.flags & 0xff;
93 wpc.config.bytes_per_sample = (wps->wphdr.flags & BYTES_STORED) + 1;
94 wpc.config.float_norm_exp = wps->float_norm_exp;
95
96 wpc.config.bits_per_sample = (wpc.config.bytes_per_sample * 8) -
97 ((wps->wphdr.flags & SHIFT_MASK) >> SHIFT_LSB);
98
99 if (!wpc.config.sample_rate) {
100 if (!wps || !wps->wphdr.block_samples || (wps->wphdr.flags & SRATE_MASK) == SRATE_MASK)
101 wpc.config.sample_rate = 44100;
102 else
103 wpc.config.sample_rate = sample_rates [(wps->wphdr.flags & SRATE_MASK) >> SRATE_LSB];
104 }
105
106 if (!wpc.config.num_channels) {
107 wpc.config.num_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2;
108 wpc.config.channel_mask = 0x5 - wpc.config.num_channels;
109 }
110
111 if (!(wps->wphdr.flags & FINAL_BLOCK))
112 wpc.reduced_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2;
113
114 return &wpc;
115}
116
117// This function obtains general information about an open file and returns
118// a mask with the following bit values:
119
120// MODE_LOSSLESS: file is lossless (pure lossless only)
121// MODE_HYBRID: file is hybrid mode (lossy part only)
122// MODE_FLOAT: audio data is 32-bit ieee floating point
123// MODE_HIGH: file was created in "high" mode (information only)
124// MODE_FAST: file was created in "fast" mode (information only)
125
126int WavpackGetMode (WavpackContext *wpc)
127{
128 int mode = 0;
129
130 if (wpc) {
131 if (wpc->config.flags & CONFIG_HYBRID_FLAG)
132 mode |= MODE_HYBRID;
133 else if (!(wpc->config.flags & CONFIG_LOSSY_MODE))
134 mode |= MODE_LOSSLESS;
135
136 if (wpc->lossy_blocks)
137 mode &= ~MODE_LOSSLESS;
138
139 if (wpc->config.flags & CONFIG_FLOAT_DATA)
140 mode |= MODE_FLOAT;
141
142 if (wpc->config.flags & CONFIG_HIGH_FLAG)
143 mode |= MODE_HIGH;
144
145 if (wpc->config.flags & CONFIG_FAST_FLAG)
146 mode |= MODE_FAST;
147 }
148
149 return mode;
150}
151
152// Unpack the specified number of samples from the current file position.
153// Note that "samples" here refers to "complete" samples, which would be
154// 2 int32_t's for stereo files. The audio data is returned right-justified in
155// 32-bit int32_t's in the endian mode native to the executing processor. So,
156// if the original data was 16-bit, then the values returned would be
157// +/-32k. Floating point data can also be returned if the source was
158// floating point data (and this is normalized to +/-1.0). The actual number
159// of samples unpacked is returned, which should be equal to the number
160// requested unless the end of fle is encountered or an error occurs.
161
162uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples)
163{
164 WavpackStream *wps = &wpc->stream;
165 uint32_t bcount, samples_unpacked = 0, samples_to_unpack;
166 int num_channels = wpc->config.num_channels;
167
168 while (samples) {
169 if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) ||
170 wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples) {
171 bcount = read_next_header (wpc->infile, &wps->wphdr);
172
173 if (bcount == (uint32_t) -1)
174 break;
175
176 wps->block_bytes_left = wps->wphdr.ckSize - 24;
177
178 if (wps->wphdr.version < MIN_STREAM_VERS || wps->wphdr.version > MAX_STREAM_VERS) {
179 strcpy_loc (wpc->error_message, "invalid WavPack file!");
180 break;
181 }
182
183 if (!wps->wphdr.block_samples || wps->sample_index == wps->wphdr.block_index)
184 if (!unpack_init (wpc))
185 break;
186 }
187
188 if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) ||
189 wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples)
190 continue;
191
192 if (wps->sample_index < wps->wphdr.block_index) {
193 samples_to_unpack = wps->wphdr.block_index - wps->sample_index;
194
195 if (samples_to_unpack > samples)
196 samples_to_unpack = samples;
197
198 wps->sample_index += samples_to_unpack;
199 samples_unpacked += samples_to_unpack;
200 samples -= samples_to_unpack;
201
202 if (wpc->reduced_channels)
203 samples_to_unpack *= wpc->reduced_channels;
204 else
205 samples_to_unpack *= num_channels;
206
207 while (samples_to_unpack--)
208 *buffer++ = 0;
209
210 continue;
211 }
212
213 samples_to_unpack = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index;
214
215 if (samples_to_unpack > samples)
216 samples_to_unpack = samples;
217
218 unpack_samples (wpc, buffer, samples_to_unpack);
219
220 if (wpc->reduced_channels)
221 buffer += samples_to_unpack * wpc->reduced_channels;
222 else
223 buffer += samples_to_unpack * num_channels;
224
225 samples_unpacked += samples_to_unpack;
226 samples -= samples_to_unpack;
227
228 if (wps->sample_index == wps->wphdr.block_index + wps->wphdr.block_samples) {
229 if (check_crc_error (wpc))
230 wpc->crc_errors++;
231 }
232
233 if (wps->sample_index == wpc->total_samples)
234 break;
235 }
236
237 return samples_unpacked;
238}
239
240// Get total number of samples contained in the WavPack file, or -1 if unknown
241
242uint32_t WavpackGetNumSamples (WavpackContext *wpc)
243{
244 return wpc ? wpc->total_samples : (uint32_t) -1;
245}
246
247// Get the current sample index position, or -1 if unknown
248
249uint32_t WavpackGetSampleIndex (WavpackContext *wpc)
250{
251 if (wpc)
252 return wpc->stream.sample_index;
253
254 return (uint32_t) -1;
255}
256
257// Get the number of errors encountered so far
258
259int WavpackGetNumErrors (WavpackContext *wpc)
260{
261 return wpc ? wpc->crc_errors : 0;
262}
263
264// return TRUE if any uncorrected lossy blocks were actually written or read
265
266int WavpackLossyBlocks (WavpackContext *wpc)
267{
268 return wpc ? wpc->lossy_blocks : 0;
269}
270
271// Returns the sample rate of the specified WavPack file
272
273uint32_t WavpackGetSampleRate (WavpackContext *wpc)
274{
275 return wpc ? wpc->config.sample_rate : 44100;
276}
277
278// Returns the number of channels of the specified WavPack file. Note that
279// this is the actual number of channels contained in the file, but this
280// version can only decode the first two.
281
282int WavpackGetNumChannels (WavpackContext *wpc)
283{
284 return wpc ? wpc->config.num_channels : 2;
285}
286
287// Returns the actual number of valid bits per sample contained in the
288// original file, which may or may not be a multiple of 8. Floating data
289// always has 32 bits, integers may be from 1 to 32 bits each. When this
290// value is not a multiple of 8, then the "extra" bits are located in the
291// LSBs of the results. That is, values are right justified when unpacked
292// into int32_t's, but are left justified in the number of bytes used by the
293// original data.
294
295int WavpackGetBitsPerSample (WavpackContext *wpc)
296{
297 return wpc ? wpc->config.bits_per_sample : 16;
298}
299
300// Returns the number of bytes used for each sample (1 to 4) in the original
301// file. This is required information for the user of this module because the
302// audio data is returned in the LOWER bytes of the int32_t buffer and must be
303// left-shifted 8, 16, or 24 bits if normalized int32_t's are required.
304
305int WavpackGetBytesPerSample (WavpackContext *wpc)
306{
307 return wpc ? wpc->config.bytes_per_sample : 2;
308}
309
310// This function will return the actual number of channels decoded from the
311// file (which may or may not be less than the actual number of channels, but
312// will always be 1 or 2). Normally, this will be the front left and right
313// channels of a multi-channel file.
314
315int WavpackGetReducedChannels (WavpackContext *wpc)
316{
317 if (wpc)
318 return wpc->reduced_channels ? wpc->reduced_channels : wpc->config.num_channels;
319 else
320 return 2;
321}
322
323// Read from current file position until a valid 32-byte WavPack 4.0 header is
324// found and read into the specified pointer. The number of bytes skipped is
325// returned. If no WavPack header is found within 1 meg, then a -1 is returned
326// to indicate the error. No additional bytes are read past the header and it
327// is returned in the processor's native endian mode. Seeking is not required.
328
329static uint32_t read_next_header (read_stream infile, WavpackHeader *wphdr)
330{
331 char buffer [sizeof (*wphdr)], *sp = buffer + sizeof (*wphdr), *ep = sp;
332 uint32_t bytes_skipped = 0;
333 int bleft;
334
335 while (1) {
336 if (sp < ep) {
337 bleft = ep - sp;
338 memcpy (buffer, sp, bleft);
339 }
340 else
341 bleft = 0;
342
343 if (infile (buffer + bleft, sizeof (*wphdr) - bleft) != (int32_t) sizeof (*wphdr) - bleft)
344 return -1;
345
346 sp = buffer;
347
348 if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' &&
349 !(*++sp & 1) && sp [2] < 16 && !sp [3] && sp [5] == 4 &&
350 sp [4] >= (MIN_STREAM_VERS & 0xff) && sp [4] <= (MAX_STREAM_VERS & 0xff)) {
351 memcpy (wphdr, buffer, sizeof (*wphdr));
352 little_endian_to_native (wphdr, WavpackHeaderFormat);
353 return bytes_skipped;
354 }
355
356 while (sp < ep && *sp != 'w')
357 sp++;
358
359 if ((bytes_skipped += sp - buffer) > 1024 * 1024)
360 return -1;
361 }
362}
363
364// Open context for writing WavPack files. The returned context pointer is used
365// in all following calls to the library. A return value of NULL indicates
366// that memory could not be allocated for the context.
367
368WavpackContext *WavpackOpenFileOutput (void)
369{
370 CLEAR (wpc);
371 return &wpc;
372}
373
374// Set configuration for writing WavPack files. This must be done before
375// sending any actual samples, however it is okay to send wrapper or other
376// metadata before calling this. The "config" structure contains the following
377// required information:
378
379// config->bytes_per_sample see WavpackGetBytesPerSample() for info
380// config->bits_per_sample see WavpackGetBitsPerSample() for info
381// config->num_channels self evident
382// config->sample_rate self evident
383
384// In addition, the following fields and flags may be set:
385
386// config->flags:
387// --------------
388// o CONFIG_HYBRID_FLAG select hybrid mode (must set bitrate)
389// o CONFIG_JOINT_STEREO select joint stereo (must set override also)
390// o CONFIG_JOINT_OVERRIDE override default joint stereo selection
391// o CONFIG_HYBRID_SHAPE select hybrid noise shaping (set override &
392// shaping_weight != 0.0)
393// o CONFIG_SHAPE_OVERRIDE override default hybrid noise shaping
394// (set CONFIG_HYBRID_SHAPE and shaping_weight)
395// o CONFIG_FAST_FLAG "fast" compression mode
396// o CONFIG_HIGH_FLAG "high" compression mode
397// o CONFIG_BITRATE_KBPS hybrid bitrate is kbps, not bits / sample
398
399// config->bitrate hybrid bitrate in either bits/sample or kbps
400// config->shaping_weight hybrid noise shaping coefficient override
401// config->float_norm_exp select floating-point data (127 for +/-1.0)
402
403// If the number of samples to be written is known then it should be passed
404// here. If the duration is not known then pass -1. In the case that the size
405// is not known (or the writing is terminated early) then it is suggested that
406// the application retrieve the first block written and let the library update
407// the total samples indication. A function is provided to do this update and
408// it should be done to the "correction" file also. If this cannot be done
409// (because a pipe is being used, for instance) then a valid WavPack will still
410// be created, but when applications want to access that file they will have
411// to seek all the way to the end to determine the actual duration. Also, if
412// a RIFF header has been included then it should be updated as well or the
413// WavPack file will not be directly unpackable to a valid wav file (although
414// it will still be usable by itself). A return of FALSE indicates an error.
415
416int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples)
417{
418 WavpackStream *wps = &wpc->stream;
419 uint32_t flags = (config->bytes_per_sample - 1), shift = 0;
420 int num_chans = config->num_channels;
421 int i;
422
423 if ((wpc->config.flags & CONFIG_HYBRID_FLAG) ||
424 wpc->config.float_norm_exp ||
425 num_chans < 1 || num_chans > 2)
426 return FALSE;
427
428 wpc->total_samples = total_samples;
429 wpc->config.sample_rate = config->sample_rate;
430 wpc->config.num_channels = config->num_channels;
431 wpc->config.bits_per_sample = config->bits_per_sample;
432 wpc->config.bytes_per_sample = config->bytes_per_sample;
433 wpc->config.flags = config->flags;
434
435 shift = (config->bytes_per_sample * 8) - config->bits_per_sample;
436
437 for (i = 0; i < 15; ++i)
438 if (wpc->config.sample_rate == sample_rates [i])
439 break;
440
441 flags |= i << SRATE_LSB;
442 flags |= shift << SHIFT_LSB;
443 flags |= CROSS_DECORR;
444
445 if (!(config->flags & CONFIG_JOINT_OVERRIDE) || (config->flags & CONFIG_JOINT_STEREO))
446 flags |= JOINT_STEREO;
447
448 flags |= INITIAL_BLOCK | FINAL_BLOCK;
449
450 if (num_chans == 1) {
451 flags &= ~(JOINT_STEREO | CROSS_DECORR | HYBRID_BALANCE);
452 flags |= MONO_FLAG;
453 }
454
455 flags &= ~MAG_MASK;
456 flags += (1 << MAG_LSB) * ((flags & BYTES_STORED) * 8 + 7);
457
458 memcpy (wps->wphdr.ckID, "wvpk", 4);
459 wps->wphdr.ckSize = sizeof (WavpackHeader) - 8;
460 wps->wphdr.total_samples = wpc->total_samples;
461 wps->wphdr.version = CUR_STREAM_VERS;
462 wps->wphdr.flags = flags;
463
464 pack_init (wpc);
465 return TRUE;
466}
467
468// Add wrapper (currently RIFF only) to WavPack blocks. This should be called
469// before sending any audio samples. If the exact contents of the RIFF header
470// are not known because, for example, the file duration is uncertain or
471// trailing chunks are possible, simply write a "dummy" header of the correct
472// length. When all data has been written it will be possible to read the
473// first block written and update the header directly. An example of this can
474// be found in the Audition filter.
475
476void WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount)
477{
478 wpc->wrapper_data = data;
479 wpc->wrapper_bytes = bcount;
480}
481
482// Start a WavPack block to be stored in the specified buffer. This must be
483// called before calling WavpackPackSamples(). Note that writing CANNOT wrap
484// in the buffer; the entire output block must fit in the buffer.
485
486int WavpackStartBlock (WavpackContext *wpc, uchar *begin, uchar *end)
487{
488 wpc->stream.blockbuff = begin;
489 wpc->stream.blockend = end;
490 return pack_start_block (wpc);
491}
492
493// Pack the specified samples. Samples must be stored in int32_ts in the native
494// endian format of the executing processor. The number of samples specified
495// indicates composite samples (sometimes called "frames"). So, the actual
496// number of data points would be this "sample_count" times the number of
497// channels. The caller must decide how many samples to place in each
498// WavPack block (1/2 second is common), but this function may be called as
499// many times as desired to build the final block (and performs the actual
500// compression during the call). A return of FALSE indicates an error.
501
502int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count)
503{
504 if (!sample_count || pack_samples (wpc, sample_buffer, sample_count))
505 return TRUE;
506
507 strcpy_loc (wpc->error_message, "output buffer overflowed!");
508 return FALSE;
509}
510
511// Finish the WavPack block being built, returning the total size of the
512// block in bytes. Note that the possible conversion of the WavPack header to
513// little-endian takes place here.
514
515uint32_t WavpackFinishBlock (WavpackContext *wpc)
516{
517 WavpackStream *wps = &wpc->stream;
518 uint32_t bcount;
519
520 pack_finish_block (wpc);
521 bcount = ((WavpackHeader *) wps->blockbuff)->ckSize + 8;
522 native_to_little_endian ((WavpackHeader *) wps->blockbuff, WavpackHeaderFormat);
523
524 return bcount;
525}
526
527// Given the pointer to the first block written (to either a .wv or .wvc file),
528// update the block with the actual number of samples written. This should
529// be done if WavpackSetConfiguration() was called with an incorrect number
530// of samples (or -1). It is the responsibility of the application to read and
531// rewrite the block. An example of this can be found in the Audition filter.
532
533void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block)
534{
535 little_endian_to_native (wpc, WavpackHeaderFormat);
536 ((WavpackHeader *) first_block)->total_samples = WavpackGetSampleIndex (wpc);
537 native_to_little_endian (wpc, WavpackHeaderFormat);
538}
539
540// Given the pointer to the first block written to a WavPack file, this
541// function returns the location of the stored RIFF header that was originally
542// written with WavpackAddWrapper(). This would normally be used to update
543// the wav header to indicate that a different number of samples was actually
544// written or if additional RIFF chunks are written at the end of the file.
545// It is the responsibility of the application to read and rewrite the block.
546// An example of this can be found in the Audition filter.
547
548void *WavpackGetWrapperLocation (void *first_block)
549{
550 if (((uchar *) first_block) [32] == ID_RIFF_HEADER)
551 return ((uchar *) first_block) + 34;
552 else
553 return NULL;
554}
555