summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libtta/ttadec.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libtta/ttadec.c')
-rw-r--r--lib/rbcodec/codecs/libtta/ttadec.c582
1 files changed, 582 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libtta/ttadec.c b/lib/rbcodec/codecs/libtta/ttadec.c
new file mode 100644
index 0000000000..06ca431084
--- /dev/null
+++ b/lib/rbcodec/codecs/libtta/ttadec.c
@@ -0,0 +1,582 @@
1/*
2 * ttadec.c
3 *
4 * Description: TTAv1 decoder library for HW players
5 * Developed by: Alexander Djourik <ald@true-audio.com>
6 * Pavel Zhilin <pzh@true-audio.com>
7 *
8 * Copyright (c) 2004 True Audio Software. All rights reserved.
9 *
10 */
11
12/*
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. Neither the name of the True Audio Software nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#include <stdio.h>
40#include "codeclib.h"
41
42#include "ttalib.h"
43#include "ttadec.h"
44#include "filter.h"
45
46/******************* static variables and structures *******************/
47
48static unsigned char isobuffers[ISO_BUFFERS_SIZE + 4] IBSS_ATTR;
49static unsigned char * const iso_buffers_end ICONST_ATTR = isobuffers + ISO_BUFFERS_SIZE;
50static unsigned int pcm_buffer_size IBSS_ATTR;
51
52static decoder tta[MAX_NCH] IBSS_ATTR; /* decoder state */
53/* Rockbox speciffic: cache is defined in get_samples() (non static value) */
54/* static int cache[MAX_NCH]; // decoder cache */
55
56static tta_info *ttainfo IBSS_ATTR; /* currently playing file info */
57
58static unsigned int fframes IBSS_ATTR; /* number of frames in file */
59static unsigned int framelen IBSS_ATTR; /* the frame length in samples */
60static unsigned int lastlen IBSS_ATTR; /* the length of the last frame in samples */
61static unsigned int data_pos IBSS_ATTR; /* currently playing frame index */
62static unsigned int data_cur IBSS_ATTR; /* the playing position in frame */
63
64static int maxvalue IBSS_ATTR; /* output data max value */
65
66/* Rockbox speciffic: seek_table is static size */
67static unsigned int seek_table[MAX_SEEK_TABLE_SIZE]; /* the playing position table */
68static unsigned int st_state; /* seek table status */
69
70static unsigned int frame_crc32 IBSS_ATTR;
71static unsigned int bit_count IBSS_ATTR;
72static unsigned int bit_cache IBSS_ATTR;
73static unsigned char *bitpos IBSS_ATTR;
74
75/* Rockbox speciffic: deletes read_id3_tags(). */
76/* static int read_id3_tags (tta_info *info); */
77
78/********************* rockbox helper functions *************************/
79
80/* emulate stdio functions */
81static size_t tta_fread(void *ptr, size_t size, size_t nobj)
82{
83 size_t read_size;
84 unsigned char *buffer = ci->request_buffer(&read_size, size * nobj);
85
86 if (read_size > 0)
87 {
88 ci->memcpy(ptr, buffer, read_size);
89 ci->advance_buffer(read_size);
90 }
91 return read_size;
92}
93
94static int tta_fseek(long offset, int origin)
95{
96 switch (origin)
97 {
98 case SEEK_CUR:
99 ci->advance_buffer(offset);
100 break;
101 case SEEK_SET:
102 ci->seek_buffer(offset);
103 break;
104 case SEEK_END:
105 ci->seek_buffer(offset + ci->id3->filesize);
106 break;
107 default:
108 return -1;
109 }
110 return 0;
111}
112
113/************************* crc32 functions *****************************/
114
115#define UPDATE_CRC32(x, crc) crc = \
116 (((crc>>8) & 0x00FFFFFF) ^ crc32_table[(crc^x) & 0xFF])
117
118static unsigned int
119crc32 (unsigned char *buffer, unsigned int len) {
120 unsigned int i;
121 unsigned int crc = 0xFFFFFFFF;
122
123 for (i = 0; i < len; i++) UPDATE_CRC32(buffer[i], crc);
124
125 return (crc ^ 0xFFFFFFFF);
126}
127
128/************************* bit operations ******************************/
129
130#define GET_BINARY(value, bits) \
131 while (bit_count < bits) { \
132 if (bitpos == iso_buffers_end) { \
133 if (!tta_fread(isobuffers, 1, ISO_BUFFERS_SIZE)) { \
134 ttainfo->STATE = READ_ERROR; \
135 return -1; \
136 } \
137 bitpos = isobuffers; \
138 } \
139 UPDATE_CRC32(*bitpos, frame_crc32); \
140 bit_cache |= *bitpos << bit_count; \
141 bit_count += 8; \
142 bitpos++; \
143 } \
144 value = bit_cache & bit_mask[bits]; \
145 bit_cache >>= bits; \
146 bit_count -= bits; \
147 bit_cache &= bit_mask[bit_count];
148
149#define GET_UNARY(value) \
150 value = 0; \
151 while (!(bit_cache ^ bit_mask[bit_count])) { \
152 if (bitpos == iso_buffers_end) { \
153 if (!tta_fread(isobuffers, 1, ISO_BUFFERS_SIZE)) { \
154 ttainfo->STATE = READ_ERROR; \
155 return -1; \
156 } \
157 bitpos = isobuffers; \
158 } \
159 value += bit_count; \
160 bit_cache = *bitpos++; \
161 UPDATE_CRC32(bit_cache, frame_crc32); \
162 bit_count = 8; \
163 } \
164 while (bit_cache & 1) { \
165 value++; \
166 bit_cache >>= 1; \
167 bit_count--; \
168 } \
169 bit_cache >>= 1; \
170 bit_count--;
171
172/************************* rice operations ******************************/
173
174static inline int update_rice(int value, adapt *rice, int depth,
175 const unsigned int *shift_table)
176{
177 if (depth > 0)
178 {
179 rice->sum1 += value - (rice->sum1 >> 4);
180 if (rice->k1 > 0 && rice->sum1 < shift_table[rice->k1])
181 rice->k1--;
182 else if (rice->sum1 > shift_table[rice->k1 + 1])
183 rice->k1++;
184 value += *(shift_table + rice->k0 - 4);
185 }
186 rice->sum0 += value - (rice->sum0 >> 4);
187 if (rice->k0 > 0 && rice->sum0 < shift_table[rice->k0])
188 rice->k0--;
189 else if (rice->sum0 > shift_table[rice->k0 + 1])
190 rice->k0++;
191
192 return DEC(value);
193}
194
195/************************* buffer functions ******************************/
196
197static void init_buffer_read(void) {
198 frame_crc32 = 0xFFFFFFFFUL;
199 bit_count = bit_cache = 0;
200 bitpos = iso_buffers_end;
201}
202
203static int done_buffer_read(void) {
204 unsigned int crc32, rbytes;
205
206 frame_crc32 ^= 0xFFFFFFFFUL;
207 rbytes = iso_buffers_end - bitpos;
208
209 if (rbytes < sizeof(int)) {
210 ci->memcpy(isobuffers, bitpos, 4);
211 if (!tta_fread(isobuffers + rbytes, 1, ISO_BUFFERS_SIZE - rbytes))
212 return -1;
213 bitpos = isobuffers;
214 }
215
216 ci->memcpy(&crc32, bitpos, 4);
217 crc32 = ENDSWAP_INT32(crc32);
218 bitpos += sizeof(int);
219
220 if (crc32 != frame_crc32) return -1;
221
222 bit_cache = bit_count = 0;
223 frame_crc32 = 0xFFFFFFFFUL;
224
225 return 0;
226}
227
228/************************* decoder functions ****************************/
229
230/* rockbox: not used
231const char *get_error_str (int error) {
232 switch (error) {
233 case NO_ERROR: return "No errors found";
234 case OPEN_ERROR: return "Can't open file";
235 case FORMAT_ERROR: return "Not supported file format";
236 case FILE_ERROR: return "File is corrupted";
237 case READ_ERROR: return "Can't read from file";
238 case MEMORY_ERROR: return "Insufficient memory available";
239 default: return "Unknown error code";
240 }
241} */
242
243int set_tta_info (tta_info *info)
244{
245 unsigned int checksum;
246 unsigned int datasize;
247 unsigned int origsize;
248 tta_hdr ttahdr;
249
250 /* clear the memory */
251 ci->memset (info, 0, sizeof(tta_info));
252
253 /* skip id3v2 tags */
254 tta_fseek(ci->id3->id3v2len, SEEK_SET);
255
256 /* read TTA header */
257 if (tta_fread (&ttahdr, 1, sizeof (ttahdr)) == 0) {
258 info->STATE = READ_ERROR;
259 return -1;
260 }
261
262 /* check for TTA3 signature */
263 if (ENDSWAP_INT32(ttahdr.TTAid) != TTA1_SIGN) {
264 DEBUGF("ID error: %x\n", ENDSWAP_INT32(ttahdr.TTAid));
265 info->STATE = FORMAT_ERROR;
266 return -1;
267 }
268
269 ttahdr.CRC32 = ENDSWAP_INT32(ttahdr.CRC32);
270 checksum = crc32((unsigned char *) &ttahdr,
271 sizeof(tta_hdr) - sizeof(int));
272 if (checksum != ttahdr.CRC32) {
273 DEBUGF("CRC error: %x != %x\n", ttahdr.CRC32, checksum);
274 info->STATE = FILE_ERROR;
275 return -1;
276 }
277
278 ttahdr.AudioFormat = ENDSWAP_INT16(ttahdr.AudioFormat);
279 ttahdr.NumChannels = ENDSWAP_INT16(ttahdr.NumChannels);
280 ttahdr.BitsPerSample = ENDSWAP_INT16(ttahdr.BitsPerSample);
281 ttahdr.SampleRate = ENDSWAP_INT32(ttahdr.SampleRate);
282 ttahdr.DataLength = ENDSWAP_INT32(ttahdr.DataLength);
283
284 /* check for player supported formats */
285 if (ttahdr.AudioFormat != WAVE_FORMAT_PCM ||
286 ttahdr.NumChannels > MAX_NCH ||
287 ttahdr.BitsPerSample > MAX_BPS ||(
288 ttahdr.SampleRate != 16000 &&
289 ttahdr.SampleRate != 22050 &&
290 ttahdr.SampleRate != 24000 &&
291 ttahdr.SampleRate != 32000 &&
292 ttahdr.SampleRate != 44100 &&
293 ttahdr.SampleRate != 48000 &&
294 ttahdr.SampleRate != 64000 &&
295 ttahdr.SampleRate != 88200 &&
296 ttahdr.SampleRate != 96000)) {
297 info->STATE = FORMAT_ERROR;
298 DEBUGF("illegal audio format: %d channels: %d samplerate: %d\n",
299 ttahdr.AudioFormat, ttahdr.NumChannels, ttahdr.SampleRate);
300 return -1;
301 }
302
303 /* fill the File Info */
304 info->NCH = ttahdr.NumChannels;
305 info->BPS = ttahdr.BitsPerSample;
306 info->BSIZE = (ttahdr.BitsPerSample + 7)/8;
307 info->FORMAT = ttahdr.AudioFormat;
308 info->SAMPLERATE = ttahdr.SampleRate;
309 info->DATALENGTH = ttahdr.DataLength;
310 info->FRAMELEN = (int) MULTIPLY_FRAME_TIME(ttahdr.SampleRate);
311 info->LENGTH = ttahdr.DataLength / ttahdr.SampleRate;
312 info->DATAPOS = ci->id3->id3v2len;
313 info->FILESIZE = ci->id3->filesize;
314
315 datasize = info->FILESIZE - info->DATAPOS;
316 origsize = info->DATALENGTH * info->BSIZE * info->NCH;
317
318 /* info->COMPRESS = (double) datasize / origsize; */
319 info->BITRATE = (int) ((uint64_t) datasize * info->SAMPLERATE * info->NCH * info->BPS
320 / (origsize * 1000LL));
321
322 return 0;
323}
324
325static void rice_init(adapt *rice, unsigned int k0, unsigned int k1) {
326 rice->k0 = k0;
327 rice->k1 = k1;
328 rice->sum0 = shift_16[k0];
329 rice->sum1 = shift_16[k1];
330}
331
332static void decoder_init(decoder *tta, int nch, int byte_size) {
333 int shift = flt_set[byte_size - 1];
334 int i;
335
336 for (i = 0; i < nch; i++) {
337 filter_init(&tta[i].fst, shift);
338 rice_init(&tta[i].rice, 10, 10);
339 tta[i].last = 0;
340 }
341}
342
343static void seek_table_init (unsigned int *seek_table,
344 unsigned int len, unsigned int data_offset) {
345 unsigned int *st, frame_len;
346
347 for (st = seek_table; st < (seek_table + len); st++) {
348 frame_len = ENDSWAP_INT32(*st);
349 *st = data_offset;
350 data_offset += frame_len;
351 }
352}
353
354int set_position (unsigned int pos, enum tta_seek_type type)
355{
356 unsigned int i;
357 unsigned int seek_pos;
358
359 if (type == TTA_SEEK_TIME)
360 {
361 if (pos >= fframes)
362 pos = fframes -1;
363 }
364 else
365 {
366 pos -= ttainfo->DATAPOS;
367 for (i = 1; i < fframes; i++)
368 {
369 if (seek_table[i] > pos)
370 break;
371 }
372 pos = i - 1;
373 }
374 if (!st_state) {
375 ttainfo->STATE = FILE_ERROR;
376 return -1;
377 }
378 seek_pos = ttainfo->DATAPOS + seek_table[data_pos = pos];
379 if (tta_fseek(seek_pos, SEEK_SET) < 0) {
380 ttainfo->STATE = READ_ERROR;
381 return -1;
382 }
383
384 data_cur = 0;
385 framelen = 0;
386
387 /* init bit reader */
388 init_buffer_read();
389 return data_pos * ttainfo->FRAMELEN;
390}
391
392int player_init (tta_info *info) {
393 unsigned int checksum;
394 unsigned int data_offset;
395 unsigned int st_size;
396
397#ifdef CPU_COLDFIRE
398 coldfire_set_macsr(0); /* signed integer mode */
399#endif
400
401 ttainfo = info;
402
403 framelen = 0;
404 data_pos = 0;
405 data_cur = 0;
406
407 lastlen = ttainfo->DATALENGTH % ttainfo->FRAMELEN;
408 fframes = ttainfo->DATALENGTH / ttainfo->FRAMELEN + (lastlen ? 1 : 0);
409 st_size = (fframes + 1) * sizeof(int);
410
411 /*
412 * Rockbox speciffic
413 * playable tta file is to MAX_SEEK_TABLE_SIZE frames
414 * about 1:08:15 (frequency 44.1 kHz)
415 */
416 if (fframes > MAX_SEEK_TABLE_SIZE)
417 {
418 LOGF("frame is too many: %d > %d", fframes, MAX_SEEK_TABLE_SIZE);
419 return -1;
420 }
421
422 /* read seek table */
423 if (!tta_fread(seek_table, st_size, 1)) {
424 ttainfo->STATE = READ_ERROR;
425 return -1;
426 }
427
428 checksum = crc32((unsigned char *) seek_table, st_size - sizeof(int));
429 st_state = (checksum == ENDSWAP_INT32(seek_table[fframes]));
430 data_offset = sizeof(tta_hdr) + st_size;
431
432 /* init seek table */
433 seek_table_init(seek_table, fframes, data_offset);
434
435 /* init bit reader */
436 init_buffer_read();
437
438 /*
439 * Rockbox speciffic
440 * because pcm data is int32_t, does not multiply ttainfo->BSIZE.
441 */
442 pcm_buffer_size = PCM_BUFFER_LENGTH * ttainfo->NCH;
443 maxvalue = (1UL << ttainfo->BPS) - 1;
444
445 return 0;
446}
447
448/*
449 * Rockbox specffic
450 * because the seek table is static size buffer, player_stop() is nooperation function.
451 */
452void player_stop (void) {
453/*
454 if (seek_table) {
455 free(seek_table);
456 seek_table = NULL;
457 }
458*/
459}
460
461/*
462 * Rockbox speciffic
463 * with the optimization, the decoding logic is modify a little.
464 */
465int get_samples (int32_t *buffer) {
466 unsigned int k, depth, unary, binary;
467 int32_t *p = buffer;
468 decoder *dec = tta;
469 int value, res;
470 int cur_pos = pcm_buffer_size;
471 int pcm_shift_bits = TTA_OUTPUT_DEPTH - ttainfo->BPS;
472 int pr_bits = (ttainfo->BSIZE == 1)? 4 : 5;
473 int cache = 0; /* decoder cache */
474
475 fltst *fst;
476 adapt *rice;
477
478 for (res = 0; --cur_pos >= 0;) {
479 fst = &dec->fst;
480 rice = &dec->rice;
481
482 if (data_cur == framelen) {
483 if (data_pos == fframes) break;
484 if (framelen && done_buffer_read()) {
485 if (set_position(data_pos, TTA_SEEK_TIME) < 0) return -1;
486 if (res) break;
487 }
488
489 if (data_pos == fframes - 1 && lastlen)
490 framelen = lastlen;
491 else framelen = ttainfo->FRAMELEN;
492
493 decoder_init(tta, ttainfo->NCH, ttainfo->BSIZE);
494 data_pos++; data_cur = 0;
495 }
496
497 /* decode Rice unsigned */
498 GET_UNARY(unary);
499
500 switch (unary) {
501 case 0: depth = 0; k = rice->k0; break;
502 default:
503 depth = 1; k = rice->k1;
504 unary--;
505 }
506
507 if (k) {
508 GET_BINARY(binary, k);
509 value = (unary << k) + binary;
510 } else value = unary;
511
512 value = update_rice(value, rice, depth, shift_16);
513
514 /* Rockbox specific: the following logic move to update_rice() */
515#if 0
516 if (depth > 0)
517 {
518 rice->sum1 += value - (rice->sum1 >> 4);
519 if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1])
520 rice->k1--;
521 else if (rice->sum1 > shift_16[rice->k1 + 1])
522 rice->k1++;
523 value += bit_shift[rice->k0];
524 }
525 rice->sum0 += value - (rice->sum0 >> 4);
526 if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0])
527 rice->k0--;
528 else if (rice->sum0 > shift_16[rice->k0 + 1])
529 rice->k0++;
530
531 value = DEC(value);
532#endif
533
534 /* decompress stage 1: adaptive hybrid filter */
535 hybrid_filter(fst, &value);
536
537 /* decompress stage 2: fixed order 1 prediction */
538 value += PREDICTOR1(dec->last, pr_bits);
539 dec->last = value;
540
541 /* check for errors */
542 if (abs(value) > maxvalue) {
543 unsigned int tail =
544 pcm_buffer_size / (ttainfo->BSIZE * ttainfo->NCH) - res;
545 ci->memset(buffer, 0, pcm_buffer_size * sizeof(int32_t));
546 data_cur += tail; res += tail;
547 break;
548 }
549
550 /* Rockbox speciffic: Rockbox supports max 2channels */
551 if (ttainfo->NCH == 1)
552 {
553 *p++ = value << pcm_shift_bits;
554 data_cur++;
555 res++;
556 }
557 else
558 {
559 if (dec == tta)
560 {
561 cache = value;
562 dec++;
563 }
564 else
565 {
566 value += cache / 2;
567 cache = value - cache;
568 dec = tta;
569 *p++ = cache << pcm_shift_bits;
570 *p++ = value << pcm_shift_bits;
571 data_cur++;
572 res++;
573 }
574 }
575 }
576
577 return res;
578}
579
580/* Rockbox speciffic: id3 tags functions delete. */
581
582/* eof */