Calibrate iPod Classic battery gauge a bit better
[kugel-rb.git] / apps / codecs / atrac3_oma.c
blob73f3ad29fdbd3cf3f9d7bdbd2e990f24306f14ba
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2009 Mohamed Tarek
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 <string.h>
24 #include "logf.h"
25 #include "codeclib.h"
26 #include "inttypes.h"
27 #include "libatrac/atrac3.h"
29 CODEC_HEADER
31 #define FRAMESIZE ci->id3->bytesperframe
32 #define BITRATE ci->id3->bitrate
34 static ATRAC3Context q IBSS_ATTR;
36 /* this is the codec entry point */
37 enum codec_status codec_main(void)
39 static size_t buff_size;
40 int datasize, res, frame_counter, total_frames, seek_frame_offset;
41 uint8_t *bit_buffer;
42 int elapsed = 0;
43 size_t resume_offset;
45 next_track:
46 if (codec_init()) {
47 DEBUGF("codec init failed\n");
48 return CODEC_ERROR;
51 if (codec_wait_taginfo() != 0)
52 goto done;
54 resume_offset = ci->id3->offset;
56 codec_set_replaygain(ci->id3);
57 ci->memset(&q,0,sizeof(ATRAC3Context));
59 ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
60 ci->configure(DSP_SET_SAMPLE_DEPTH, 17); /* Remark: atrac3 uses s15.0 by default, s15.2 was hacked. */
61 ci->configure(DSP_SET_STEREO_MODE, ci->id3->channels == 1 ?
62 STEREO_MONO : STEREO_NONINTERLEAVED);
64 res =atrac3_decode_init(&q, ci->id3);
65 if(res < 0) {
66 DEBUGF("failed to initialize OMA atrac decoder\n");
67 return CODEC_ERROR;
70 /* check for a mid-track resume and force a seek time accordingly */
71 if(resume_offset > ci->id3->first_frame_offset) {
72 resume_offset -= ci->id3->first_frame_offset;
73 /* calculate resume_offset in frames */
74 resume_offset = (int)resume_offset / FRAMESIZE;
75 ci->seek_time = (int)resume_offset * ((FRAMESIZE * 8)/BITRATE);
77 total_frames = (ci->id3->filesize - ci->id3->first_frame_offset) / FRAMESIZE;
78 frame_counter = 0;
80 ci->set_elapsed(0);
81 ci->seek_buffer(0);
82 ci->advance_buffer(ci->id3->first_frame_offset);
84 /* The main decoder loop */
85 seek_start :
86 while(frame_counter < total_frames)
88 bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE);
90 ci->yield();
91 if (ci->stop_codec || ci->new_track)
92 goto done;
94 if (ci->seek_time) {
95 ci->set_elapsed(ci->seek_time);
97 /* Do not allow seeking beyond the file's length */
98 if ((unsigned) ci->seek_time > ci->id3->length) {
99 ci->seek_complete();
100 goto done;
103 /* Seek to the start of the track */
104 if (ci->seek_time == 1) {
105 ci->set_elapsed(0);
106 ci->seek_complete();
107 ci->seek_buffer(ci->id3->first_frame_offset);
108 elapsed = 0;
109 goto seek_start;
111 seek_frame_offset = (ci->seek_time * BITRATE) / (8 * FRAMESIZE);
112 frame_counter = seek_frame_offset;
113 ci->seek_buffer(ci->id3->first_frame_offset + seek_frame_offset* FRAMESIZE);
114 bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE);
115 elapsed = ci->seek_time;
117 ci->set_elapsed(elapsed);
118 ci->seek_complete();
121 res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE);
123 if(res != (int)FRAMESIZE) {
124 DEBUGF("codec error\n");
125 return CODEC_ERROR;
128 if(datasize)
129 ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, q.samples_per_frame / ci->id3->channels);
131 elapsed += (FRAMESIZE * 8) / BITRATE;
132 ci->set_elapsed(elapsed);
134 ci->advance_buffer(FRAMESIZE);
135 frame_counter++;
138 done:
139 if (ci->request_next_track())
140 goto next_track;
142 return CODEC_OK;