diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/atrac3_oma.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/atrac3_oma.c')
-rw-r--r-- | lib/rbcodec/codecs/atrac3_oma.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/atrac3_oma.c b/lib/rbcodec/codecs/atrac3_oma.c new file mode 100644 index 0000000000..50f7c8f163 --- /dev/null +++ b/lib/rbcodec/codecs/atrac3_oma.c | |||
@@ -0,0 +1,153 @@ | |||
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 <string.h> | ||
23 | |||
24 | #include "logf.h" | ||
25 | #include "codeclib.h" | ||
26 | #include "inttypes.h" | ||
27 | #include "libatrac/atrac3.h" | ||
28 | |||
29 | CODEC_HEADER | ||
30 | |||
31 | #define FRAMESIZE ci->id3->bytesperframe | ||
32 | #define BITRATE ci->id3->bitrate | ||
33 | |||
34 | static ATRAC3Context q IBSS_ATTR; | ||
35 | |||
36 | /* this is the codec entry point */ | ||
37 | enum codec_status codec_main(enum codec_entry_call_reason reason) | ||
38 | { | ||
39 | /* Nothing to do */ | ||
40 | return CODEC_OK; | ||
41 | (void)reason; | ||
42 | } | ||
43 | |||
44 | /* this is called for each file to process */ | ||
45 | enum codec_status codec_run(void) | ||
46 | { | ||
47 | static size_t buff_size; | ||
48 | int datasize, res, frame_counter, total_frames, seek_frame_offset; | ||
49 | uint8_t *bit_buffer; | ||
50 | int elapsed = 0; | ||
51 | size_t resume_offset; | ||
52 | intptr_t param; | ||
53 | enum codec_command_action action = CODEC_ACTION_NULL; | ||
54 | |||
55 | if (codec_init()) { | ||
56 | DEBUGF("codec init failed\n"); | ||
57 | return CODEC_ERROR; | ||
58 | } | ||
59 | |||
60 | resume_offset = ci->id3->offset; | ||
61 | |||
62 | codec_set_replaygain(ci->id3); | ||
63 | ci->memset(&q,0,sizeof(ATRAC3Context)); | ||
64 | |||
65 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); | ||
66 | ci->configure(DSP_SET_SAMPLE_DEPTH, 17); /* Remark: atrac3 uses s15.0 by default, s15.2 was hacked. */ | ||
67 | ci->configure(DSP_SET_STEREO_MODE, ci->id3->channels == 1 ? | ||
68 | STEREO_MONO : STEREO_NONINTERLEAVED); | ||
69 | |||
70 | ci->seek_buffer(0); | ||
71 | |||
72 | res = atrac3_decode_init(&q, ci->id3); | ||
73 | if(res < 0) { | ||
74 | DEBUGF("failed to initialize OMA atrac decoder\n"); | ||
75 | return CODEC_ERROR; | ||
76 | } | ||
77 | |||
78 | total_frames = (ci->id3->filesize - ci->id3->first_frame_offset) / FRAMESIZE; | ||
79 | frame_counter = 0; | ||
80 | |||
81 | /* check for a mid-track resume and force a seek time accordingly */ | ||
82 | if(resume_offset > ci->id3->first_frame_offset) { | ||
83 | resume_offset -= ci->id3->first_frame_offset; | ||
84 | /* calculate resume_offset in frames */ | ||
85 | resume_offset = (int)resume_offset / FRAMESIZE; | ||
86 | param = (int)resume_offset * ((FRAMESIZE * 8)/BITRATE); | ||
87 | action = CODEC_ACTION_SEEK_TIME; | ||
88 | } | ||
89 | else { | ||
90 | ci->set_elapsed(0); | ||
91 | ci->seek_buffer(ci->id3->first_frame_offset); | ||
92 | } | ||
93 | |||
94 | /* The main decoder loop */ | ||
95 | while(frame_counter < total_frames) | ||
96 | { | ||
97 | if (action == CODEC_ACTION_NULL) | ||
98 | action = ci->get_command(¶m); | ||
99 | |||
100 | if (action == CODEC_ACTION_HALT) | ||
101 | break; | ||
102 | |||
103 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); | ||
104 | |||
105 | if (action == CODEC_ACTION_SEEK_TIME) { | ||
106 | /* Do not allow seeking beyond the file's length */ | ||
107 | if ((unsigned) param > ci->id3->length) { | ||
108 | ci->set_elapsed(ci->id3->length); | ||
109 | ci->seek_complete(); | ||
110 | break; | ||
111 | } | ||
112 | |||
113 | /* Seek to the start of the track */ | ||
114 | if (param == 0) { | ||
115 | elapsed = 0; | ||
116 | ci->set_elapsed(0); | ||
117 | ci->seek_buffer(ci->id3->first_frame_offset); | ||
118 | ci->seek_complete(); | ||
119 | action = CODEC_ACTION_NULL; | ||
120 | continue; | ||
121 | } | ||
122 | |||
123 | seek_frame_offset = (param * BITRATE) / (8 * FRAMESIZE); | ||
124 | frame_counter = seek_frame_offset; | ||
125 | ci->seek_buffer(ci->id3->first_frame_offset + seek_frame_offset* FRAMESIZE); | ||
126 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); | ||
127 | elapsed = param; | ||
128 | ci->set_elapsed(elapsed); | ||
129 | ci->seek_complete(); | ||
130 | } | ||
131 | |||
132 | action = CODEC_ACTION_NULL; | ||
133 | |||
134 | res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE); | ||
135 | |||
136 | if(res != (int)FRAMESIZE) { | ||
137 | DEBUGF("codec error\n"); | ||
138 | return CODEC_ERROR; | ||
139 | } | ||
140 | |||
141 | if(datasize) | ||
142 | ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, | ||
143 | q.samples_per_frame / ci->id3->channels); | ||
144 | |||
145 | elapsed += (FRAMESIZE * 8) / BITRATE; | ||
146 | ci->set_elapsed(elapsed); | ||
147 | |||
148 | ci->advance_buffer(FRAMESIZE); | ||
149 | frame_counter++; | ||
150 | } | ||
151 | |||
152 | return CODEC_OK; | ||
153 | } | ||