summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libatrac
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libatrac')
-rw-r--r--lib/rbcodec/codecs/libatrac/README.rockbox30
-rw-r--r--lib/rbcodec/codecs/libatrac/SOURCES8
-rw-r--r--lib/rbcodec/codecs/libatrac/atrac3.c1293
-rw-r--r--lib/rbcodec/codecs/libatrac/atrac3.h114
-rw-r--r--lib/rbcodec/codecs/libatrac/atrac3_arm.S172
-rw-r--r--lib/rbcodec/codecs/libatrac/atrac3_armv5e.S163
-rw-r--r--lib/rbcodec/codecs/libatrac/atrac3data.h148
-rw-r--r--lib/rbcodec/codecs/libatrac/atrac3data_fixed.h108
-rw-r--r--lib/rbcodec/codecs/libatrac/fixp_math.h111
-rw-r--r--lib/rbcodec/codecs/libatrac/libatrac.make18
10 files changed, 2165 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libatrac/README.rockbox b/lib/rbcodec/codecs/libatrac/README.rockbox
new file mode 100644
index 0000000000..30703a3e49
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/README.rockbox
@@ -0,0 +1,30 @@
1Library: libatrac
2Imported by : Mohamed Tarek
3Import date : 10-August-2009
4
5LICENSING INFORMATION
6
7ffmpeg is licensed under the Lesser GNU General Public License.
8
9IMPORT DETAILS
10
11The decoder is based on ffmpeg-svn r18110 : Mar 21 2009.
12Some changes were done on in order to use static VLC tables
13according to this commit :
14http://git.ffmpeg.org/?p=ffmpeg;a=commit;h=4c20cf13a166577d93f5b2b0abb4609c60104d33
15
16The decoder had been modified to use fixed-point arithmetic.
17
18TESTING
19
20The test program should compile in any Unix-like environment using the
21command "make -f Makefile.test".
22
23For ARM targets add -DCPU_ARM to CFLAGS in Makefile.test to make use of
24the asm ARM optimisations in rockbox's mdct library.
25
26For Big-endian targets, change -D"ROCKBOX_LITTLE_ENDIAN=1"
27to -D"ROCKBOX_BIG_ENDIAN=1" in Makefile.test.
28
29Running "./atractest file.rm" will decode the audio data to a WAV file
30called "output.wav" in the current directory.
diff --git a/lib/rbcodec/codecs/libatrac/SOURCES b/lib/rbcodec/codecs/libatrac/SOURCES
new file mode 100644
index 0000000000..85f011cb87
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/SOURCES
@@ -0,0 +1,8 @@
1atrac3.c
2#if defined(CPU_ARM)
3atrac3_arm.S
4#if (ARM_ARCH >= 5)
5atrac3_armv5e.S
6#endif
7#endif
8
diff --git a/lib/rbcodec/codecs/libatrac/atrac3.c b/lib/rbcodec/codecs/libatrac/atrac3.c
new file mode 100644
index 0000000000..bb52dd4cf0
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/atrac3.c
@@ -0,0 +1,1293 @@
1/*
2 * Atrac 3 compatible decoder
3 * Copyright (c) 2006-2008 Maxim Poliakovski
4 * Copyright (c) 2006-2008 Benjamin Larsson
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/**
24 * @file libavcodec/atrac3.c
25 * Atrac 3 compatible decoder.
26 * This decoder handles Sony's ATRAC3 data.
27 *
28 * Container formats used to store atrac 3 data:
29 * RealMedia (.rm), RIFF WAV (.wav, .at3), Sony OpenMG (.oma, .aa3).
30 *
31 * To use this decoder, a calling application must supply the extradata
32 * bytes provided in the containers above.
33 */
34
35#include <math.h>
36#include <stddef.h>
37#include <stdio.h>
38
39#include "atrac3.h"
40#include "atrac3data.h"
41#include "atrac3data_fixed.h"
42#include "fixp_math.h"
43
44#define JOINT_STEREO 0x12
45#define STEREO 0x2
46
47#ifdef ROCKBOX
48#undef DEBUGF
49#define DEBUGF(...)
50#endif /* ROCKBOX */
51
52/* FFMAX/MIN/SWAP and av_clip were taken from libavutil/common.h */
53#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
54#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
55#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
56
57#if defined(CPU_ARM) && (ARM_ARCH >= 5)
58 #define QMFWIN_TYPE int16_t /* ARMv5e+ uses 32x16 multiplication */
59#else
60 #define QMFWIN_TYPE int32_t
61#endif
62
63static VLC spectral_coeff_tab[7] IBSS_ATTR_LARGE_IRAM;
64static QMFWIN_TYPE qmf_window[48] IBSS_ATTR MEM_ALIGN_ATTR;
65static int32_t atrac3_spectrum [2][1024] IBSS_ATTR MEM_ALIGN_ATTR;
66static int32_t atrac3_IMDCT_buf[2][ 512] IBSS_ATTR MEM_ALIGN_ATTR;
67static int32_t atrac3_prevFrame[2][1024] IBSS_ATTR MEM_ALIGN_ATTR;
68static channel_unit channel_units[2] IBSS_ATTR_LARGE_IRAM;
69static VLC_TYPE atrac3_vlc_table[4096][2] IBSS_ATTR_LARGE_IRAM;
70static int vlcs_initialized = 0;
71
72
73
74/**
75 * Matrixing within quadrature mirror synthesis filter.
76 *
77 * @param p3 output buffer
78 * @param inlo lower part of spectrum
79 * @param inhi higher part of spectrum
80 * @param nIn size of spectrum buffer
81 */
82
83#if defined(CPU_ARM)
84 extern void
85 atrac3_iqmf_matrixing(int32_t *p3,
86 int32_t *inlo,
87 int32_t *inhi,
88 unsigned int nIn);
89#else
90 static inline void
91 atrac3_iqmf_matrixing(int32_t *p3,
92 int32_t *inlo,
93 int32_t *inhi,
94 unsigned int nIn)
95 {
96 uint32_t i;
97 for(i=0; i<nIn; i+=2){
98 p3[2*i+0] = inlo[i ] + inhi[i ];
99 p3[2*i+1] = inlo[i ] - inhi[i ];
100 p3[2*i+2] = inlo[i+1] + inhi[i+1];
101 p3[2*i+3] = inlo[i+1] - inhi[i+1];
102 }
103 }
104#endif
105
106
107/**
108 * Matrixing within quadrature mirror synthesis filter.
109 *
110 * @param out output buffer
111 * @param in input buffer
112 * @param win windowing coefficients
113 * @param nIn size of spectrum buffer
114 * Reference implementation:
115 *
116 * for (j = nIn; j != 0; j--) {
117 * s1 = fixmul32(in[0], win[0]);
118 * s2 = fixmul32(in[1], win[1]);
119 * for (i = 2; i < 48; i += 2) {
120 * s1 += fixmul31(in[i ], win[i ]);
121 * s2 += fixmul31(in[i+1], win[i+1]);
122 * }
123 * out[0] = s2;
124 * out[1] = s1;
125 * in += 2;
126 * out += 2;
127 * }
128 */
129
130#if defined(CPU_ARM) && (ARM_ARCH >= 5)
131 extern void
132 atrac3_iqmf_dewindowing_armv5e(int32_t *out,
133 int32_t *in,
134 int16_t *win,
135 unsigned int nIn);
136 static inline void
137 atrac3_iqmf_dewindowing(int32_t *out,
138 int32_t *in,
139 int16_t *win,
140 unsigned int nIn)
141 {
142 atrac3_iqmf_dewindowing_armv5e(out, in, win, nIn);
143
144 }
145
146
147#elif defined(CPU_ARM)
148 extern void
149 atrac3_iqmf_dewindowing(int32_t *out,
150 int32_t *in,
151 int32_t *win,
152 unsigned int nIn);
153
154#elif defined (CPU_COLDFIRE)
155 #define MULTIPLY_ADD_BLOCK \
156 "movem.l (%[win]), %%d0-%%d7 \n\t" \
157 "lea.l (8*4, %[win]), %[win] \n\t" \
158 "mac.l %%d0, %%a5, (%[in])+, %%a5, %%acc0\n\t" \
159 "mac.l %%d1, %%a5, (%[in])+, %%a5, %%acc1\n\t" \
160 "mac.l %%d2, %%a5, (%[in])+, %%a5, %%acc0\n\t" \
161 "mac.l %%d3, %%a5, (%[in])+, %%a5, %%acc1\n\t" \
162 "mac.l %%d4, %%a5, (%[in])+, %%a5, %%acc0\n\t" \
163 "mac.l %%d5, %%a5, (%[in])+, %%a5, %%acc1\n\t" \
164 "mac.l %%d6, %%a5, (%[in])+, %%a5, %%acc0\n\t" \
165 "mac.l %%d7, %%a5, (%[in])+, %%a5, %%acc1\n\t" \
166
167
168 static inline void
169 atrac3_iqmf_dewindowing(int32_t *out,
170 int32_t *in,
171 int32_t *win,
172 unsigned int nIn)
173 {
174 int32_t j;
175 int32_t *_in, *_win;
176 for (j = nIn; j != 0; j--, in+=2, out+=2) {
177 _in = in;
178 _win = win;
179
180 asm volatile (
181 "move.l (%[in])+, %%a5 \n\t" /* preload frist in value */
182 MULTIPLY_ADD_BLOCK /* 0.. 7 */
183 MULTIPLY_ADD_BLOCK /* 8..15 */
184 MULTIPLY_ADD_BLOCK /* 16..23 */
185 MULTIPLY_ADD_BLOCK /* 24..31 */
186 MULTIPLY_ADD_BLOCK /* 32..39 */
187 /* 40..47 */
188 "movem.l (%[win]), %%d0-%%d7 \n\t"
189 "mac.l %%d0, %%a5, (%[in])+, %%a5, %%acc0 \n\t"
190 "mac.l %%d1, %%a5, (%[in])+, %%a5, %%acc1 \n\t"
191 "mac.l %%d2, %%a5, (%[in])+, %%a5, %%acc0 \n\t"
192 "mac.l %%d3, %%a5, (%[in])+, %%a5, %%acc1 \n\t"
193 "mac.l %%d4, %%a5, (%[in])+, %%a5, %%acc0 \n\t"
194 "mac.l %%d5, %%a5, (%[in])+, %%a5, %%acc1 \n\t"
195 "mac.l %%d6, %%a5, (%[in])+, %%a5, %%acc0 \n\t"
196 "mac.l %%d7, %%a5, %%acc1 \n\t"
197 "movclr.l %%acc0, %%d1 \n\t" /* s1 */
198 "movclr.l %%acc1, %%d0 \n\t" /* s2 */
199 "movem.l %%d0-%%d1, (%[out]) \n\t"
200 : [in] "+a" (_in), [win] "+a" (_win)
201 : [out] "a" (out)
202 : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5", "memory");
203 }
204 }
205#else
206 #define MULTIPLY_ADD_BLOCK(y1, y2, x, c, k) \
207 y1 += fixmul31(c[k], x[k]); k++; \
208 y2 += fixmul31(c[k], x[k]); k++; \
209 y1 += fixmul31(c[k], x[k]); k++; \
210 y2 += fixmul31(c[k], x[k]); k++; \
211 y1 += fixmul31(c[k], x[k]); k++; \
212 y2 += fixmul31(c[k], x[k]); k++; \
213 y1 += fixmul31(c[k], x[k]); k++; \
214 y2 += fixmul31(c[k], x[k]); k++;
215
216 static inline void
217 atrac3_iqmf_dewindowing(int32_t *out,
218 int32_t *in,
219 int32_t *win,
220 unsigned int nIn)
221 {
222 int32_t i, j, s1, s2;
223
224 for (j = nIn; j != 0; j--, in+=2, out+=2) {
225 s1 = s2 = i = 0;
226
227 MULTIPLY_ADD_BLOCK(s1, s2, in, win, i); /* 0.. 7 */
228 MULTIPLY_ADD_BLOCK(s1, s2, in, win, i); /* 8..15 */
229 MULTIPLY_ADD_BLOCK(s1, s2, in, win, i); /* 16..23 */
230 MULTIPLY_ADD_BLOCK(s1, s2, in, win, i); /* 24..31 */
231 MULTIPLY_ADD_BLOCK(s1, s2, in, win, i); /* 32..39 */
232 MULTIPLY_ADD_BLOCK(s1, s2, in, win, i); /* 40..47 */
233
234 out[0] = s2;
235 out[1] = s1;
236
237 }
238
239 }
240#endif
241
242
243/**
244 * IMDCT windowing.
245 *
246 * @param buffer sample buffer
247 * @param win window coefficients
248 */
249
250static inline void
251atrac3_imdct_windowing(int32_t *buffer,
252 const int32_t *win)
253{
254 int32_t i;
255 /* win[0..127] = win[511..384], win[128..383] = 1 */
256 for(i = 0; i<128; i++) {
257 buffer[ i] = fixmul31(win[i], buffer[ i]);
258 buffer[511-i] = fixmul31(win[i], buffer[511-i]);
259 }
260}
261
262
263/**
264 * Quadrature mirror synthesis filter.
265 *
266 * @param inlo lower part of spectrum
267 * @param inhi higher part of spectrum
268 * @param nIn size of spectrum buffer
269 * @param pOut out buffer
270 * @param delayBuf delayBuf buffer
271 * @param temp temp buffer
272 */
273
274static void iqmf (int32_t *inlo, int32_t *inhi, unsigned int nIn, int32_t *pOut, int32_t *delayBuf, int32_t *temp)
275{
276
277 /* Restore the delay buffer */
278 memcpy(temp, delayBuf, 46*sizeof(int32_t));
279
280 /* loop1: matrixing */
281 atrac3_iqmf_matrixing(temp + 46, inlo, inhi, nIn);
282
283 /* loop2: dewindowing */
284 atrac3_iqmf_dewindowing(pOut, temp, qmf_window, nIn);
285
286 /* Save the delay buffer */
287 memcpy(delayBuf, temp + (nIn << 1), 46*sizeof(int32_t));
288}
289
290
291/**
292 * Regular 512 points IMDCT without overlapping, with the exception of the swapping of odd bands
293 * caused by the reverse spectra of the QMF.
294 *
295 * @param pInput input
296 * @param pOutput output
297 * @param odd_band 1 if the band is an odd band
298 */
299
300static void IMLT(int32_t *pInput, int32_t *pOutput)
301{
302 /* Apply the imdct. */
303 ff_imdct_calc(9, pOutput, pInput);
304
305 /* Windowing. */
306 atrac3_imdct_windowing(pOutput, window_lookup);
307
308}
309
310
311/**
312 * Atrac 3 indata descrambling, only used for data coming from the rm container
313 *
314 * @param in pointer to 8 bit array of indata
315 * @param bits amount of bits
316 * @param out pointer to 8 bit array of outdata
317 */
318
319static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){
320 int i, off;
321 uint32_t c;
322 const uint32_t* buf;
323 uint32_t* obuf = (uint32_t*) out;
324
325#if ((defined(TEST) || defined(SIMULATOR)) && !defined(CPU_ARM))
326 off = 0; /* no check for memory alignment of inbuffer */
327#else
328 off = (intptr_t)inbuffer & 3;
329#endif /* TEST */
330 buf = (const uint32_t*) (inbuffer - off);
331
332 c = be2me_32((0x537F6103 >> (off*8)) | (0x537F6103 << (32-(off*8))));
333 bytes += 3 + off;
334 for (i = 0; i < bytes/4; i++)
335 obuf[i] = c ^ buf[i];
336
337 return off;
338}
339
340
341static void init_atrac3_transforms(void)
342{
343 int32_t s;
344 int i;
345
346 /* Generate the mdct window, for details see
347 * http://wiki.multimedia.cx/index.php?title=RealAudio_atrc#Windows */
348
349 /* mdct window had been generated and saved as a lookup table in atrac3data_fixed.h */
350
351 /* Generate the QMF window. */
352 for (i=0 ; i<24; i++) {
353 s = qmf_48tap_half_fix[i] << 1;
354 #if defined(CPU_ARM) && (ARM_ARCH >= 5)
355 qmf_window[i] = qmf_window[47-i] = (int16_t)((s+(1<<15))>>16);
356 #else
357 qmf_window[i] = qmf_window[47-i] = s;
358 #endif
359 }
360
361}
362
363
364/**
365 * Mantissa decoding
366 *
367 * @param gb the GetBit context
368 * @param selector what table is the output values coded with
369 * @param codingFlag constant length coding or variable length coding
370 * @param mantissas mantissa output table
371 * @param numCodes amount of values to get
372 */
373
374static void readQuantSpectralCoeffs (GetBitContext *gb, int selector, int codingFlag, int* mantissas, int numCodes)
375{
376 int numBits, cnt, code, huffSymb;
377
378 if (selector == 1)
379 numCodes /= 2;
380
381 if (codingFlag != 0) {
382 /* constant length coding (CLC) */
383 numBits = CLCLengthTab[selector];
384
385 if (selector > 1) {
386 for (cnt = 0; cnt < numCodes; cnt++) {
387 if (numBits)
388 code = get_sbits(gb, numBits);
389 else
390 code = 0;
391 mantissas[cnt] = code;
392 }
393 } else {
394 for (cnt = 0; cnt < numCodes; cnt++) {
395 if (numBits)
396 code = get_bits(gb, numBits); /* numBits is always 4 in this case */
397 else
398 code = 0;
399 mantissas[cnt*2] = seTab_0[code >> 2];
400 mantissas[cnt*2+1] = seTab_0[code & 3];
401 }
402 }
403 } else {
404 /* variable length coding (VLC) */
405 if (selector != 1) {
406 for (cnt = 0; cnt < numCodes; cnt++) {
407 huffSymb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, spectral_coeff_tab[selector-1].bits, 3);
408 huffSymb += 1;
409 code = huffSymb >> 1;
410 if (huffSymb & 1)
411 code = -code;
412 mantissas[cnt] = code;
413 }
414 } else {
415 for (cnt = 0; cnt < numCodes; cnt++) {
416 huffSymb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, spectral_coeff_tab[selector-1].bits, 3);
417 mantissas[cnt*2] = decTable1[huffSymb*2];
418 mantissas[cnt*2+1] = decTable1[huffSymb*2+1];
419 }
420 }
421 }
422}
423
424
425/**
426 * Requantize the spectrum.
427 *
428 * @param *mantissas pointer to mantissas for each spectral line
429 * @param pOut requantized band spectrum
430 * @param first first spectral line in subband
431 * @param last last spectral line in subband
432 * @param SF scalefactor for all spectral lines of this band
433 */
434
435static void inverseQuantizeSpectrum(int *mantissas, int32_t *pOut,
436 int32_t first, int32_t last, int32_t SF)
437{
438 int *pIn = mantissas;
439
440 /* Inverse quantize the coefficients. */
441 if((first/256) &1) {
442 /* Odd band - Reverse coefficients */
443 do {
444 pOut[last--] = fixmul16(*pIn++, SF);
445 pOut[last--] = fixmul16(*pIn++, SF);
446 pOut[last--] = fixmul16(*pIn++, SF);
447 pOut[last--] = fixmul16(*pIn++, SF);
448 pOut[last--] = fixmul16(*pIn++, SF);
449 pOut[last--] = fixmul16(*pIn++, SF);
450 pOut[last--] = fixmul16(*pIn++, SF);
451 pOut[last--] = fixmul16(*pIn++, SF);
452 } while (last>first);
453 } else {
454 /* Even band - Do not reverse coefficients */
455 do {
456 pOut[first++] = fixmul16(*pIn++, SF);
457 pOut[first++] = fixmul16(*pIn++, SF);
458 pOut[first++] = fixmul16(*pIn++, SF);
459 pOut[first++] = fixmul16(*pIn++, SF);
460 pOut[first++] = fixmul16(*pIn++, SF);
461 pOut[first++] = fixmul16(*pIn++, SF);
462 pOut[first++] = fixmul16(*pIn++, SF);
463 pOut[first++] = fixmul16(*pIn++, SF);
464 } while (first<last);
465 }
466}
467
468
469/**
470 * Restore the quantized band spectrum coefficients
471 *
472 * @param gb the GetBit context
473 * @param pOut decoded band spectrum
474 * @return outSubbands subband counter, fix for broken specification/files
475 */
476
477static int decodeSpectrum (GetBitContext *gb, int32_t *pOut) ICODE_ATTR_LARGE_IRAM;
478static int decodeSpectrum (GetBitContext *gb, int32_t *pOut)
479{
480 int numSubbands, codingMode, cnt, first, last, subbWidth;
481 int subband_vlc_index[32], SF_idxs[32];
482 int mantissas[128];
483 int32_t SF;
484
485 numSubbands = get_bits(gb, 5); /* number of coded subbands */
486 codingMode = get_bits1(gb); /* coding Mode: 0 - VLC/ 1-CLC */
487
488 /* Get the VLC selector table for the subbands, 0 means not coded. */
489 for (cnt = 0; cnt <= numSubbands; cnt++)
490 subband_vlc_index[cnt] = get_bits(gb, 3);
491
492 /* Read the scale factor indexes from the stream. */
493 for (cnt = 0; cnt <= numSubbands; cnt++) {
494 if (subband_vlc_index[cnt] != 0)
495 SF_idxs[cnt] = get_bits(gb, 6);
496 }
497
498 for (cnt = 0; cnt <= numSubbands; cnt++) {
499 first = subbandTab[cnt];
500 last = subbandTab[cnt+1];
501
502 subbWidth = last - first;
503
504 if (subband_vlc_index[cnt] != 0) {
505 /* Decode spectral coefficients for this subband. */
506 /* TODO: This can be done faster is several blocks share the
507 * same VLC selector (subband_vlc_index) */
508 readQuantSpectralCoeffs (gb, subband_vlc_index[cnt], codingMode, mantissas, subbWidth);
509
510 /* Decode the scale factor for this subband. */
511 SF = fixmul31(SFTable_fixed[SF_idxs[cnt]], iMaxQuant_fix[subband_vlc_index[cnt]]);
512 /* Remark: Hardcoded hack to add 2 bits (empty) fract part to internal sample
513 * representation. Needed for higher accuracy in internal calculations as
514 * well as for DSP configuration. See also: ../atrac3_rm.c, DSP_SET_SAMPLE_DEPTH
515 */
516 SF <<= 2;
517
518 /* Inverse quantize the coefficients. */
519 inverseQuantizeSpectrum(mantissas, pOut, first, last, SF);
520
521 } else {
522 /* This subband was not coded, so zero the entire subband. */
523 memset(pOut+first, 0, subbWidth*sizeof(int32_t));
524 }
525 }
526
527 /* Clear the subbands that were not coded. */
528 first = subbandTab[cnt];
529 memset(pOut+first, 0, (1024 - first) * sizeof(int32_t));
530 return numSubbands;
531}
532
533
534/**
535 * Restore the quantized tonal components
536 *
537 * @param gb the GetBit context
538 * @param pComponent tone component
539 * @param numBands amount of coded bands
540 */
541
542static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent, int numBands)
543{
544 int i,j,k,cnt;
545 int components, coding_mode_selector, coding_mode, coded_values_per_component;
546 int sfIndx, coded_values, max_coded_values, quant_step_index, coded_components;
547 int band_flags[4], mantissa[8];
548 int32_t *pCoef;
549 int32_t scalefactor;
550 int component_count = 0;
551
552 components = get_bits(gb,5);
553
554 /* no tonal components */
555 if (components == 0)
556 return 0;
557
558 coding_mode_selector = get_bits(gb,2);
559 if (coding_mode_selector == 2)
560 return -1;
561
562 coding_mode = coding_mode_selector & 1;
563
564 for (i = 0; i < components; i++) {
565 for (cnt = 0; cnt <= numBands; cnt++)
566 band_flags[cnt] = get_bits1(gb);
567
568 coded_values_per_component = get_bits(gb,3);
569
570 quant_step_index = get_bits(gb,3);
571 if (quant_step_index <= 1)
572 return -1;
573
574 if (coding_mode_selector == 3)
575 coding_mode = get_bits1(gb);
576
577 for (j = 0; j < (numBands + 1) * 4; j++) {
578 if (band_flags[j >> 2] == 0)
579 continue;
580
581 coded_components = get_bits(gb,3);
582
583 for (k=0; k<coded_components; k++) {
584 sfIndx = get_bits(gb,6);
585 pComponent[component_count].pos = j * 64 + (get_bits(gb,6));
586 max_coded_values = 1024 - pComponent[component_count].pos;
587 coded_values = coded_values_per_component + 1;
588 coded_values = FFMIN(max_coded_values,coded_values);
589
590 scalefactor = fixmul31(SFTable_fixed[sfIndx], iMaxQuant_fix[quant_step_index]);
591 /* Remark: Hardcoded hack to add 2 bits (empty) fract part to internal sample
592 * representation. Needed for higher accuracy in internal calculations as
593 * well as for DSP configuration. See also: ../atrac3_rm.c, DSP_SET_SAMPLE_DEPTH
594 */
595 scalefactor <<= 2;
596
597 readQuantSpectralCoeffs(gb, quant_step_index, coding_mode, mantissa, coded_values);
598
599 pComponent[component_count].numCoefs = coded_values;
600
601 /* inverse quant */
602 pCoef = pComponent[component_count].coef;
603 for (cnt = 0; cnt < coded_values; cnt++)
604 pCoef[cnt] = fixmul16(mantissa[cnt], scalefactor);
605
606 component_count++;
607 }
608 }
609 }
610
611 return component_count;
612}
613
614
615/**
616 * Decode gain parameters for the coded bands
617 *
618 * @param gb the GetBit context
619 * @param pGb the gainblock for the current band
620 * @param numBands amount of coded bands
621 */
622
623static int decodeGainControl (GetBitContext *gb, gain_block *pGb, int numBands)
624{
625 int i, cf, numData;
626 int *pLevel, *pLoc;
627
628 gain_info *pGain = pGb->gBlock;
629
630 for (i=0 ; i<=numBands; i++)
631 {
632 numData = get_bits(gb,3);
633 pGain[i].num_gain_data = numData;
634 pLevel = pGain[i].levcode;
635 pLoc = pGain[i].loccode;
636
637 for (cf = 0; cf < numData; cf++){
638 pLevel[cf]= get_bits(gb,4);
639 pLoc [cf]= get_bits(gb,5);
640 if(cf && pLoc[cf] <= pLoc[cf-1])
641 return -1;
642 }
643 }
644
645 /* Clear the unused blocks. */
646 for (; i<4 ; i++)
647 pGain[i].num_gain_data = 0;
648
649 return 0;
650}
651
652
653/**
654 * Apply fix (constant) gain and overlap for sample[start...255].
655 *
656 * @param pIn input buffer
657 * @param pPrev previous buffer to perform overlap against
658 * @param pOut output buffer
659 * @param start index to start with (always a multiple of 8)
660 * @param gain gain to apply
661 */
662
663static void applyFixGain (int32_t *pIn, int32_t *pPrev, int32_t *pOut,
664 int32_t start, int32_t gain)
665{
666 int32_t i = start;
667
668 /* start is always a multiple of 8 and therefore allows us to unroll the
669 * loop to 8 calculation per loop
670 */
671 if (ONE_16 == gain) {
672 /* gain1 = 1.0 -> no multiplication needed, just adding */
673 /* Remark: This path is called >90%. */
674 while (i<256) {
675 pOut[i] = pIn[i] + pPrev[i]; i++;
676 pOut[i] = pIn[i] + pPrev[i]; i++;
677 pOut[i] = pIn[i] + pPrev[i]; i++;
678 pOut[i] = pIn[i] + pPrev[i]; i++;
679 pOut[i] = pIn[i] + pPrev[i]; i++;
680 pOut[i] = pIn[i] + pPrev[i]; i++;
681 pOut[i] = pIn[i] + pPrev[i]; i++;
682 pOut[i] = pIn[i] + pPrev[i]; i++;
683 };
684 } else {
685 /* gain1 != 1.0 -> we need to do a multiplication */
686 /* Remark: This path is called seldom. */
687 while (i<256) {
688 pOut[i] = fixmul16(pIn[i], gain) + pPrev[i]; i++;
689 pOut[i] = fixmul16(pIn[i], gain) + pPrev[i]; i++;
690 pOut[i] = fixmul16(pIn[i], gain) + pPrev[i]; i++;
691 pOut[i] = fixmul16(pIn[i], gain) + pPrev[i]; i++;
692 pOut[i] = fixmul16(pIn[i], gain) + pPrev[i]; i++;
693 pOut[i] = fixmul16(pIn[i], gain) + pPrev[i]; i++;
694 pOut[i] = fixmul16(pIn[i], gain) + pPrev[i]; i++;
695 pOut[i] = fixmul16(pIn[i], gain) + pPrev[i]; i++;
696 };
697 }
698}
699
700
701/**
702 * Apply variable gain and overlap. Returns sample index after applying gain,
703 * resulting sample index is always a multiple of 8.
704 *
705 * @param pIn input buffer
706 * @param pPrev previous buffer to perform overlap against
707 * @param pOut output buffer
708 * @param start index to start with (always a multiple of 8)
709 * @param end end index for first loop (always a multiple of 8)
710 * @param gain1 current bands gain to apply
711 * @param gain2 next bands gain to apply
712 * @param gain_inc stepwise adaption from gain1 to gain2
713 */
714
715static int applyVariableGain (int32_t *pIn, int32_t *pPrev, int32_t *pOut,
716 int32_t start, int32_t end,
717 int32_t gain1, int32_t gain2, int32_t gain_inc)
718{
719 int32_t i = start;
720
721 /* Apply fix gains until end index is reached */
722 do {
723 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
724 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
725 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
726 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
727 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
728 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
729 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
730 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
731 } while (i < end);
732
733 /* Interpolation is done over next eight samples */
734 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
735 gain2 = fixmul16(gain2, gain_inc);
736 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
737 gain2 = fixmul16(gain2, gain_inc);
738 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
739 gain2 = fixmul16(gain2, gain_inc);
740 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
741 gain2 = fixmul16(gain2, gain_inc);
742 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
743 gain2 = fixmul16(gain2, gain_inc);
744 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
745 gain2 = fixmul16(gain2, gain_inc);
746 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
747 gain2 = fixmul16(gain2, gain_inc);
748 pOut[i] = fixmul16((fixmul16(pIn[i], gain1) + pPrev[i]), gain2); i++;
749 gain2 = fixmul16(gain2, gain_inc);
750
751 return i;
752}
753
754
755/**
756 * Apply gain parameters and perform the MDCT overlapping part
757 *
758 * @param pIn input buffer
759 * @param pPrev previous buffer to perform overlap against
760 * @param pOut output buffer
761 * @param pGain1 current band gain info
762 * @param pGain2 next band gain info
763 */
764
765static void gainCompensateAndOverlap (int32_t *pIn, int32_t *pPrev, int32_t *pOut,
766 gain_info *pGain1, gain_info *pGain2)
767{
768 /* gain compensation function */
769 int32_t gain1, gain2, gain_inc;
770 int cnt, numdata, nsample, startLoc;
771
772 if (pGain2->num_gain_data == 0)
773 gain1 = ONE_16;
774 else
775 gain1 = (ONE_16<<4)>>(pGain2->levcode[0]);
776
777 if (pGain1->num_gain_data == 0) {
778 /* Remark: This path is called >90%. */
779 /* Apply gain for all samples from 0...255 */
780 applyFixGain(pIn, pPrev, pOut, 0, gain1);
781 } else {
782 /* Remark: This path is called seldom. */
783 numdata = pGain1->num_gain_data;
784 pGain1->loccode[numdata] = 32;
785 pGain1->levcode[numdata] = 4;
786
787 nsample = 0; /* starting loop with =0 */
788
789 for (cnt = 0; cnt < numdata; cnt++) {
790 startLoc = pGain1->loccode[cnt] * 8;
791
792 gain2 = (ONE_16<<4)>>(pGain1->levcode[cnt]);
793 gain_inc = gain_tab2[(pGain1->levcode[cnt+1] - pGain1->levcode[cnt])+15];
794
795 /* Apply variable gain (gain1 -> gain2) to samples */
796 nsample = applyVariableGain(pIn, pPrev, pOut, nsample, startLoc, gain1, gain2, gain_inc);
797 }
798 /* Apply gain for the residual samples from nsample...255 */
799 applyFixGain(pIn, pPrev, pOut, nsample, gain1);
800 }
801
802 /* Delay for the overlapping part. */
803 memcpy(pPrev, &pIn[256], 256*sizeof(int32_t));
804}
805
806
807/**
808 * Combine the tonal band spectrum and regular band spectrum
809 * Return position of the last tonal coefficient
810
811 *
812 * @param pSpectrum output spectrum buffer
813 * @param numComponents amount of tonal components
814 * @param pComponent tonal components for this band
815 */
816
817static int addTonalComponents (int32_t *pSpectrum, int numComponents, tonal_component *pComponent)
818{
819 int cnt, i, lastPos = -1;
820 int32_t *pOut;
821 int32_t *pIn;
822
823 for (cnt = 0; cnt < numComponents; cnt++){
824 lastPos = FFMAX(pComponent[cnt].pos + pComponent[cnt].numCoefs, lastPos);
825 pIn = pComponent[cnt].coef;
826 pOut = &(pSpectrum[pComponent[cnt].pos]);
827
828 for (i=0 ; i<pComponent[cnt].numCoefs ; i++)
829 pOut[i] += pIn[i];
830 }
831
832 return lastPos;
833}
834
835
836/**
837 * Linear equidistant interpolation between two points x and y. 7 interpolation
838 * points can be calculated.
839 * Result for s=0 is x
840 * Result for s=8 is y
841 *
842 * @param x first input point
843 * @param y second input point
844 * @param s index of interpolation point (0..7)
845 */
846
847/* rockbox: Not used anymore. Faster version defined below.
848#define INTERPOLATE_FP16(x, y, s) ((x) + fixmul16(((s*ONE_16)>>3), (((y) - (x)))))
849*/
850#define INTERPOLATE_FP16(x, y, s) ((x) + ((s*((y)-(x)))>>3))
851
852static void reverseMatrixing(int32_t *su1, int32_t *su2, int *pPrevCode, int *pCurrCode)
853{
854 int i, band, nsample, s1, s2;
855 int32_t c1, c2;
856 int32_t mc1_l, mc1_r, mc2_l, mc2_r;
857
858 for (i=0,band = 0; band < 4*256; band+=256,i++) {
859 s1 = pPrevCode[i];
860 s2 = pCurrCode[i];
861 nsample = 0;
862
863 if (s1 != s2) {
864 /* Selector value changed, interpolation needed. */
865 mc1_l = matrixCoeffs_fix[s1<<1];
866 mc1_r = matrixCoeffs_fix[(s1<<1)+1];
867 mc2_l = matrixCoeffs_fix[s2<<1];
868 mc2_r = matrixCoeffs_fix[(s2<<1)+1];
869
870 /* Interpolation is done over the first eight samples. */
871 for(; nsample < 8; nsample++) {
872 c1 = su1[band+nsample];
873 c2 = su2[band+nsample];
874 c2 = fixmul16(c1, INTERPOLATE_FP16(mc1_l, mc2_l, nsample)) + fixmul16(c2, INTERPOLATE_FP16(mc1_r, mc2_r, nsample));
875 su1[band+nsample] = c2;
876 su2[band+nsample] = (c1 << 1) - c2;
877 }
878 }
879
880 /* Apply the matrix without interpolation. */
881 switch (s2) {
882 case 0: /* M/S decoding */
883 for (; nsample < 256; nsample++) {
884 c1 = su1[band+nsample];
885 c2 = su2[band+nsample];
886 su1[band+nsample] = c2 << 1;
887 su2[band+nsample] = (c1 - c2) << 1;
888 }
889 break;
890
891 case 1:
892 for (; nsample < 256; nsample++) {
893 c1 = su1[band+nsample];
894 c2 = su2[band+nsample];
895 su1[band+nsample] = (c1 + c2) << 1;
896 su2[band+nsample] = -1*(c2 << 1);
897 }
898 break;
899 case 2:
900 case 3:
901 for (; nsample < 256; nsample++) {
902 c1 = su1[band+nsample];
903 c2 = su2[band+nsample];
904 su1[band+nsample] = c1 + c2;
905 su2[band+nsample] = c1 - c2;
906 }
907 break;
908 default:
909 /* assert(0) */;
910 break;
911 }
912 }
913}
914
915static void getChannelWeights (int indx, int flag, int32_t ch[2]){
916 /* Read channel weights from table */
917 if (flag) {
918 /* Swap channel weights */
919 ch[1] = channelWeights0[indx&7];
920 ch[0] = channelWeights1[indx&7];
921 } else {
922 ch[0] = channelWeights0[indx&7];
923 ch[1] = channelWeights1[indx&7];
924 }
925}
926
927static void channelWeighting (int32_t *su1, int32_t *su2, int *p3)
928{
929 int band, nsample;
930 /* w[x][y] y=0 is left y=1 is right */
931 int32_t w[2][2];
932
933 if (p3[1] != 7 || p3[3] != 7){
934 getChannelWeights(p3[1], p3[0], w[0]);
935 getChannelWeights(p3[3], p3[2], w[1]);
936
937 for(band = 1; band < 4; band++) {
938 /* scale the channels by the weights */
939 for(nsample = 0; nsample < 8; nsample++) {
940 su1[band*256+nsample] = fixmul16(su1[band*256+nsample], INTERPOLATE_FP16(w[0][0], w[0][1], nsample));
941 su2[band*256+nsample] = fixmul16(su2[band*256+nsample], INTERPOLATE_FP16(w[1][0], w[1][1], nsample));
942 }
943
944 for(; nsample < 256; nsample++) {
945 su1[band*256+nsample] = fixmul16(su1[band*256+nsample], w[1][0]);
946 su2[band*256+nsample] = fixmul16(su2[band*256+nsample], w[1][1]);
947 }
948 }
949 }
950}
951
952/**
953 * Decode a Sound Unit
954 *
955 * @param gb the GetBit context
956 * @param pSnd the channel unit to be used
957 * @param pOut the decoded samples before IQMF
958 * @param channelNum channel number
959 * @param codingMode the coding mode (JOINT_STEREO or regular stereo/mono)
960 */
961
962static int decodeChannelSoundUnit (GetBitContext *gb, channel_unit *pSnd, int32_t *pOut, int channelNum, int codingMode)
963{
964 int band, result=0, numSubbands, lastTonal, numBands;
965 if (codingMode == JOINT_STEREO && channelNum == 1) {
966 if (get_bits(gb,2) != 3) {
967 DEBUGF("JS mono Sound Unit id != 3.\n");
968 return -1;
969 }
970 } else {
971 if (get_bits(gb,6) != 0x28) {
972 DEBUGF("Sound Unit id != 0x28.\n");
973 return -1;
974 }
975 }
976
977 /* number of coded QMF bands */
978 pSnd->bandsCoded = get_bits(gb,2);
979
980 result = decodeGainControl (gb, &(pSnd->gainBlock[pSnd->gcBlkSwitch]), pSnd->bandsCoded);
981 if (result) return result;
982
983 pSnd->numComponents = decodeTonalComponents (gb, pSnd->components, pSnd->bandsCoded);
984 if (pSnd->numComponents == -1) return -1;
985
986 numSubbands = decodeSpectrum (gb, pSnd->spectrum);
987
988 /* Merge the decoded spectrum and tonal components. */
989 lastTonal = addTonalComponents (pSnd->spectrum, pSnd->numComponents, pSnd->components);
990
991
992 /* calculate number of used MLT/QMF bands according to the amount of coded spectral lines */
993 numBands = (subbandTab[numSubbands] - 1) >> 8;
994 if (lastTonal >= 0)
995 numBands = FFMAX((lastTonal + 256) >> 8, numBands);
996
997 /* Reconstruct time domain samples. */
998 for (band=0; band<4; band++) {
999 /* Perform the IMDCT step without overlapping. */
1000 if (band <= numBands) {
1001 IMLT(&(pSnd->spectrum[band*256]), pSnd->IMDCT_buf);
1002 } else {
1003 memset(pSnd->IMDCT_buf, 0, 512 * sizeof(int32_t));
1004 }
1005
1006 /* gain compensation and overlapping */
1007 gainCompensateAndOverlap (pSnd->IMDCT_buf, &(pSnd->prevFrame[band*256]), &(pOut[band*256]),
1008 &((pSnd->gainBlock[1 - (pSnd->gcBlkSwitch)]).gBlock[band]),
1009 &((pSnd->gainBlock[pSnd->gcBlkSwitch]).gBlock[band]));
1010 }
1011
1012 /* Swap the gain control buffers for the next frame. */
1013 pSnd->gcBlkSwitch ^= 1;
1014
1015 return 0;
1016}
1017
1018/**
1019 * Frame handling
1020 *
1021 * @param q Atrac3 private context
1022 * @param databuf the input data
1023 */
1024
1025static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, int off)
1026{
1027 int result, i;
1028 int32_t *p1, *p2, *p3, *p4;
1029 uint8_t *ptr1;
1030
1031 if (q->codingMode == JOINT_STEREO) {
1032
1033 /* channel coupling mode */
1034 /* decode Sound Unit 1 */
1035 init_get_bits(&q->gb,databuf,q->bits_per_frame);
1036
1037 result = decodeChannelSoundUnit(&q->gb, q->pUnits, q->outSamples, 0, JOINT_STEREO);
1038 if (result != 0)
1039 return (result);
1040
1041 /* Framedata of the su2 in the joint-stereo mode is encoded in
1042 * reverse byte order so we need to swap it first. */
1043 if (databuf == q->decoded_bytes_buffer) {
1044 uint8_t *ptr2 = q->decoded_bytes_buffer+q->bytes_per_frame-1;
1045 ptr1 = q->decoded_bytes_buffer;
1046 for (i = 0; i < (q->bytes_per_frame/2); i++, ptr1++, ptr2--) {
1047 FFSWAP(uint8_t,*ptr1,*ptr2);
1048 }
1049 } else {
1050 const uint8_t *ptr2 = databuf+q->bytes_per_frame-1;
1051 for (i = 0; i < q->bytes_per_frame; i++)
1052 q->decoded_bytes_buffer[i] = *ptr2--;
1053 }
1054
1055 /* Skip the sync codes (0xF8). */
1056 ptr1 = q->decoded_bytes_buffer;
1057 for (i = 4; *ptr1 == 0xF8; i++, ptr1++) {
1058 if (i >= q->bytes_per_frame)
1059 return -1;
1060 }
1061
1062
1063 /* set the bitstream reader at the start of the second Sound Unit*/
1064 init_get_bits(&q->gb,ptr1,q->bits_per_frame);
1065
1066 /* Fill the Weighting coeffs delay buffer */
1067 memmove(q->weighting_delay,&(q->weighting_delay[2]),4*sizeof(int));
1068 q->weighting_delay[4] = get_bits1(&q->gb);
1069 q->weighting_delay[5] = get_bits(&q->gb,3);
1070
1071 for (i = 0; i < 4; i++) {
1072 q->matrix_coeff_index_prev[i] = q->matrix_coeff_index_now[i];
1073 q->matrix_coeff_index_now[i] = q->matrix_coeff_index_next[i];
1074 q->matrix_coeff_index_next[i] = get_bits(&q->gb,2);
1075 }
1076
1077 /* Decode Sound Unit 2. */
1078 result = decodeChannelSoundUnit(&q->gb, &q->pUnits[1], &q->outSamples[1024], 1, JOINT_STEREO);
1079 if (result != 0)
1080 return (result);
1081
1082 /* Reconstruct the channel coefficients. */
1083 reverseMatrixing(q->outSamples, &q->outSamples[1024], q->matrix_coeff_index_prev, q->matrix_coeff_index_now);
1084
1085 channelWeighting(q->outSamples, &q->outSamples[1024], q->weighting_delay);
1086
1087 } else {
1088 /* normal stereo mode or mono */
1089 /* Decode the channel sound units. */
1090 for (i=0 ; i<q->channels ; i++) {
1091
1092 /* Set the bitstream reader at the start of a channel sound unit. */
1093 init_get_bits(&q->gb, databuf+((i*q->bytes_per_frame)/q->channels)+off, (q->bits_per_frame)/q->channels);
1094
1095 result = decodeChannelSoundUnit(&q->gb, &q->pUnits[i], &q->outSamples[i*1024], i, q->codingMode);
1096 if (result != 0)
1097 return (result);
1098 }
1099 }
1100
1101 /* Apply the iQMF synthesis filter. */
1102 p1= q->outSamples;
1103 for (i=0 ; i<q->channels ; i++) {
1104 p2= p1+256;
1105 p3= p2+256;
1106 p4= p3+256;
1107 iqmf (p1, p2, 256, p1, q->pUnits[i].delayBuf1, q->tempBuf);
1108 iqmf (p4, p3, 256, p3, q->pUnits[i].delayBuf2, q->tempBuf);
1109 iqmf (p1, p3, 512, p1, q->pUnits[i].delayBuf3, q->tempBuf);
1110 p1 +=1024;
1111 }
1112
1113 return 0;
1114}
1115
1116
1117/**
1118 * Atrac frame decoding
1119 *
1120 * @param rmctx pointer to the AVCodecContext
1121 */
1122
1123int atrac3_decode_frame(unsigned long block_align, ATRAC3Context *q,
1124 int *data_size, const uint8_t *buf, int buf_size) {
1125 int result = 0, off = 0;
1126 const uint8_t* databuf;
1127
1128 if ((unsigned)buf_size < block_align)
1129 return buf_size;
1130
1131 /* Check if we need to descramble and what buffer to pass on. */
1132 if (q->scrambled_stream) {
1133 off = decode_bytes(buf, q->decoded_bytes_buffer, block_align);
1134 databuf = q->decoded_bytes_buffer;
1135 } else {
1136 databuf = buf;
1137 }
1138
1139 result = decodeFrame(q, databuf, off);
1140
1141 if (result != 0) {
1142 DEBUGF("Frame decoding error!\n");
1143 return -1;
1144 }
1145
1146 if (q->channels == 1)
1147 *data_size = 1024 * sizeof(int32_t);
1148 else
1149 *data_size = 2048 * sizeof(int32_t);
1150
1151 return block_align;
1152}
1153
1154
1155/**
1156 * Atrac3 initialization
1157 *
1158 * @param rmctx pointer to the RMContext
1159 */
1160int atrac3_decode_init(ATRAC3Context *q, struct mp3entry *id3)
1161{
1162 int i;
1163 uint8_t *edata_ptr = (uint8_t*)&id3->id3v2buf;
1164
1165#if defined(CPU_COLDFIRE)
1166 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
1167#endif
1168
1169 /* Take data from the RM container. */
1170 q->sample_rate = id3->frequency;
1171 q->channels = id3->channels;
1172 q->bit_rate = id3->bitrate * 1000;
1173 q->bits_per_frame = id3->bytesperframe * 8;
1174 q->bytes_per_frame = id3->bytesperframe;
1175
1176 /* Take care of the codec-specific extradata. */
1177
1178 if (id3->extradata_size == 14) {
1179 /* Parse the extradata, WAV format */
1180 DEBUGF("[0-1] %d\n",rm_get_uint16le(&edata_ptr[0])); /* Unknown value always 1 */
1181 q->samples_per_channel = rm_get_uint32le(&edata_ptr[2]);
1182 q->codingMode = rm_get_uint16le(&edata_ptr[6]);
1183 DEBUGF("[8-9] %d\n",rm_get_uint16le(&edata_ptr[8])); /* Dupe of coding mode */
1184 q->frame_factor = rm_get_uint16le(&edata_ptr[10]); /* Unknown always 1 */
1185 DEBUGF("[12-13] %d\n",rm_get_uint16le(&edata_ptr[12])); /* Unknown always 0 */
1186
1187 /* setup */
1188 q->samples_per_frame = 1024 * q->channels;
1189 q->atrac3version = 4;
1190 q->delay = 0x88E;
1191 if (q->codingMode)
1192 q->codingMode = JOINT_STEREO;
1193 else
1194 q->codingMode = STEREO;
1195 q->scrambled_stream = 0;
1196
1197 if ((q->bytes_per_frame == 96*q->channels*q->frame_factor) || (q->bytes_per_frame == 152*q->channels*q->frame_factor) || (q->bytes_per_frame == 192*q->channels*q->frame_factor)) {
1198 } else {
1199 DEBUGF("Unknown frame/channel/frame_factor configuration %d/%d/%d\n", q->bytes_per_frame, q->channels, q->frame_factor);
1200 return -1;
1201 }
1202
1203 } else if (id3->extradata_size == 10) {
1204 /* Parse the extradata, RM format. */
1205 q->atrac3version = rm_get_uint32be(&edata_ptr[0]);
1206 q->samples_per_frame = rm_get_uint16be(&edata_ptr[4]);
1207 q->delay = rm_get_uint16be(&edata_ptr[6]);
1208 q->codingMode = rm_get_uint16be(&edata_ptr[8]);
1209
1210 q->samples_per_channel = q->samples_per_frame / q->channels;
1211 q->scrambled_stream = 1;
1212
1213 } else {
1214 DEBUGF("Unknown extradata size %d.\n",id3->extradata_size);
1215 }
1216 /* Check the extradata. */
1217
1218 if (q->atrac3version != 4) {
1219 DEBUGF("Version %d != 4.\n",q->atrac3version);
1220 return -1;
1221 }
1222
1223 if (q->samples_per_frame != 1024 && q->samples_per_frame != 2048) {
1224 DEBUGF("Unknown amount of samples per frame %d.\n",q->samples_per_frame);
1225 return -1;
1226 }
1227
1228 if (q->delay != 0x88E) {
1229 DEBUGF("Unknown amount of delay %x != 0x88E.\n",q->delay);
1230 return -1;
1231 }
1232
1233 if (q->codingMode == STEREO) {
1234 DEBUGF("Normal stereo detected.\n");
1235 } else if (q->codingMode == JOINT_STEREO) {
1236 DEBUGF("Joint stereo detected.\n");
1237 } else {
1238 DEBUGF("Unknown channel coding mode %x!\n",q->codingMode);
1239 return -1;
1240 }
1241
1242 if (id3->channels <= 0 || id3->channels > 2 ) {
1243 DEBUGF("Channel configuration error!\n");
1244 return -1;
1245 }
1246
1247
1248 if(id3->bytesperframe >= UINT16_MAX/2)
1249 return -1;
1250
1251
1252 /* Initialize the VLC tables. */
1253 if (!vlcs_initialized) {
1254 for (i=0 ; i<7 ; i++) {
1255 spectral_coeff_tab[i].table = &atrac3_vlc_table[atrac3_vlc_offs[i]];
1256 spectral_coeff_tab[i].table_allocated = atrac3_vlc_offs[i + 1] - atrac3_vlc_offs[i];
1257 init_vlc (&spectral_coeff_tab[i], 9, huff_tab_sizes[i],
1258 huff_bits[i], 1, 1,
1259 huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
1260 }
1261
1262 vlcs_initialized = 1;
1263
1264 }
1265
1266 init_atrac3_transforms();
1267
1268 /* init the joint-stereo decoding data */
1269 q->weighting_delay[0] = 0;
1270 q->weighting_delay[1] = 7;
1271 q->weighting_delay[2] = 0;
1272 q->weighting_delay[3] = 7;
1273 q->weighting_delay[4] = 0;
1274 q->weighting_delay[5] = 7;
1275
1276 for (i=0; i<4; i++) {
1277 q->matrix_coeff_index_prev[i] = 3;
1278 q->matrix_coeff_index_now[i] = 3;
1279 q->matrix_coeff_index_next[i] = 3;
1280 }
1281
1282 /* Link the iram'ed arrays to the decoder's data structure */
1283 q->pUnits = channel_units;
1284 q->pUnits[0].spectrum = &atrac3_spectrum [0][0];
1285 q->pUnits[1].spectrum = &atrac3_spectrum [1][0];
1286 q->pUnits[0].IMDCT_buf = &atrac3_IMDCT_buf[0][0];
1287 q->pUnits[1].IMDCT_buf = &atrac3_IMDCT_buf[1][0];
1288 q->pUnits[0].prevFrame = &atrac3_prevFrame[0][0];
1289 q->pUnits[1].prevFrame = &atrac3_prevFrame[1][0];
1290
1291 return 0;
1292}
1293
diff --git a/lib/rbcodec/codecs/libatrac/atrac3.h b/lib/rbcodec/codecs/libatrac/atrac3.h
new file mode 100644
index 0000000000..64086b6411
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/atrac3.h
@@ -0,0 +1,114 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 Mohamed Tarek
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#include "ffmpeg_get_bits.h"
23#include "../librm/rm.h"
24#include "codeclib.h"
25
26#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || \
27 (CONFIG_CPU == MCF5250) || defined(CPU_S5L870X)
28/* PP5022/24, MCF5250 and S5L870x have larger IRAM */
29#define IBSS_ATTR_LARGE_IRAM IBSS_ATTR
30#define ICODE_ATTR_LARGE_IRAM ICODE_ATTR
31#define ICONST_ATTR_LARGE_IRAM ICONST_ATTR
32#else
33/* other CPUs IRAM is not large enough */
34#define IBSS_ATTR_LARGE_IRAM
35#define ICODE_ATTR_LARGE_IRAM
36#define ICONST_ATTR_LARGE_IRAM
37#endif
38
39/* These structures are needed to store the parsed gain control data. */
40typedef struct {
41 int num_gain_data;
42 int levcode[8];
43 int loccode[8];
44} gain_info;
45
46typedef struct {
47 gain_info gBlock[4];
48} gain_block;
49
50typedef struct {
51 int pos;
52 int numCoefs;
53 int32_t coef[8];
54} tonal_component;
55
56typedef struct {
57 int bandsCoded;
58 int numComponents;
59 tonal_component components[64];
60 int32_t *prevFrame;
61 int gcBlkSwitch;
62 gain_block gainBlock[2];
63
64 int32_t *spectrum;
65 int32_t *IMDCT_buf;
66
67 int32_t delayBuf1[46] MEM_ALIGN_ATTR; ///<qmf delay buffers
68 int32_t delayBuf2[46] MEM_ALIGN_ATTR;
69 int32_t delayBuf3[46] MEM_ALIGN_ATTR;
70} channel_unit;
71
72typedef struct {
73 int32_t outSamples[2048] MEM_ALIGN_ATTR;
74 GetBitContext gb;
75 //@{
76 /** stream data */
77 int channels;
78 int codingMode;
79 int bit_rate;
80 int sample_rate;
81 int samples_per_channel;
82 int samples_per_frame;
83
84 int bits_per_frame;
85 int bytes_per_frame;
86 int pBs;
87 channel_unit* pUnits;
88 //@}
89 //@{
90 /** joint-stereo related variables */
91 int matrix_coeff_index_prev[4];
92 int matrix_coeff_index_now[4];
93 int matrix_coeff_index_next[4];
94 int weighting_delay[6];
95 //@}
96 //@{
97 /** data buffers */
98 uint8_t decoded_bytes_buffer[1024] MEM_ALIGN_ATTR;
99 int32_t tempBuf[1070] MEM_ALIGN_ATTR;
100 //@}
101 //@{
102 /** extradata */
103 int atrac3version;
104 int delay;
105 int scrambled_stream;
106 int frame_factor;
107 //@}
108} ATRAC3Context;
109
110int atrac3_decode_init(ATRAC3Context *q, struct mp3entry *id3);
111
112int atrac3_decode_frame(unsigned long block_align, ATRAC3Context *q,
113 int *data_size, const uint8_t *buf, int buf_size);
114
diff --git a/lib/rbcodec/codecs/libatrac/atrac3_arm.S b/lib/rbcodec/codecs/libatrac/atrac3_arm.S
new file mode 100644
index 0000000000..68f8de2c4e
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/atrac3_arm.S
@@ -0,0 +1,172 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright (C) 2009 by Andree Buschmann
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#include "config.h"
23
24 .section .text, "ax", %progbits
25
26/****************************************************************************
27 * void atrac3_iqmf_matrixing(int32_t *dest,
28 * int32_t *inlo,
29 * int32_t *inhi,
30 * unsigned int count);
31 *
32 * Matrixing step within iqmf of atrac3 synthesis. Reference implementation:
33 *
34 * for(i=0; i<counter; i+=2){
35 * dest[2*i+0] = inlo[i ] + inhi[i ];
36 * dest[2*i+1] = inlo[i ] - inhi[i ];
37 * dest[2*i+2] = inlo[i+1] + inhi[i+1];
38 * dest[2*i+3] = inlo[i+1] - inhi[i+1];
39 * }
40 * Note: r12 is a scratch register and can be used without restorage.
41 ****************************************************************************/
42 .align 2
43 .global atrac3_iqmf_matrixing
44 .type atrac3_iqmf_matrixing, %function
45
46atrac3_iqmf_matrixing:
47 /* r0 = dest */
48 /* r1 = inlo */
49 /* r2 = inhi */
50 /* r3 = counter */
51 stmfd sp!, {r4-r9, lr} /* save non-scratch registers */
52
53.iqmf_matrixing_loop:
54 ldmia r1!, { r4, r6, r8, r12} /* load inlo[0...3] */
55 ldmia r2!, { r5, r7, r9, lr } /* load inhi[0...3] */
56 add r4, r4, r5 /* r4 = inlo[0] + inhi[0] */
57 sub r5, r4, r5, asl #1 /* r5 = inlo[0] - inhi[0] */
58 add r6, r6, r7 /* r6 = inlo[1] + inhi[1] */
59 sub r7, r6, r7, asl #1 /* r7 = inlo[1] - inhi[1] */
60 add r8, r8, r9 /* r8 = inlo[2] + inhi[2] */
61 sub r9, r8, r9, asl #1 /* r9 = inlo[2] - inhi[2] */
62 add r12, r12, lr /* r12 = inlo[3] + inhi[3] */
63 sub lr , r12, lr, asl #1 /* lr = inlo[3] - inhi[3] */
64 stmia r0!, {r4-r9, r12, lr} /* store results to dest */
65 subs r3, r3, #4 /* counter -= 4 */
66 bgt .iqmf_matrixing_loop
67
68 ldmpc regs=r4-r9 /* restore registers */
69
70.atrac3_iqmf_matrixing_end:
71 .size atrac3_iqmf_matrixing,.atrac3_iqmf_matrixing_end-atrac3_iqmf_matrixing
72
73
74/****************************************************************************
75 * atrac3_iqmf_dewindowing(int32_t *out,
76 * int32_t *in,
77 * int32_t *win,
78 * unsigned int nIn);
79 *
80 * Dewindowing step within iqmf of atrac3 synthesis. Reference implementation:
81 *
82 * for (j = nIn; j != 0; j--) {
83 * s1 = fixmul32(in[0], win[0]);
84 * s2 = fixmul32(in[1], win[1]);
85 * for (i = 2; i < 48; i += 2) {
86 * s1 += fixmul32(in[i ], win[i ]);
87 * s2 += fixmul32(in[i+1], win[i+1]);
88 * }
89 * out[0] = s2 << 1;
90 * out[1] = s1 << 1;
91 * in += 2;
92 * out += 2;
93 * }
94 * Note: r12 is a scratch register and can be used without restorage.
95 ****************************************************************************/
96
97/* To be called as first block to call smull for initial filling of the result
98 * registers lr/r9 and r12/r8. */
99#define DEWIN_8_SAMPLES_MUL_ASM \
100 ldmia r2!, {r4, r5}; /* load win[0..1] */ \
101 ldmia r1!, {r6, r7}; /* load in [0..1] */ \
102 smull lr , r9, r4, r6; /* s1 = win[0] * in[0] */ \
103 smull r12, r8, r5, r7; /* s2 = win[1] * in[1] */ \
104 ldmia r2!, {r4, r5}; /* load win[i..i+1] */ \
105 ldmia r1!, {r6, r7}; /* load in [i..i+1] */ \
106 smlal lr , r9, r4, r6; /* s1 = win[i ] * in[i ] */ \
107 smlal r12, r8, r5, r7; /* s2 = win[i+1] * in[i+1] */ \
108 ldmia r2!, {r4, r5}; /* load win[i..i+1] */ \
109 ldmia r1!, {r6, r7}; /* load in [i..i+1] */ \
110 smlal lr , r9, r4, r6; /* s1 = win[i ] * in[i ] */ \
111 smlal r12, r8, r5, r7; /* s2 = win[i+1] * in[i+1] */ \
112 ldmia r2!, {r4, r5}; /* load win[i..i+1] */ \
113 ldmia r1!, {r6, r7}; /* load in [i..i+1] */ \
114 smlal lr , r9, r4, r6; /* s1 = win[i ] * in[i ] */ \
115 smlal r12, r8, r5, r7; /* s2 = win[i+1] * in[i+1] */
116
117/* Called after first block. Will always multiply-add to the result registers
118 * lr/r9 and r12/r8. */
119#define DEWIN_8_SAMPLES_MLA_ASM \
120 ldmia r2!, {r4, r5}; /* load win[i..i+1] */ \
121 ldmia r1!, {r6, r7}; /* load in [i..i+1] */ \
122 smlal lr , r9, r4, r6; /* s1 = win[i ] * in[i ] */ \
123 smlal r12, r8, r5, r7; /* s2 = win[i+1] * in[i+1] */ \
124 ldmia r2!, {r4, r5}; /* load win[i..i+1] */ \
125 ldmia r1!, {r6, r7}; /* load in [i..i+1] */ \
126 smlal lr , r9, r4, r6; /* s1 = win[i ] * in[i ] */ \
127 smlal r12, r8, r5, r7; /* s2 = win[i+1] * in[i+1] */ \
128 ldmia r2!, {r4, r5}; /* load win[i..i+1] */ \
129 ldmia r1!, {r6, r7}; /* load in [i..i+1] */ \
130 smlal lr , r9, r4, r6; /* s1 = win[i ] * in[i ] */ \
131 smlal r12, r8, r5, r7; /* s2 = win[i+1] * in[i+1] */ \
132 ldmia r2!, {r4, r5}; /* load win[i..i+1] */ \
133 ldmia r1!, {r6, r7}; /* load in [i..i+1] */ \
134 smlal lr , r9, r4, r6; /* s1 = win[i ] * in[i ] */ \
135 smlal r12, r8, r5, r7; /* s2 = win[i+1] * in[i+1] */
136
137 .align 2
138 .global atrac3_iqmf_dewindowing
139 .type atrac3_iqmf_dewindowing, %function
140
141atrac3_iqmf_dewindowing:
142 /* r0 = dest */
143 /* r1 = input samples */
144 /* r2 = window coefficients */
145 /* r3 = counter */
146 stmfd sp!, {r4-r9, lr} /* save non-scratch registers */
147
148.iqmf_dewindow_outer_loop: /* outer loop 0...counter-1 */
149
150 DEWIN_8_SAMPLES_MUL_ASM /* 0.. 7, use "MUL" macro here! */
151 DEWIN_8_SAMPLES_MLA_ASM /* 8..15 */
152 DEWIN_8_SAMPLES_MLA_ASM /* 16..23 */
153 DEWIN_8_SAMPLES_MLA_ASM /* 24..31 */
154 DEWIN_8_SAMPLES_MLA_ASM /* 32..39 */
155 DEWIN_8_SAMPLES_MLA_ASM /* 40..47 */
156
157 mov lr , lr , lsr #31
158 orr r9, lr , r9, lsl #1 /* s1 = low>>31 || hi<<1 */
159 mov r12, r12, lsr #31
160 orr r8, r12, r8, lsl #1 /* s2 = low>>31 || hi<<1 */
161
162 stmia r0!, {r8, r9} /* store result out[0]=s2, out[1]=s1 */
163 sub r1, r1, #184 /* roll back 64 entries = 184 bytes */
164 sub r2, r2, #192 /* roll back 48 entries = 192 bytes = win[0] */
165
166 subs r3, r3, #1 /* outer loop -= 1 */
167 bgt .iqmf_dewindow_outer_loop
168
169 ldmpc regs=r4-r9 /* restore registers */
170
171.atrac3_iqmf_dewindowing_end:
172 .size atrac3_iqmf_dewindowing,.atrac3_iqmf_dewindowing_end-atrac3_iqmf_dewindowing
diff --git a/lib/rbcodec/codecs/libatrac/atrac3_armv5e.S b/lib/rbcodec/codecs/libatrac/atrac3_armv5e.S
new file mode 100644
index 0000000000..1d9d35a5da
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/atrac3_armv5e.S
@@ -0,0 +1,163 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright (C) 2010 by Michael Giacomelli
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#include "config.h"
23
24 .section .text, "ax", %progbits
25
26
27/****************************************************************************
28 * atrac3_iqmf_dewindowing_armv5e(int32_t *out,
29 * int32_t *in,
30 * int32_t *win,
31 * unsigned int nIn);
32 *
33 * Dewindowing step within iqmf of atrac3 synthesis using 16 bit filter
34 * coefficients and armv5e packed multiply instructions. Uses 2.5 cycles
35 * per filter coefficient (ideal). Benchmarked 3.54 per coefficient (Clip+).
36 *
37 * Reference implementation:
38 *
39 * for (j = nIn; j != 0; j--) {
40 * s1 = fixmul32(in[0], win[0]);
41 * s2 = fixmul32(in[1], win[1]);
42 * for (i = 2; i < 48; i += 2) {
43 * s1 += fixmul32(in[i ], win[i ]);
44 * s2 += fixmul32(in[i+1], win[i+1]);
45 * }
46 * out[0] = s2 << 1;
47 * out[1] = s1 << 1;
48 * in += 2;
49 * out += 2;
50 * }
51 * Note: r12 is a scratch register and can be used without restorage.
52 ****************************************************************************/
53 .align 2
54 .global atrac3_iqmf_dewindowing_armv5e
55 .type atrac3_iqmf_dewindowing_armv5e, %function
56
57atrac3_iqmf_dewindowing_armv5e:
58 /* r0 = dest */
59 /* r1 = input samples */
60 /* r2 = window coefficients */
61 /* r3 = counter */
62 stmfd sp!, {r4-r11, lr} /* save non-scratch registers */
63
64.iqmf_dewindow_outer_loop: /* outer loop 0...counter-1 */
65 /* 0.. 7 */
66 ldmia r2!, {r4, r5, r8, r9} /* load win[0..7] */
67 ldmia r1!, {r6, r7, r10, r11} /* load in[0..3] to avoid stall on arm11 */
68 smulwb lr, r6, r4 /* s1 = in[0] * win[0] */
69 smulwt r12, r7, r4 /* s2 = in[1] * win[1] */
70 smlawb lr, r10, r5, lr /* s1 += in[i ] * win[i ] >> 16 */
71 smlawt r12, r11,r5, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
72
73 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
74 smlawb lr, r6, r8, lr /* s1 += in[i ] * win[i ] >> 16 */
75 smlawt r12, r7, r8, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
76 smlawb lr, r10, r9, lr /* s1 += in[i ] * win[i ] >> 16 */
77 smlawt r12, r11, r9, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
78
79 /* 8..15 */
80 ldmia r2!, {r4, r5, r8, r9} /* load win[8..15] */
81 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
82 smlawb lr, r6, r4, lr /* s1 += in[i ] * win[i ] >> 16 */
83 smlawt r12, r7, r4, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
84 smlawb lr, r10, r5, lr /* s1 += in[i ] * win[i ] >> 16 */
85 smlawt r12, r11,r5, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
86
87 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
88 smlawb lr, r6, r8, lr /* s1 += in[i ] * win[i ] >> 16 */
89 smlawt r12, r7, r8, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
90 smlawb lr, r10, r9, lr /* s1 += in[i ] * win[i ] >> 16 */
91 smlawt r12, r11,r9, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
92
93 /* 16..23 */
94 ldmia r2!, {r4, r5, r8, r9} /* load win[16..23] */
95 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
96 smlawb lr, r6, r4, lr /* s1 += in[i ] * win[i ] >> 16 */
97 smlawt r12, r7, r4, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
98 smlawb lr, r10, r5, lr /* s1 += in[i ] * win[i ] >> 16 */
99 smlawt r12, r11,r5, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
100
101 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
102 smlawb lr, r6, r8, lr /* s1 += in[i ] * win[i ] >> 16 */
103 smlawt r12, r7, r8, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
104 smlawb lr, r10, r9, lr /* s1 += in[i ] * win[i ] >> 16 */
105 smlawt r12, r11,r9, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
106
107 /* 24..31 */
108 ldmia r2!, {r4, r5, r8, r9} /* load win[24..31] */
109 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
110 smlawb lr, r6, r4, lr /* s1 += in[i ] * win[i ] >> 16 */
111 smlawt r12, r7, r4, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
112 smlawb lr, r10, r5, lr /* s1 += in[i ] * win[i ] >> 16 */
113 smlawt r12, r11,r5, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
114
115 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
116 smlawb lr, r6, r8, lr /* s1 += in[i ] * win[i ] >> 16 */
117 smlawt r12, r7, r8, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
118 smlawb lr, r10, r9, lr /* s1 += in[i ] * win[i ] >> 16 */
119 smlawt r12, r11,r9, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
120
121 /* 32..39 */
122 ldmia r2!, {r4, r5, r8, r9} /* load win[32..39] */
123 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
124 smlawb lr, r6, r4, lr /* s1 += in[i ] * win[i ] >> 16 */
125 smlawt r12, r7, r4, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
126 smlawb lr, r10, r5, lr /* s1 += in[i ] * win[i ] >> 16 */
127 smlawt r12, r11,r5, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
128
129 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
130 smlawb lr, r6, r8, lr /* s1 += in[i ] * win[i ] >> 16 */
131 smlawt r12, r7, r8, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
132 smlawb lr, r10, r9, lr /* s1 += in[i ] * win[i ] >> 16 */
133 smlawt r12, r11,r9, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
134
135 /* 40..47 */
136 ldmia r2!, {r4, r5, r8, r9} /* load win[40..47] */
137 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
138 smlawb lr, r6, r4, lr /* s1 += in[i ] * win[i ] >> 16 */
139 smlawt r12, r7, r4, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
140 smlawb lr, r10, r5, lr /* s1 += in[i ] * win[i ] >> 16 */
141 smlawt r12, r11,r5, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
142
143 ldmia r1!, {r6, r7, r10, r11} /* load in[i...i+3] */
144 smlawb lr, r6, r8, lr /* s1 += in[i ] * win[i ] >> 16 */
145 smlawt r12, r7, r8, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
146 smlawb lr, r10, r9, lr /* s1 += in[i ] * win[i ] >> 16 */
147 smlawt r12, r11,r9, r12 /* s2 += in[i+1] * win[i+1] >> 16 */
148
149
150 mov lr , lr , lsl #1
151 mov r12, r12, lsl #1
152
153 stmia r0!, {r12, lr} /* store result out[0]=s2, out[1]=s1 */
154 sub r1, r1, #184 /* roll back 64 entries = 184 bytes */
155 sub r2, r2, #96 /* roll back 48 entries * 2 bytes = 96 bytes = win[0] */
156
157 subs r3, r3, #1 /* outer loop -= 1 */
158 bgt .iqmf_dewindow_outer_loop
159
160 ldmpc regs=r4-r11 /* restore registers */
161
162.atrac3_iqmf_dewindowing_armv5e_end:
163 .size atrac3_iqmf_dewindowing_armv5e,.atrac3_iqmf_dewindowing_armv5e_end-atrac3_iqmf_dewindowing_armv5e
diff --git a/lib/rbcodec/codecs/libatrac/atrac3data.h b/lib/rbcodec/codecs/libatrac/atrac3data.h
new file mode 100644
index 0000000000..30abb37572
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/atrac3data.h
@@ -0,0 +1,148 @@
1/*
2 * Atrac 3 compatible decoder data
3 * Copyright (c) 2006-2007 Maxim Poliakovski
4 * Copyright (c) 2006-2007 Benjamin Larsson
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/**
24 * @file libavcodec/atrac3data.h
25 * Atrac 3 AKA RealAudio 8 compatible decoder data
26 */
27
28#ifndef AVCODEC_ATRAC3DATA_H
29#define AVCODEC_ATRAC3DATA_H
30
31#include <inttypes.h>
32
33/* VLC tables */
34
35static const uint8_t huffcode1[9] ICONST_ATTR_LARGE_IRAM = {
36 0x0,0x4,0x5,0xC,0xD,0x1C,0x1D,0x1E,0x1F,
37};
38
39static const uint8_t huffbits1[9] ICONST_ATTR_LARGE_IRAM = {
40 1,3,3,4,4,5,5,5,5,
41};
42
43static const uint8_t huffcode2[5] ICONST_ATTR_LARGE_IRAM = {
44 0x0,0x4,0x5,0x6,0x7,
45};
46
47static const uint8_t huffbits2[5] ICONST_ATTR_LARGE_IRAM = {
48 1,3,3,3,3,
49};
50
51static const uint8_t huffcode3[7] ICONST_ATTR_LARGE_IRAM = {
520x0,0x4,0x5,0xC,0xD,0xE,0xF,
53};
54
55static const uint8_t huffbits3[7] ICONST_ATTR_LARGE_IRAM = {
56 1,3,3,4,4,4,4,
57};
58
59static const uint8_t huffcode4[9] ICONST_ATTR_LARGE_IRAM = {
60 0x0,0x4,0x5,0xC,0xD,0x1C,0x1D,0x1E,0x1F,
61};
62
63static const uint8_t huffbits4[9] ICONST_ATTR_LARGE_IRAM = {
64 1,3,3,4,4,5,5,5,5,
65};
66
67static const uint8_t huffcode5[15] ICONST_ATTR_LARGE_IRAM = {
68 0x0,0x2,0x3,0x8,0x9,0xA,0xB,0x1C,0x1D,0x3C,0x3D,0x3E,0x3F,0xC,0xD,
69};
70
71static const uint8_t huffbits5[15] ICONST_ATTR_LARGE_IRAM = {
72 2,3,3,4,4,4,4,5,5,6,6,6,6,4,4
73};
74
75static const uint8_t huffcode6[31] ICONST_ATTR_LARGE_IRAM = {
76 0x0,0x2,0x3,0x4,0x5,0x6,0x7,0x14,0x15,0x16,0x17,0x18,0x19,0x34,0x35,
77 0x36,0x37,0x38,0x39,0x3A,0x3B,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x8,0x9,
78};
79
80static const uint8_t huffbits6[31] ICONST_ATTR_LARGE_IRAM = {
81 3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,4,4
82};
83
84static const uint8_t huffcode7[63] ICONST_ATTR_LARGE_IRAM = {
85 0x0,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,0x10,0x11,0x24,0x25,0x26,0x27,0x28,
86 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x68,0x69,0x6A,0x6B,0x6C,
87 0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,
88 0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x2,0x3,
89};
90
91static const uint8_t huffbits7[63] ICONST_ATTR_LARGE_IRAM = {
92 3,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,
93 7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,4,4
94};
95
96static const uint8_t huff_tab_sizes[7] ICONST_ATTR_LARGE_IRAM = {
97 9, 5, 7, 9, 15, 31, 63,
98};
99
100static const uint8_t* const huff_codes[7] ICONST_ATTR_LARGE_IRAM = {
101 huffcode1,huffcode2,huffcode3,huffcode4,huffcode5,huffcode6,huffcode7,
102};
103
104static const uint8_t* const huff_bits[7] ICONST_ATTR_LARGE_IRAM = {
105 huffbits1,huffbits2,huffbits3,huffbits4,huffbits5,huffbits6,huffbits7,
106};
107
108static const uint16_t atrac3_vlc_offs[] ICONST_ATTR_LARGE_IRAM = {
109 0,512,1024,1536,2048,2560,3072,3584,4096
110};
111
112/* selector tables */
113
114static const uint8_t CLCLengthTab[8] ICONST_ATTR_LARGE_IRAM = {
115 0, 4, 3, 3, 4, 4, 5, 6};
116static const int8_t seTab_0[4] ICONST_ATTR_LARGE_IRAM = {
117 0, 1, -2, -1};
118static const int8_t decTable1[18] ICONST_ATTR_LARGE_IRAM = {
119 0,0, 0,1, 0,-1, 1,0, -1,0, 1,1, 1,-1, -1,1, -1,-1};
120
121
122/* tables for the scalefactor decoding */
123/* not needed anymore
124static const float iMaxQuant[8] = {
125 0.0, 1.0/1.5, 1.0/2.5, 1.0/3.5, 1.0/4.5, 1.0/7.5, 1.0/15.5, 1.0/31.5
126};
127*/
128static const uint16_t subbandTab[33] ICONST_ATTR_LARGE_IRAM = {
129 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224,
130 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024
131};
132
133/* transform data */
134/* not needed anymore
135static const float qmf_48tap_half[24] = {
136 -0.00001461907, -0.00009205479, -0.000056157569, 0.00030117269,
137 0.0002422519,-0.00085293897, -0.0005205574, 0.0020340169,
138 0.00078333891, -0.0042153862, -0.00075614988, 0.0078402944,
139 -0.000061169922, -0.01344162, 0.0024626821, 0.021736089,
140 -0.007801671, -0.034090221, 0.01880949, 0.054326009,
141 -0.043596379, -0.099384367, 0.13207909, 0.46424159
142};
143*/
144/* joint stereo related tables */
145/* not needed anymore
146static const float matrixCoeffs[8] = {0.0, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0};
147*/
148#endif /* AVCODEC_ATRAC3DATA_H */
diff --git a/lib/rbcodec/codecs/libatrac/atrac3data_fixed.h b/lib/rbcodec/codecs/libatrac/atrac3data_fixed.h
new file mode 100644
index 0000000000..9eb79731ce
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/atrac3data_fixed.h
@@ -0,0 +1,108 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 Michael Giacomelli
11 * Copyright (C) 2009 Mohamed Tarek
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22/* tables for the scalefactor decoding */
23/* scaled by 2^31*/
24static const int32_t iMaxQuant_fix[8] ICONST_ATTR = {
25 0x0, 0x55555580, 0x33333340, 0x24924940, 0x1c71c720, 0x11111120, 0x8421080,
26 0x4104108
27};
28
29/* scaled by 2^16 */
30static const int32_t SFTable_fixed[64] ICONST_ATTR = {
31 0x00000800, 0x00000a14, 0x00000cb3, 0x00001000, 0x00001429, 0x00001966,
32 0x00002000, 0x00002851, 0x000032cc, 0x00004000, 0x000050a3, 0x00006598,
33 0x00008000, 0x0000a145, 0x0000cb30, 0x00010000, 0x0001428a, 0x00019660,
34 0x00020000, 0x00028514, 0x00032cc0, 0x00040000, 0x00050a29, 0x00065980,
35 0x00080000, 0x000a1452, 0x000cb2ff, 0x00100000, 0x001428a3, 0x001965ff,
36 0x00200000, 0x00285146, 0x0032cbfd, 0x00400000, 0x0050a28c, 0x006597fb,
37 0x00800000, 0x00a14518, 0x00cb2ff5, 0x01000000, 0x01428a30, 0x01965fea,
38 0x02000000, 0x02851460, 0x032cbfd4, 0x04000000, 0x050a28c0, 0x06597fa8,
39 0x08000000, 0x0a145180, 0x0cb2ff50, 0x10000000, 0x1428a300, 0x1965fea0,
40 0x20000000, 0x28514600, 0x32cbfd40, 0x40000000, 0x50a28c00, 0x6597fa80,
41 0x80000000, 0x80000000, 0x80000000, 0x80000000,
42};
43
44/* transform data */
45/* floating point values scaled by 2^31 */
46static const int32_t qmf_48tap_half_fix[24] = {
47 0xffff855e, 0xfffcfbca, 0xfffe28eb, 0x0009de6b, 0x0007f028, 0xffe40d08,
48 0xffeef140, 0x0042a692, 0x0019ab1f, 0xff75dec7, 0xffe738f5, 0x0100e928,
49 0xfffdfedf, 0xfe478b84, 0x0050b279, 0x02c83f88, 0xff005ad7, 0xfba2ee80,
50 0x02685970, 0x06f42798, 0xfa6b6f10, 0xf3475f80, 0x10e7f7c0, 0x3b6c44c0
51};
52
53/* mdct window scaled by 2^31 */
54/* Remark: The preceding sign corrects the sign of the hexadecimal values */
55static const int32_t window_lookup[128] ICONST_ATTR MEM_ALIGN_ATTR = {
56 -0xffffb10c, -0xfffd394b, -0xfff8494f, -0xfff0e025, -0xffe6fc5f, -0xffda9c15,
57 -0xffcbbce6, -0xffba5bf4, -0xffa675e8, -0xff9006f0, -0xff770aba, -0xff5b7c7e,
58 -0xff3d56f2, -0xff1c9452, -0xfef92e59, -0xfed31e45, -0xfeaa5cd5, -0xfe7ee247,
59 -0xfe50a657, -0xfe1fa041, -0xfdebc6c1, -0xfdb5100d, -0xfd7b71d5, -0xfd3ee149,
60 -0xfcff5311, -0xfcbcbb49, -0xfc770d99, -0xfc2e3d15, -0xfbe23c39, -0xfb92fd29,
61 -0xfb407141, -0xfaea8989, -0xfa913661, -0xfa3467b1, -0xf9d40cd9, -0xf9701499,
62 -0xf9086d41, -0xf89d04a9, -0xf82dc7f1, -0xf7baa3e1, -0xf74384b1, -0xf6c85611,
63 -0xf6490321, -0xf5c576b1, -0xf53d9b21, -0xf4b15a01, -0xf4209ce1, -0xf38b4c71,
64 -0xf2f15171, -0xf2529411, -0xf1aefbf1, -0xf10670a1, -0xf058d941, -0xefa61cc1,
65 -0xeeee21c1, -0xee30cec1, -0xed6e0a41, -0xeca5ba61, -0xebd7c5c1, -0xeb041241,
66 -0xea2a8601, -0xe94b0861, -0xe8657f61, -0xe779d241, -0xe687e861, -0xe58fa9e1,
67 -0xe490fec1, -0xe38bd101, -0xe28009c1, -0xe16d93e1, -0xe0545ba1, -0xdf344dc1,
68 -0xde0d5881, -0xdcdf6bc1, -0xdbaa7801, -0xda6e70c1, -0xd92b4ac1, -0xd7e0fc81,
69 -0xd68f7ec1, -0xd536cd41, -0xd3d6e5c1, -0xd26fc901, -0xd10179c1, -0xcf8bff41,
70 -0xce0f6301, -0xcc8bb241, -0xcb00fdc1, -0xc96f5b01, -0xc7d6e141, -0xc637af41,
71 -0xc491e4c1, -0xc2e5a801, -0xc1332401, -0xbf7a8701, -0xbdbc0681, -0xbbf7da01,
72 -0xba2e4181, -0xb85f7f81, -0xb68bde01, -0xb4b3a981, -0xb2d73781, -0xb0f6df01,
73 -0xaf12ff01, -0xad2bfa81, -0xab423981, -0xa9562981, -0xa7683c01, -0xa578e701,
74 -0xa388a681, -0xa197f801, -0x9fa75e81, -0x9db75f01, -0x9bc88201, -0x99db5301,
75 -0x97f06001, -0x96083601, -0x94236601, -0x92427f81, -0x90661481, -0x8e8eb481,
76 -0x8cbced01, -0x8af14d81, -0x892c5f81, -0x876eab01, -0x85b8b681, -0x840b0301,
77 -0x82660c01, -0x80ca4a01,
78};
79
80/* Gain tables scaled by 2^16 */
81static const int32_t gain_tab2[31] ICONST_ATTR = {
82 0x0003ab03, 0x00035d14, 0x0003159d, 0x0002d414, 0x000297fb, 0x000260e0,
83 0x00022e57, 0x00020000, 0x0001d582, 0x0001ae8a, 0x00018ace, 0x00016a0a,
84 0x00014bfe, 0x00013070, 0x0001172c, 0x00010000, 0x0000eac1, 0x0000d745,
85 0x0000c567, 0x0000b505, 0x0000a5ff, 0x00009838, 0x00008b96, 0x00008000,
86 0x00007560, 0x00006ba2, 0x000062b4, 0x00005a82, 0x000052ff, 0x00004c1c,
87 0x000045cb,
88
89};
90
91/* Joint-Stereo related tables, scaled by 2^16 */
92static const int32_t matrixCoeffs_fix[8] ICONST_ATTR = {
93 0x00000000, 0x00020000, 0x00020000, 0x00020000,
94 0x00000000, 0x00000000, 0x00010000, 0x00010000,
95};
96
97/* channelWeights0[i] = ONE_16 * ((i & 7)/7) */
98static const int32_t channelWeights0[8] = {
99 0x00000000, 0x00002492, 0x00004925, 0x00006DB7,
100 0x00009249, 0x0000B6DB, 0x0000DB6D, 0x00010000,
101};
102
103/* channelWeights1[i] = ONE_16 * sqrt(2-channelWeights0^2) */
104static const int32_t channelWeights1[8] = {
105 0x00016A0A, 0x00016830, 0x00016293, 0x00015904,
106 0x00014B2B, 0x00013877, 0x00011FF7, 0x00010000,
107};
108
diff --git a/lib/rbcodec/codecs/libatrac/fixp_math.h b/lib/rbcodec/codecs/libatrac/fixp_math.h
new file mode 100644
index 0000000000..014c5aa559
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/fixp_math.h
@@ -0,0 +1,111 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 Mohamed Tarek
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#include <stdlib.h>
22#include <inttypes.h>
23
24/* Macros for converting between various fixed-point representations and floating point. */
25#define ONE_16 (1L << 16)
26#define fixtof64(x) (float)((float)(x) / (float)(1 << 16)) //does not work on int64_t!
27#define ftofix32(x) ((int32_t)((x) * (float)(1 << 16) + ((x) < 0 ? -0.5 : 0.5)))
28#define ftofix31(x) ((int32_t)((x) * (float)(1 << 31) + ((x) < 0 ? -0.5 : 0.5)))
29#define fix31tof64(x) (float)((float)(x) / (float)(1 << 31))
30
31/* Fixed point math routines for use in atrac3.c */
32
33#if defined(CPU_ARM)
34 /* Calculates: result = (X*Y)>>16 */
35 #define fixmul16(X,Y) \
36 ({ \
37 int32_t lo; \
38 int32_t hi; \
39 asm volatile ( \
40 "smull %[lo], %[hi], %[x], %[y] \n\t" /* multiply */ \
41 "mov %[lo], %[lo], lsr #16 \n\t" /* lo >>= 16 */ \
42 "orr %[lo], %[lo], %[hi], lsl #16" /* lo |= (hi << 16) */ \
43 : [lo]"=&r"(lo), [hi]"=&r"(hi) \
44 : [x]"r"(X), [y]"r"(Y)); \
45 lo; \
46 })
47
48 /* Calculates: result = (X*Y)>>31 */
49 /* Use scratch register r12 */
50 #define fixmul31(X,Y) \
51 ({ \
52 int32_t lo; \
53 int32_t hi; \
54 asm volatile ( \
55 "smull %[lo], %[hi], %[x], %[y] \n\t" /* multiply */ \
56 "mov %[lo], %[lo], lsr #31 \n\t" /* lo >>= 31 */ \
57 "orr %[lo], %[lo], %[hi], lsl #1" /* lo |= (hi << 1) */ \
58 : [lo]"=&r"(lo), [hi]"=&r"(hi) \
59 : [x]"r"(X), [y]"r"(Y)); \
60 lo; \
61 })
62#elif defined(CPU_COLDFIRE)
63 /* Calculates: result = (X*Y)>>16 */
64 #define fixmul16(X,Y) \
65 ({ \
66 int32_t t, x = (X); \
67 asm volatile ( \
68 "mac.l %[x],%[y],%%acc0\n\t" /* multiply */ \
69 "mulu.l %[y],%[x] \n\t" /* get lower half, avoid emac stall */ \
70 "movclr.l %%acc0,%[t] \n\t" /* get higher half */ \
71 "lsr.l #1,%[t] \n\t" /* hi >>= 1 to compensate emac shift */ \
72 "move.w %[t],%[x] \n\t" /* combine halfwords */\
73 "swap %[x] \n\t" \
74 : [t]"=&d"(t), [x] "+d" (x) \
75 : [y] "d" ((Y))); \
76 x; \
77 })
78
79 #define fixmul31(X,Y) \
80 ({ \
81 int32_t t; \
82 asm volatile ( \
83 "mac.l %[x], %[y], %%acc0\n\t" /* multiply */ \
84 "movclr.l %%acc0, %[t]\n\t" /* get higher half as result */ \
85 : [t] "=d" (t) \
86 : [x] "r" ((X)), [y] "r" ((Y))); \
87 t; \
88 })
89#else
90 static inline int32_t fixmul16(int32_t x, int32_t y)
91 {
92 int64_t temp;
93 temp = x;
94 temp *= y;
95
96 temp >>= 16;
97
98 return (int32_t)temp;
99 }
100
101 static inline int32_t fixmul31(int32_t x, int32_t y)
102 {
103 int64_t temp;
104 temp = x;
105 temp *= y;
106
107 temp >>= 31; //16+31-16 = 31 bits
108
109 return (int32_t)temp;
110 }
111#endif
diff --git a/lib/rbcodec/codecs/libatrac/libatrac.make b/lib/rbcodec/codecs/libatrac/libatrac.make
new file mode 100644
index 0000000000..69a66eb6f5
--- /dev/null
+++ b/lib/rbcodec/codecs/libatrac/libatrac.make
@@ -0,0 +1,18 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id: libatrac.make 20151 2009-03-01 09:04:15Z amiconn $
8#
9
10# libatrac
11ATRACLIB := $(CODECDIR)/libatrac.a
12ATRACLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libatrac/SOURCES)
13ATRACLIB_OBJ := $(call c2obj, $(ATRACLIB_SRC))
14OTHER_SRC += $(ATRACLIB_SRC)
15
16$(ATRACLIB): $(ATRACLIB_OBJ)
17 $(SILENT)$(shell rm -f $@)
18 $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null