comparison src/alac/plugin.c @ 3146:87b0c47089e5

alac: Various patches from Hans de Goede. (Closes #61)
author William Pitcock <nenolod@atheme.org>
date Sat, 09 May 2009 13:47:30 -0500
parents 3134a0987162
children d7eea4d29d4a
comparison
equal deleted inserted replaced
3145:76f5bcf547d5 3146:87b0c47089e5
54 54
55 static int input_opened = 0; 55 static int input_opened = 0;
56 56
57 gpointer decode_thread(void *args); 57 gpointer decode_thread(void *args);
58 static GThread *playback_thread; 58 static GThread *playback_thread;
59 static int going = 0;
60 static int seek_to = -1; 59 static int seek_to = -1;
61 60
62 extern void set_endian(); 61 extern void set_endian();
63 62
64 static void alac_about(void) 63 static void alac_about(void)
99 } 98 }
100 99
101 stream_destroy(input_stream); 100 stream_destroy(input_stream);
102 101
103 return TRUE; 102 return TRUE;
103 }
104
105 static int get_duration(demux_res_t *demux_res)
106 {
107 int i;
108 long long samples = 0;
109
110 for (i = 0; i < demux_res->num_time_to_samples; i++)
111 samples += demux_res->time_to_sample[i].sample_count *
112 demux_res->time_to_sample[i].sample_duration;
113
114 return (samples * 1000) / demux_res->sample_rate;
104 } 115 }
105 116
106 Tuple *build_aud_tuple_from_demux(demux_res_t *demux_res, char *path) 117 Tuple *build_aud_tuple_from_demux(demux_res_t *demux_res, char *path)
107 { 118 {
108 Tuple *ti = aud_tuple_new_from_filename(path); 119 Tuple *ti = aud_tuple_new_from_filename(path);
120 if (demux_res->tuple.day != NULL) 131 if (demux_res->tuple.day != NULL)
121 aud_tuple_associate_int(ti, FIELD_YEAR, NULL, atoi(demux_res->tuple.day)); 132 aud_tuple_associate_int(ti, FIELD_YEAR, NULL, atoi(demux_res->tuple.day));
122 133
123 aud_tuple_associate_string(ti, FIELD_CODEC, NULL, "Apple Lossless (ALAC)"); 134 aud_tuple_associate_string(ti, FIELD_CODEC, NULL, "Apple Lossless (ALAC)");
124 aud_tuple_associate_string(ti, FIELD_QUALITY, NULL, "lossless"); 135 aud_tuple_associate_string(ti, FIELD_QUALITY, NULL, "lossless");
136 aud_tuple_associate_int(ti, FIELD_LENGTH, NULL, get_duration(demux_res));
125 137
126 return ti; 138 return ti;
127 } 139 }
128 140
129 Tuple *build_tuple(char *filename) 141 Tuple *build_tuple(char *filename)
161 static InputPlayback *playback; 173 static InputPlayback *playback;
162 174
163 static void play_file(InputPlayback *data) 175 static void play_file(InputPlayback *data)
164 { 176 {
165 char *filename = data->filename; 177 char *filename = data->filename;
166 going = 1;
167 playback = data; 178 playback = data;
179 playback->playing = TRUE;
168 playback_thread = g_thread_self(); 180 playback_thread = g_thread_self();
169 playback->set_pb_ready(playback); 181 playback->set_pb_ready(playback);
170 decode_thread(filename); 182 decode_thread(filename);
171 } 183 }
172 184
173 static void stop(InputPlayback * data) 185 static void stop(InputPlayback * data)
174 { 186 {
175 going = 0; 187 playback->playing = FALSE;
176 g_thread_join(playback_thread); 188 g_thread_join(playback_thread);
177 data->output->close_audio(); 189 data->output->close_audio();
178 } 190 }
179 191
180 static void do_pause(InputPlayback *data, short paused) 192 static void do_pause(InputPlayback *data, short paused)
183 } 195 }
184 196
185 static void seek(InputPlayback * data, gint time) 197 static void seek(InputPlayback * data, gint time)
186 { 198 {
187 seek_to = time; 199 seek_to = time;
188 }
189
190 static int get_sample_info(demux_res_t *demux_res, uint32_t samplenum,
191 uint32_t *sample_duration,
192 uint32_t *sample_byte_size)
193 {
194 unsigned int duration_index_accum = 0;
195 unsigned int duration_cur_index = 0;
196
197 if (samplenum >= demux_res->num_sample_byte_sizes)
198 return 0;
199
200 if (!demux_res->num_time_to_samples)
201 return 0;
202
203 while ((demux_res->time_to_sample[duration_cur_index].sample_count + duration_index_accum)
204 <= samplenum)
205 {
206 duration_index_accum += demux_res->time_to_sample[duration_cur_index].sample_count;
207 duration_cur_index++;
208
209 if (duration_cur_index >= demux_res->num_time_to_samples)
210 return 0;
211 }
212
213 *sample_duration = demux_res->time_to_sample[duration_cur_index].sample_duration;
214 *sample_byte_size = demux_res->sample_byte_size[samplenum];
215
216 return 1;
217 } 200 }
218 201
219 void GetBuffer(demux_res_t *demux_res) 202 void GetBuffer(demux_res_t *demux_res)
220 { 203 {
221 unsigned long destBufferSize = 1024*16; /* 16kb buffer = 4096 frames = 1 alac sample */ 204 unsigned long destBufferSize = 1024*16; /* 16kb buffer = 4096 frames = 1 alac sample */
227 210
228 unsigned int i; 211 unsigned int i;
229 212
230 buffer = malloc(buffer_size); 213 buffer = malloc(buffer_size);
231 214
232 for (i = 0; i < demux_res->num_sample_byte_sizes && going == 1; i++) 215 for (i = 0; i < demux_res->num_sample_byte_sizes && playback->playing; i++)
233 { 216 {
234 uint32_t sample_duration;
235 uint32_t sample_byte_size; 217 uint32_t sample_byte_size;
236 218
237 int outputBytes; 219 int outputBytes;
238 220
239 #if 0 221 #if 0
251 seek_to = -1; 233 seek_to = -1;
252 } 234 }
253 #endif 235 #endif
254 236
255 /* just get one sample for now */ 237 /* just get one sample for now */
256 if (!get_sample_info(demux_res, i, 238 sample_byte_size = demux_res->sample_byte_size[i];
257 &sample_duration, &sample_byte_size))
258 return;
259 239
260 if (buffer_size < sample_byte_size) 240 if (buffer_size < sample_byte_size)
261 return; 241 return;
262 242
263 stream_read(demux_res->stream, sample_byte_size, buffer); 243 stream_read(demux_res->stream, sample_byte_size, buffer);
267 decode_frame(demux_res->alac, buffer, pDestBuffer, &outputBytes); 247 decode_frame(demux_res->alac, buffer, pDestBuffer, &outputBytes);
268 248
269 /* write */ 249 /* write */
270 bytes_read += outputBytes; 250 bytes_read += outputBytes;
271 251
272 playback->pass_audio(playback, FMT_S16_LE, demux_res->num_channels, outputBytes, pDestBuffer, &going); 252 playback->pass_audio(playback, FMT_S16_LE, demux_res->num_channels, outputBytes, pDestBuffer, &playback->playing);
273 } 253 }
274 254
275 free(buffer); 255 free(buffer);
276 free(pDestBuffer); 256 free(pDestBuffer);
277 } 257 }
295 DECLARE_PLUGIN(alac, NULL, NULL, alac_iplist, NULL, NULL, NULL, NULL, NULL); 275 DECLARE_PLUGIN(alac, NULL, NULL, alac_iplist, NULL, NULL, NULL, NULL, NULL);
296 276
297 gpointer decode_thread(void *args) 277 gpointer decode_thread(void *args)
298 { 278 {
299 demux_res_t demux_res; 279 demux_res_t demux_res;
300 gulong duration = 0; /* samples added up */
301 VFSFile *input_file; 280 VFSFile *input_file;
302 stream_t *input_stream; 281 stream_t *input_stream;
303 Tuple *ti; 282 Tuple *ti;
304 gchar *title; 283 gchar *title;
305 284
326 305
327 /* initialise the sound converter */ 306 /* initialise the sound converter */
328 demux_res.alac = create_alac(demux_res.sample_size, demux_res.num_channels); 307 demux_res.alac = create_alac(demux_res.sample_size, demux_res.num_channels);
329 alac_set_info(demux_res.alac, demux_res.codecdata); 308 alac_set_info(demux_res.alac, demux_res.codecdata);
330 309
331 /* Sample rates are multiples of 251?! Apple is *fucking* *insane*! -nenolod */
332 duration = (demux_res.num_sample_byte_sizes * (float)((1024 * demux_res.sample_size) - 1.0) /
333 (float)(demux_res.sample_rate / 251));
334
335 playback->output->open_audio(FMT_S16_LE, demux_res.sample_rate, demux_res.num_channels); 310 playback->output->open_audio(FMT_S16_LE, demux_res.sample_rate, demux_res.num_channels);
336 playback->set_params(playback, title, duration, -1, demux_res.sample_rate, demux_res.num_channels); 311 playback->set_params(playback, title, get_duration(&demux_res), -1, demux_res.sample_rate, demux_res.num_channels);
337 312
338 /* will convert the entire buffer */ 313 /* will convert the entire buffer */
339 GetBuffer(&demux_res); 314 GetBuffer(&demux_res);
340 315
341 going = 0; 316 if (playback->playing) {
317 playback->output->buffer_free();
318 playback->output->buffer_free();
319 while (playback->output->buffer_playing() && playback->playing)
320 g_usleep(100000);
321 }
342 322
343 stream_destroy(input_stream); 323 stream_destroy(input_stream);
344 324
345 if (input_opened) 325 if (input_opened)
346 aud_vfs_fclose(input_file); 326 aud_vfs_fclose(input_file);
347 327
348 playback->output->close_audio(); 328 playback->output->close_audio();
349 329
330 playback->playing = FALSE;
331
350 return NULL; 332 return NULL;
351 } 333 }