Theme Editor: Added support for upper-case wps file extensions
[kugel-rb.git] / apps / codecs / tta.c
blob2d531315a21abeece4afefb991e93c96c3031055
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Yoshihisa Uchida
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "codeclib.h"
23 #include "codecs/libtta/ttalib.h"
25 CODEC_HEADER
28 * TTA (True Audio) codec:
30 * References
31 * [1] TRUE AUDIO CODEC SOFTWARE http://true-audio.com/
34 static int32_t samples[PCM_BUFFER_LENGTH * 2] IBSS_ATTR;
36 /* this is the codec entry point */
37 enum codec_status codec_main(void)
39 tta_info info;
40 int status = CODEC_OK;
41 unsigned int decodedsamples;
42 int endofstream;
43 int new_pos = 0;
44 int sample_count;
46 /* Generic codec initialisation */
47 ci->configure(DSP_SET_SAMPLE_DEPTH, TTA_OUTPUT_DEPTH - 1);
49 next_track:
50 if (codec_init())
52 DEBUGF("codec_init() error\n");
53 status = CODEC_ERROR;
54 goto exit;
57 while (!*ci->taginfo_ready && !ci->stop_codec)
58 ci->sleep(1);
60 if (set_tta_info(&info) < 0 || player_init(&info) < 0)
62 status = CODEC_ERROR;
63 goto exit;
66 codec_set_replaygain(ci->id3);
68 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
69 if (info.NCH == 2) {
70 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
71 } else if (info.NCH == 1) {
72 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
73 } else {
74 DEBUGF("CODEC_ERROR: more than 2 channels\n");
75 status = CODEC_ERROR;
76 goto done;
79 /* The main decoder loop */
80 decodedsamples = 0;
81 endofstream = 0;
83 if (ci->id3->offset > 0)
85 /* Need to save offset for later use (cleared indirectly by advance_buffer) */
86 new_pos = set_position(ci->id3->offset, TTA_SEEK_POS);
87 if (new_pos >= 0)
88 decodedsamples = new_pos;
89 ci->seek_complete();
92 while (!endofstream)
94 ci->yield();
95 if (ci->stop_codec || ci->new_track)
96 break;
98 if (ci->seek_time)
100 new_pos = set_position(ci->seek_time / SEEK_STEP, TTA_SEEK_TIME);
101 if (new_pos >= 0)
103 decodedsamples = new_pos;
104 ci->seek_complete();
108 sample_count = get_samples(samples);
109 if (sample_count < 0)
111 status = CODEC_ERROR;
112 break;
114 ci->pcmbuf_insert(samples, NULL, sample_count);
115 decodedsamples += sample_count;
116 if (decodedsamples >= info.DATALENGTH)
117 endofstream = 1;
118 ci->set_elapsed((uint64_t)info.LENGTH * 1000 * decodedsamples / info.DATALENGTH);
120 status = CODEC_OK;
121 done:
122 player_stop();
123 if (ci->request_next_track())
124 goto next_track;
126 exit:
127 return status;