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