summaryrefslogtreecommitdiff
path: root/apps/codecs/vorbis.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/vorbis.c')
-rw-r--r--apps/codecs/vorbis.c97
1 files changed, 40 insertions, 57 deletions
diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c
index d08cb0e90d..ca4aa9dd12 100644
--- a/apps/codecs/vorbis.c
+++ b/apps/codecs/vorbis.c
@@ -23,14 +23,12 @@
23 23
24CODEC_HEADER 24CODEC_HEADER
25 25
26static struct codec_api *rb;
27
28/* Some standard functions and variables needed by Tremor */ 26/* Some standard functions and variables needed by Tremor */
29 27
30size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource) 28size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource)
31{ 29{
32 (void)datasource; 30 (void)datasource;
33 return rb->read_filebuf(ptr, nmemb*size); 31 return ci->read_filebuf(ptr, nmemb*size);
34} 32}
35 33
36int initial_seek_handler(void *datasource, ogg_int64_t offset, int whence) 34int initial_seek_handler(void *datasource, ogg_int64_t offset, int whence)
@@ -46,12 +44,12 @@ int seek_handler(void *datasource, ogg_int64_t offset, int whence)
46 (void)datasource; 44 (void)datasource;
47 45
48 if (whence == SEEK_CUR) { 46 if (whence == SEEK_CUR) {
49 offset += rb->curpos; 47 offset += ci->curpos;
50 } else if (whence == SEEK_END) { 48 } else if (whence == SEEK_END) {
51 offset += rb->filesize; 49 offset += ci->filesize;
52 } 50 }
53 51
54 if (rb->seek_buffer(offset)) { 52 if (ci->seek_buffer(offset)) {
55 return 0; 53 return 0;
56 } 54 }
57 55
@@ -67,7 +65,7 @@ int close_handler(void *datasource)
67long tell_handler(void *datasource) 65long tell_handler(void *datasource)
68{ 66{
69 (void)datasource; 67 (void)datasource;
70 return rb->curpos; 68 return ci->curpos;
71} 69}
72 70
73/* This sets the DSP parameters based on the current logical bitstream 71/* This sets the DSP parameters based on the current logical bitstream
@@ -81,32 +79,24 @@ bool vorbis_set_codec_parameters(OggVorbis_File *vf)
81 vi = ov_info(vf, -1); 79 vi = ov_info(vf, -1);
82 80
83 if (vi == NULL) { 81 if (vi == NULL) {
84 //rb->splash(HZ*2, true, "Vorbis Error"); 82 //ci->splash(HZ*2, true, "Vorbis Error");
85 return false; 83 return false;
86 } 84 }
87 85
88 rb->configure(DSP_SWITCH_FREQUENCY, (int *)rb->id3->frequency); 86 ci->configure(DSP_SWITCH_FREQUENCY, (int *)ci->id3->frequency);
89 codec_set_replaygain(rb->id3); 87 codec_set_replaygain(ci->id3);
90 88
91 if (vi->channels == 2) { 89 if (vi->channels == 2) {
92 rb->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED); 90 ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED);
93 } else if (vi->channels == 1) { 91 } else if (vi->channels == 1) {
94 rb->configure(DSP_SET_STEREO_MODE, (int *)STEREO_MONO); 92 ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_MONO);
95 } 93 }
96 94
97 return true; 95 return true;
98} 96}
99 97
100#ifdef USE_IRAM
101extern char iramcopy[];
102extern char iramstart[];
103extern char iramend[];
104extern char iedata[];
105extern char iend[];
106#endif
107
108/* this is the codec entry point */ 98/* this is the codec entry point */
109enum codec_status codec_start(struct codec_api *api) 99enum codec_status codec_main(void)
110{ 100{
111 ov_callbacks callbacks; 101 ov_callbacks callbacks;
112 OggVorbis_File vf; 102 OggVorbis_File vf;
@@ -122,16 +112,9 @@ enum codec_status codec_start(struct codec_api *api)
122 ogg_uint32_t vf_serialnos; 112 ogg_uint32_t vf_serialnos;
123 ogg_int64_t vf_pcmlengths[2]; 113 ogg_int64_t vf_pcmlengths[2];
124 114
125 rb = api; 115 ci->configure(DSP_SET_SAMPLE_DEPTH, (long *)24);
126 116 ci->configure(DSP_SET_CLIP_MAX, (long *)((1 << 24) - 1));
127 #ifdef USE_IRAM 117 ci->configure(DSP_SET_CLIP_MIN, (long *)-((1 << 24) - 1));
128 rb->memcpy(iramstart, iramcopy, iramend - iramstart);
129 rb->memset(iedata, 0, iend - iedata);
130 #endif
131
132 rb->configure(DSP_SET_SAMPLE_DEPTH, (long *)24);
133 rb->configure(DSP_SET_CLIP_MAX, (long *)((1 << 24) - 1));
134 rb->configure(DSP_SET_CLIP_MIN, (long *)-((1 << 24) - 1));
135 /* Note: These are sane defaults for these values. Perhaps 118 /* Note: These are sane defaults for these values. Perhaps
136 * they should be set differently based on quality setting 119 * they should be set differently based on quality setting
137 */ 120 */
@@ -139,17 +122,17 @@ enum codec_status codec_start(struct codec_api *api)
139 /* The chunk size below is magic. If set any lower, resume 122 /* The chunk size below is magic. If set any lower, resume
140 * doesn't work properly (ov_raw_seek() does the wrong thing). 123 * doesn't work properly (ov_raw_seek() does the wrong thing).
141 */ 124 */
142 rb->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*256)); 125 ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*256));
143 126
144/* We need to flush reserver memory every track load. */ 127/* We need to flush reserver memory every track load. */
145next_track: 128next_track:
146 if (codec_init(rb)) { 129 if (codec_init()) {
147 error = CODEC_ERROR; 130 error = CODEC_ERROR;
148 goto exit; 131 goto exit;
149 } 132 }
150 133
151 while (!*rb->taginfo_ready && !rb->stop_codec) 134 while (!*ci->taginfo_ready && !ci->stop_codec)
152 rb->sleep(1); 135 ci->sleep(1);
153 136
154 /* Create a decoder instance */ 137 /* Create a decoder instance */
155 callbacks.read_func = read_handler; 138 callbacks.read_func = read_handler;
@@ -158,14 +141,14 @@ next_track:
158 callbacks.close_func = close_handler; 141 callbacks.close_func = close_handler;
159 142
160 /* Open a non-seekable stream */ 143 /* Open a non-seekable stream */
161 error = ov_open_callbacks(rb, &vf, NULL, 0, callbacks); 144 error = ov_open_callbacks(ci, &vf, NULL, 0, callbacks);
162 145
163 /* If the non-seekable open was successful, we need to supply the missing 146 /* If the non-seekable open was successful, we need to supply the missing
164 * data to make it seekable. This is a hack, but it's reasonable since we 147 * data to make it seekable. This is a hack, but it's reasonable since we
165 * don't want to run the whole file through the buffer before we start 148 * don't want to run the whole file through the buffer before we start
166 * playing. Using Tremor's seekable open routine would cause us to do 149 * playing. Using Tremor's seekable open routine would cause us to do
167 * this, so we pretend not to be seekable at first. Then we fill in the 150 * this, so we pretend not to be seekable at first. Then we fill in the
168 * missing fields of vf with 1) information in rb->id3, and 2) info 151 * missing fields of vf with 1) information in ci->id3, and 2) info
169 * obtained by Tremor in the above ov_open call. 152 * obtained by Tremor in the above ov_open call.
170 * 153 *
171 * Note that this assumes there is only ONE logical Vorbis bitstream in our 154 * Note that this assumes there is only ONE logical Vorbis bitstream in our
@@ -179,40 +162,40 @@ next_track:
179 vf.pcmlengths = vf_pcmlengths; 162 vf.pcmlengths = vf_pcmlengths;
180 163
181 vf.offsets[0] = 0; 164 vf.offsets[0] = 0;
182 vf.offsets[1] = rb->id3->filesize; 165 vf.offsets[1] = ci->id3->filesize;
183 vf.dataoffsets[0] = vf.offset; 166 vf.dataoffsets[0] = vf.offset;
184 vf.pcmlengths[0] = 0; 167 vf.pcmlengths[0] = 0;
185 vf.pcmlengths[1] = rb->id3->samples; 168 vf.pcmlengths[1] = ci->id3->samples;
186 vf.serialnos[0] = vf.current_serialno; 169 vf.serialnos[0] = vf.current_serialno;
187 vf.callbacks.seek_func = seek_handler; 170 vf.callbacks.seek_func = seek_handler;
188 vf.seekable = 1; 171 vf.seekable = 1;
189 vf.end = rb->id3->filesize; 172 vf.end = ci->id3->filesize;
190 vf.ready_state = OPENED; 173 vf.ready_state = OPENED;
191 vf.links = 1; 174 vf.links = 1;
192 } else { 175 } else {
193 //rb->logf("ov_open: %d", error); 176 //ci->logf("ov_open: %d", error);
194 error = CODEC_ERROR; 177 error = CODEC_ERROR;
195 goto done; 178 goto done;
196 } 179 }
197 180
198 if (rb->id3->offset) { 181 if (ci->id3->offset) {
199 rb->advance_buffer(rb->id3->offset); 182 ci->advance_buffer(ci->id3->offset);
200 ov_raw_seek(&vf, rb->id3->offset); 183 ov_raw_seek(&vf, ci->id3->offset);
201 rb->set_elapsed(ov_time_tell(&vf)); 184 ci->set_elapsed(ov_time_tell(&vf));
202 rb->set_offset(ov_raw_tell(&vf)); 185 ci->set_offset(ov_raw_tell(&vf));
203 } 186 }
204 187
205 eof = 0; 188 eof = 0;
206 while (!eof) { 189 while (!eof) {
207 rb->yield(); 190 ci->yield();
208 if (rb->stop_codec || rb->new_track) 191 if (ci->stop_codec || ci->new_track)
209 break; 192 break;
210 193
211 if (rb->seek_time) { 194 if (ci->seek_time) {
212 if (ov_time_seek(&vf, rb->seek_time - 1)) { 195 if (ov_time_seek(&vf, ci->seek_time - 1)) {
213 //rb->logf("ov_time_seek failed"); 196 //ci->logf("ov_time_seek failed");
214 } 197 }
215 rb->seek_complete(); 198 ci->seek_complete();
216 } 199 }
217 200
218 /* Read host-endian signed 24-bit PCM samples */ 201 /* Read host-endian signed 24-bit PCM samples */
@@ -233,18 +216,18 @@ next_track:
233 } else if (n < 0) { 216 } else if (n < 0) {
234 DEBUGF("Error decoding frame\n"); 217 DEBUGF("Error decoding frame\n");
235 } else { 218 } else {
236 while (!rb->pcmbuf_insert_split(pcm[0], pcm[1], 219 while (!ci->pcmbuf_insert_split(pcm[0], pcm[1],
237 n*sizeof(ogg_int32_t))) { 220 n*sizeof(ogg_int32_t))) {
238 rb->sleep(1); 221 ci->sleep(1);
239 } 222 }
240 rb->set_offset(ov_raw_tell(&vf)); 223 ci->set_offset(ov_raw_tell(&vf));
241 rb->set_elapsed(ov_time_tell(&vf)); 224 ci->set_elapsed(ov_time_tell(&vf));
242 } 225 }
243 } 226 }
244 error = CODEC_OK; 227 error = CODEC_OK;
245 228
246done: 229done:
247 if (rb->request_next_track()) { 230 if (ci->request_next_track()) {
248 /* Clean things up for the next track */ 231 /* Clean things up for the next track */
249 vf.dataoffsets = NULL; 232 vf.dataoffsets = NULL;
250 vf.offsets = NULL; 233 vf.offsets = NULL;