diff options
Diffstat (limited to 'apps/codecs/vorbis.c')
-rw-r--r-- | apps/codecs/vorbis.c | 97 |
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 | ||
24 | CODEC_HEADER | 24 | CODEC_HEADER |
25 | 25 | ||
26 | static 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 | ||
30 | size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource) | 28 | size_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 | ||
36 | int initial_seek_handler(void *datasource, ogg_int64_t offset, int whence) | 34 | int 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) | |||
67 | long tell_handler(void *datasource) | 65 | long 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 | ||
101 | extern char iramcopy[]; | ||
102 | extern char iramstart[]; | ||
103 | extern char iramend[]; | ||
104 | extern char iedata[]; | ||
105 | extern char iend[]; | ||
106 | #endif | ||
107 | |||
108 | /* this is the codec entry point */ | 98 | /* this is the codec entry point */ |
109 | enum codec_status codec_start(struct codec_api *api) | 99 | enum 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. */ |
145 | next_track: | 128 | next_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 | ||
246 | done: | 229 | done: |
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; |