comparison src/cdaudio-ng/cdaudio-ng.c @ 1123:edf2a1f1e58b trunk

[svn] Implemented DAE feature (enabled by default)
author zither
date Sat, 26 May 2007 09:21:13 -0700
parents 334afe46961c
children 4a5d64c395f5
comparison
equal deleted inserted replaced
1122:f1571687dca1 1123:edf2a1f1e58b
1 1
2 /* 2 /*
3 todo: 3 todo:
4 - if any cdio_* returns an error, stop playing immediately 4 - move stuff into cdaudio-ng.h
5 - vis_pcm...?!
6 - limit cd read speed
7 - cddb
8 - dialogs
9 - remove //'s & todo's
10 - additional comments
5 */ 11 */
6 12
7 #include <string.h> 13 #include <string.h>
8 #include <stdlib.h> 14 #include <stdlib.h>
9 #include <unistd.h> 15 #include <unistd.h>
20 26
21 #include <glib.h> 27 #include <glib.h>
22 28
23 #include <audacious/i18n.h> 29 #include <audacious/i18n.h>
24 #include <audacious/configdb.h> 30 #include <audacious/configdb.h>
31 #include <audacious/plugin.h>
25 #include <audacious/util.h> 32 #include <audacious/util.h>
26 #include <audacious/titlestring.h>
27 #include <audacious/output.h> 33 #include <audacious/output.h>
28 34
29 #define DEF_STRING_LEN 256 35 #define DEF_STRING_LEN 256
36 #define CDROM_DIR "cdda://default"
37 #define CDDA_DAE_FRAMES 8
30 38
31 39
32 typedef struct { 40 typedef struct {
33 41
34 char performer[DEF_STRING_LEN]; 42 char performer[DEF_STRING_LEN];
35 char name[DEF_STRING_LEN]; 43 char name[DEF_STRING_LEN];
36 char genre[DEF_STRING_LEN]; 44 char genre[DEF_STRING_LEN];
37 int startlsn; 45 lsn_t startlsn;
38 int endlsn; 46 lsn_t endlsn;
39 47
40 } trackinfo_t; 48 } trackinfo_t;
49
50 typedef struct {
51
52 lsn_t startlsn;
53 lsn_t endlsn;
54 lsn_t currlsn;
55 lsn_t seektime; /* in miliseconds */
56 InputPlayback *pplayback;
57 GThread *thread;
58
59 } dae_params_t;
41 60
42 61
43 static int firsttrackno = -1; 62 static int firsttrackno = -1;
44 static int lasttrackno = -1; 63 static int lasttrackno = -1;
45 static cdrom_drive_t *pcdrom_drive = NULL; 64 static CdIo_t *pcdio = NULL;
46 static trackinfo_t *trackinfo = NULL; 65 static trackinfo_t *trackinfo = NULL;
47 static char album_name[DEF_STRING_LEN]; 66 static char album_name[DEF_STRING_LEN];
48 static gboolean use_dao = FALSE; 67 static gboolean use_dae = TRUE;
49 static gboolean is_paused = FALSE; 68 static gboolean is_paused = FALSE;
50 static int playing_track = -1; 69 static int playing_track = -1;
70 static dae_params_t *pdae_params = NULL;
51 71
52 72
53 static void cdaudio_init(); 73 static void cdaudio_init();
54 static void cdaudio_about(); 74 static void cdaudio_about();
55 static void cdaudio_configure(); 75 static void cdaudio_configure();
65 static void cdaudio_cleanup(); 85 static void cdaudio_cleanup();
66 static void cdaudio_get_song_info(gchar *filename, gchar **title, gint *length); 86 static void cdaudio_get_song_info(gchar *filename, gchar **title, gint *length);
67 static void cdaudio_file_info_box(gchar *filename); 87 static void cdaudio_file_info_box(gchar *filename);
68 static TitleInput *cdaudio_get_song_tuple(gchar *filename); 88 static TitleInput *cdaudio_get_song_tuple(gchar *filename);
69 89
90 static void *dae_playing_thread_core(dae_params_t *pdae_params);
70 static int calculate_track_length(int startlsn, int endlsn); 91 static int calculate_track_length(int startlsn, int endlsn);
71 static int find_trackno_from_filename(char *filename); 92 static int find_trackno_from_filename(char *filename);
93 static void cleanup_on_error();
72 94
73 /* 95 /*
74 static int calculate_digit_sum(int n); 96 static int calculate_digit_sum(int n);
75 static unsigned long calculate_cddb_discid(); 97 static unsigned long calculate_cddb_discid();
76 */ 98 */
77 99
78 100
79 static InputPlugin inputplugin = { 101 static InputPlugin inputplugin = {
80 NULL, 102 NULL,
81 NULL, 103 NULL,
82 "Zither's CD Audio Plugin", 104 "CD Audio Plugin NG",
83 cdaudio_init, 105 cdaudio_init,
84 cdaudio_about, 106 cdaudio_about,
85 cdaudio_configure, 107 cdaudio_configure,
86 cdaudio_is_our_file, 108 cdaudio_is_our_file,
87 cdaudio_scan_dir, 109 cdaudio_scan_dir,
106 128
107 InputPlugin *cdaudio_iplist[] = { &inputplugin, NULL }; 129 InputPlugin *cdaudio_iplist[] = { &inputplugin, NULL };
108 130
109 DECLARE_PLUGIN(cdaudio, NULL, NULL, cdaudio_iplist, NULL, NULL, NULL, NULL); 131 DECLARE_PLUGIN(cdaudio, NULL, NULL, cdaudio_iplist, NULL, NULL, NULL, NULL);
110 132
133
111 void cdaudio_init() 134 void cdaudio_init()
112 { 135 {
113 cdio_init(); 136 if (!cdio_init()) {
137 fprintf(stderr, "cdaudio-ng: failed to initialize cdio subsystem\n");
138 cleanup_on_error();
139 return;
140 }
114 } 141 }
115 142
116 void cdaudio_about() 143 void cdaudio_about()
117 { 144 {
118 } 145 }
121 { 148 {
122 } 149 }
123 150
124 gint cdaudio_is_our_file(gchar *filename) 151 gint cdaudio_is_our_file(gchar *filename)
125 { 152 {
126 printf("is_our_file(\"%s\")\n", filename);
127 if ((filename != NULL) && strlen(filename) > 4 && (!strcasecmp(filename + strlen(filename) - 4, ".cda"))) { 153 if ((filename != NULL) && strlen(filename) > 4 && (!strcasecmp(filename + strlen(filename) - 4, ".cda"))) {
128 if (pcdrom_drive == NULL) { /* no CD information yet */ 154 /* no CD information yet */
129 printf("No CD information, rescanning\n"); 155 if (pcdio == NULL) {
130 cdaudio_scan_dir("/mnt/cdrom"); // todo: :) 156 printf("cdaudio-ng: no cd information, scanning\n");
131 } 157 cdaudio_scan_dir(CDROM_DIR);
132 158 }
133 if (cdio_get_media_changed(pcdrom_drive->p_cdio)) { 159
134 printf("CD changed, rescanning\n"); 160 /* reload the cd information if the media has changed */
135 cdaudio_scan_dir("/mnt/cdrom"); // todo: change the hardcoded path 161 if (cdio_get_media_changed(pcdio)) {
136 } 162 printf("cdaudio-ng: cd changed, rescanning\n");
137 163 cdaudio_scan_dir(CDROM_DIR);
138 return 1; 164 }
165
166 /* check if the requested track actually exists on the current audio cd */
167 int trackno = find_trackno_from_filename(filename);
168 if (trackno < firsttrackno || trackno > lasttrackno)
169 return FALSE;
170
171 return TRUE;
139 } 172 }
140 else 173 else
141 return 0; 174 return FALSE;
142 } 175 }
143 176
144 GList *cdaudio_scan_dir(gchar *dirname) 177 GList *cdaudio_scan_dir(gchar *dirname)
145 { 178 {
146 printf("scan_dir(\"%s\")\n", dirname); 179 /* if the given dirname does not belong to us, we return NULL */
147 180 if (strstr(dirname, CDROM_DIR) == NULL)
148 if (strstr(dirname, "/mnt/cdrom") == NULL) // todo: replace this with a more standardised string
149 return NULL; 181 return NULL;
150 182
151 /* find the first available, audio capable, cd drive */ 183 /* find the first available, audio capable, cd drive */
152 char **ppcd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false); 184 char **ppcd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false);
153 if (ppcd_drives != NULL) { /* we have at least one audio capable cd drive */ 185 if (ppcd_drives != NULL) { /* we have at least one audio capable cd drive */
154 pcdrom_drive = cdio_cddap_identify(*ppcd_drives, 1, NULL); 186 pcdio = cdio_open(*ppcd_drives, DRIVER_UNKNOWN);
155 } 187 if (pcdio == NULL) {
156 else { 188 fprintf(stderr, "cdaudio-ng: failed to open cd\n");
157 printf("Unable find or access a CD-ROM drive with an audio CD in it.\n"); 189 cleanup_on_error();
190 return NULL;
191 }
192 }
193 else {
194 fprintf(stderr, "cdaudio-ng: unable find or access a cdda capable drive\n");
195 cleanup_on_error();
158 return NULL; 196 return NULL;
159 } 197 }
160 cdio_free_device_list(ppcd_drives); 198 cdio_free_device_list(ppcd_drives);
161 199
162 /* get track information */ 200 /* get track information */
201 cdrom_drive_t *pcdrom_drive = cdio_cddap_identify_cdio(pcdio, 1, NULL); // todo : check return / NULL
163 firsttrackno = cdio_get_first_track_num(pcdrom_drive->p_cdio); 202 firsttrackno = cdio_get_first_track_num(pcdrom_drive->p_cdio);
164 lasttrackno = cdio_get_last_track_num(pcdrom_drive->p_cdio); 203 lasttrackno = cdio_get_last_track_num(pcdrom_drive->p_cdio);
204 if (firsttrackno == CDIO_INVALID_TRACK || lasttrackno == CDIO_INVALID_TRACK) {
205 fprintf(stderr, "cdaudio-ng: failed to retrieve first/last track number");
206 cleanup_on_error();
207 return NULL;
208 }
165 209
166 /* add track "file" names to the list */ 210 /* add track "file" names to the list */
167 GList *list = NULL; 211 GList *list = NULL;
168 if (trackinfo != NULL) 212 if (trackinfo != NULL) /* if a previously allocated track information exists, we free it */
169 free(trackinfo); 213 free(trackinfo);
170 trackinfo = (trackinfo_t *) malloc(sizeof(trackinfo_t) * (lasttrackno + 1)); 214 trackinfo = (trackinfo_t *) malloc(sizeof(trackinfo_t) * (lasttrackno + 1));
171 int trackno; 215 int trackno;
172 for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { 216 for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) {
173 list = g_list_append(list, g_strdup_printf("track%02u.cda", trackno)); 217 list = g_list_append(list, g_strdup_printf("track%02u.cda", trackno));
187 if (strlen(trackinfo[trackno].name) == 0) 231 if (strlen(trackinfo[trackno].name) == 0)
188 sprintf(trackinfo[trackno].name, "CD Audio Track %02u", trackno); 232 sprintf(trackinfo[trackno].name, "CD Audio Track %02u", trackno);
189 233
190 trackinfo[trackno].startlsn = cdio_get_track_lsn(pcdrom_drive->p_cdio, trackno); 234 trackinfo[trackno].startlsn = cdio_get_track_lsn(pcdrom_drive->p_cdio, trackno);
191 trackinfo[trackno].endlsn = cdio_get_track_last_lsn(pcdrom_drive->p_cdio, trackno); 235 trackinfo[trackno].endlsn = cdio_get_track_last_lsn(pcdrom_drive->p_cdio, trackno);
236
237 if (trackinfo[trackno].startlsn == CDIO_INVALID_LSN || trackinfo[trackno].endlsn == CDIO_INVALID_LSN) {
238 fprintf(stderr, "cdaudio-ng: failed to retrieve stard/end lsn for track %d\n", trackno);
239 g_list_free(list);
240 cleanup_on_error();
241 return NULL;
242 }
192 } 243 }
193 244
194 return list; 245 return list;
195 } 246 }
196 247
197 void cdaudio_play_file(InputPlayback *pinputplayback) 248 void cdaudio_play_file(InputPlayback *pinputplayback)
198 { 249 {
199 printf("play_file(\"%s\")\n", pinputplayback->filename);
200
201 if (trackinfo == NULL) { 250 if (trackinfo == NULL) {
202 printf("No CD information, rescanning\n"); 251 printf("cdaudio-ng: no cd information, scanning\n");
203 cdaudio_scan_dir("/mnt/cdrom"); // todo: change the hardcoded path 252 cdaudio_scan_dir(CDROM_DIR);
204 } 253 }
205 254
206 if (cdio_get_media_changed(pcdrom_drive->p_cdio)) { 255 if (cdio_get_media_changed(pcdio)) {
207 printf("CD changed, rescanning\n"); 256 printf("cdaudio-ng: cd changed, rescanning\n");
208 cdaudio_scan_dir("/mnt/cdrom"); // todo: change the hardcoded path 257 cdaudio_scan_dir(CDROM_DIR);
209 } 258 }
210 259
211 int trackno = find_trackno_from_filename(pinputplayback->filename); 260 int trackno = find_trackno_from_filename(pinputplayback->filename);
212 if (trackno < firsttrackno || trackno > lasttrackno) 261 if (trackno < firsttrackno || trackno > lasttrackno) {
262 fprintf(stderr, "cdaudio-ng: trackno %d should be between %d and %d\n", trackno, firsttrackno, lasttrackno);
263 cleanup_on_error();
213 return; 264 return;
214 265 }
215 msf_t startmsf, endmsf;
216 cdio_lsn_to_msf(trackinfo[trackno].startlsn, &startmsf);
217 cdio_lsn_to_msf(trackinfo[trackno].endlsn, &endmsf);
218 cdio_audio_play_msf(pcdrom_drive->p_cdio, &startmsf, &endmsf);
219 266
220 pinputplayback->playing = TRUE; 267 pinputplayback->playing = TRUE;
221 playing_track = trackno; 268 playing_track = trackno;
222 269 is_paused = FALSE;
270
271 if (use_dae) {
272 if (pdae_params != NULL) {
273 fprintf(stderr, "cdaudio-ng: dae playback seems to be already started\n");
274 return;
275 }
276
277 if (pinputplayback->output->open_audio(FMT_S16_LE, 44100, 2) == 0) {
278 fprintf(stderr, "cdaudio-ng: failed open audio output\n");
279 cleanup_on_error();
280 return;
281 }
282
283 pdae_params = (dae_params_t *) malloc(sizeof(dae_params_t));
284 pdae_params->startlsn = trackinfo[trackno].startlsn;
285 pdae_params->endlsn = trackinfo[trackno].endlsn;
286 pdae_params->pplayback = pinputplayback;
287 pdae_params->seektime = -1;
288 pdae_params->currlsn = trackinfo[trackno].startlsn;
289 pdae_params->thread = g_thread_create((GThreadFunc) dae_playing_thread_core, pdae_params, TRUE, NULL);
290 }
291 else {
292 msf_t startmsf, endmsf;
293 cdio_lsn_to_msf(trackinfo[trackno].startlsn, &startmsf);
294 cdio_lsn_to_msf(trackinfo[trackno].endlsn, &endmsf);
295 if (cdio_audio_play_msf(pcdio, &startmsf, &endmsf) != DRIVER_OP_SUCCESS) {
296 fprintf(stderr, "cdaudio-ng: failed to play analog audio cd\n");
297 cleanup_on_error();
298 return;
299 }
300 }
301
223 char title[DEF_STRING_LEN]; 302 char title[DEF_STRING_LEN];
224 303
225 if (strlen(trackinfo[trackno].performer) > 0) { 304 if (strlen(trackinfo[trackno].performer) > 0) {
226 strcpy(title, trackinfo[trackno].performer); 305 strcpy(title, trackinfo[trackno].performer);
227 strcat(title, " - "); 306 strcat(title, " - ");
228 } 307 }
229 else 308 else
230 strcpy(title, ""); 309 strcpy(title, "");
231 strcat(title, trackinfo[trackno].name); 310 strcat(title, trackinfo[trackno].name);
232 311
233 inputplugin.set_info(title, calculate_track_length(trackinfo[trackno].startlsn, trackinfo[trackno].endlsn), 128000, 44100, 2); 312 inputplugin.set_info(title, calculate_track_length(trackinfo[trackno].startlsn, trackinfo[trackno].endlsn), 128000, 44100, 2);
234 } 313 }
235 314
236 void cdaudio_stop(InputPlayback *pinputplayback) 315 void cdaudio_stop(InputPlayback *pinputplayback)
237 { 316 {
238 printf("stop(\"%s\")\n", pinputplayback->filename);
239
240 cdio_audio_stop(pcdrom_drive->p_cdio);
241 pinputplayback->playing = FALSE; 317 pinputplayback->playing = FALSE;
242 playing_track = -1; 318 playing_track = -1;
319 is_paused = FALSE;
320
321 if (use_dae) {
322 if (pdae_params != NULL) {
323 g_thread_join(pdae_params->thread);
324 free(pdae_params);
325 pdae_params = NULL;
326 }
327 }
328 else {
329 if (cdio_audio_stop(pcdio) != DRIVER_OP_SUCCESS) {
330 fprintf(stderr, "cdaudio-ng: failed to stop analog cd\n");
331 cleanup_on_error();
332 return;
333 }
334 }
243 } 335 }
244 336
245 void cdaudio_pause(InputPlayback *pinputplayback, gshort paused) 337 void cdaudio_pause(InputPlayback *pinputplayback, gshort paused)
246 { 338 {
247 if (!is_paused) { 339 if (!is_paused) {
248 is_paused = TRUE; 340 is_paused = TRUE;
249 cdio_audio_pause(pcdrom_drive->p_cdio); 341 if (!use_dae)
342 if (cdio_audio_pause(pcdio) != DRIVER_OP_SUCCESS) {
343 fprintf(stderr, "cdaudio-ng: failed to pause analog cd\n");
344 cleanup_on_error();
345 return;
346 }
250 } 347 }
251 else { 348 else {
252 is_paused = FALSE; 349 is_paused = FALSE;
253 cdio_audio_resume(pcdrom_drive->p_cdio); 350 if (!use_dae)
351 if (cdio_audio_resume(pcdio) != DRIVER_OP_SUCCESS) {
352 fprintf(stderr, "cdaudio-ng: failed to resume analog cd\n");
353 cleanup_on_error();
354 return;
355 }
254 } 356 }
255 } 357 }
256 358
257 void cdaudio_seek(InputPlayback *pinputplayback, gint time) 359 void cdaudio_seek(InputPlayback *pinputplayback, gint time)
258 { 360 {
259 printf("seek(%d)\n", time);
260 if (playing_track == -1) 361 if (playing_track == -1)
261 return; 362 return;
262 363
263 int lsnoffs = (time * 75); 364 if (use_dae) {
264 int startlsn = trackinfo[playing_track].startlsn + lsnoffs; 365 if (pdae_params != NULL) {
265 366 pdae_params->seektime = time * 1000;
266 msf_t startmsf, endmsf; 367 }
267 cdio_lsn_to_msf(startlsn, &startmsf); 368 }
268 cdio_lsn_to_msf(trackinfo[playing_track].endlsn, &endmsf); 369 else {
269 cdio_audio_play_msf(pcdrom_drive->p_cdio, &startmsf, &endmsf); 370 int newstartlsn = trackinfo[playing_track].startlsn + time * 75;
371 msf_t startmsf, endmsf;
372 cdio_lsn_to_msf(newstartlsn, &startmsf);
373 cdio_lsn_to_msf(trackinfo[playing_track].endlsn, &endmsf);
374
375 if (cdio_audio_play_msf(pcdio, &startmsf, &endmsf) != DRIVER_OP_SUCCESS) {
376 fprintf(stderr, "cdaudio-ng: failed to play analog cd\n");
377 cleanup_on_error();
378 return;
379 }
380 }
270 } 381 }
271 382
272 gint cdaudio_get_time(InputPlayback *pinputplayback) 383 gint cdaudio_get_time(InputPlayback *pinputplayback)
273 { 384 {
274 if (playing_track == -1) 385 if (playing_track == -1)
275 return -1; 386 return -1;
276 387
277 cdio_subchannel_t subchannel; 388 if (!use_dae) {
278 cdio_audio_read_subchannel(pcdrom_drive->p_cdio, &subchannel); 389 cdio_subchannel_t subchannel;
279 int currentlsn = cdio_msf_to_lsn(&subchannel.abs_addr); 390 if (cdio_audio_read_subchannel(pcdio, &subchannel) != DRIVER_OP_SUCCESS) {
280 391 fprintf(stderr, "cdaudio-ng: failed to read analog cd subchannel\n");
281 /* check to see if we have reached the end of the song */ 392 cleanup_on_error();
282 if (currentlsn == trackinfo[playing_track].endlsn) { 393 return -1;
283 cdaudio_stop(pinputplayback); 394 }
284 return -1; 395 int currlsn = cdio_msf_to_lsn(&subchannel.abs_addr);
285 } 396
286 397 /* check to see if we have reached the end of the song */
287 int seconds = calculate_track_length(trackinfo[playing_track].startlsn, currentlsn); 398 if (currlsn == trackinfo[playing_track].endlsn) {
288 // printf("%d\n", seconds); 399 cdaudio_stop(pinputplayback);
289 return seconds; 400 return -1;
401 }
402
403 return calculate_track_length(trackinfo[playing_track].startlsn, currlsn);
404 }
405 else {
406 if (pdae_params != NULL)
407 return pinputplayback->output->output_time();
408 else
409 return -1;
410 }
290 } 411 }
291 412
292 gint cdaudio_get_volume(gint *l, gint *r) 413 gint cdaudio_get_volume(gint *l, gint *r)
293 { 414 {
294 // printf("get_volume()\n"); 415 if (use_dae) {
295 416 *l = *r = 0;
296 cdio_audio_volume_t volume;; 417 return FALSE;
297 cdio_audio_set_volume(pcdrom_drive->p_cdio, &volume); 418 }
298 *l = volume.level[0]; 419 else {
299 *r = volume.level[1]; 420 cdio_audio_volume_t volume;
300 421 if (cdio_audio_get_volume(pcdio, &volume) != DRIVER_OP_SUCCESS) {
301 return 0; 422 fprintf(stderr, "cdaudio-ng: failed to retrieve analog cd volume\n");
423 cleanup_on_error();
424 *l = *r = 0;
425 return FALSE;
426 }
427 *l = volume.level[0];
428 *r = volume.level[1];
429
430 return TRUE;
431 }
302 } 432 }
303 433
304 gint cdaudio_set_volume(gint l, gint r) 434 gint cdaudio_set_volume(gint l, gint r)
305 { 435 {
306 printf("set_volume(%d, %d)\n", l, r); 436 if (use_dae) {
307 437 return FALSE;
308 cdio_audio_volume_t volume = {{l, r, 0, 0}}; 438 }
309 cdio_audio_set_volume(pcdrom_drive->p_cdio, &volume); 439 else {
310 440 cdio_audio_volume_t volume = {{l, r, 0, 0}};
311 return 0; 441 if (cdio_audio_set_volume(pcdio, &volume) != DRIVER_OP_SUCCESS) {
442 fprintf(stderr, "cdaudio-ng: failed to set analog cd volume\n");
443 cleanup_on_error();
444 return FALSE;
445 }
446
447 return TRUE;
448 }
312 } 449 }
313 450
314 void cdaudio_cleanup() 451 void cdaudio_cleanup()
315 { 452 {
316 cdio_destroy(pcdrom_drive->p_cdio); 453 if (pcdio!= NULL) {
454 if (playing_track != -1 && !use_dae)
455 cdio_audio_stop(pcdio);
456 cdio_destroy(pcdio);
457 pcdio = NULL;
458 }
459 if (trackinfo != NULL) {
460 free(trackinfo);
461 trackinfo = NULL;
462 }
463 playing_track = -1;
317 } 464 }
318 465
319 void cdaudio_get_song_info(gchar *filename, gchar **title, gint *length) 466 void cdaudio_get_song_info(gchar *filename, gchar **title, gint *length)
320 { 467 {
321 printf("get_song_info(\"%s\")\n", filename); 468 fprintf(stderr, "DEBUG: get_song_info(\"%s\")\n", filename);
322 } 469 }
323 470
324 void cdaudio_file_info_box(gchar *filename) 471 void cdaudio_file_info_box(gchar *filename)
325 { 472 {
326 473 fprintf(stderr, "DEBUG: file_info_box(\"%s\")\n", filename);
327 } 474 }
328 475
329 TitleInput *cdaudio_get_song_tuple(gchar *filename) 476 TitleInput *cdaudio_get_song_tuple(gchar *filename)
330 { 477 {
331 printf("get_song_tuple(\"%s\")\n", filename);
332
333 TitleInput *tuple = bmp_title_input_new(); 478 TitleInput *tuple = bmp_title_input_new();
334 479
335 /* return information about the requested track */ 480 /* return information about the requested track */
336 int trackno = find_trackno_from_filename(filename); 481 int trackno = find_trackno_from_filename(filename);
337 if (trackno < firsttrackno || trackno > lasttrackno) 482 if (trackno < firsttrackno || trackno > lasttrackno)
387 532
388 return ((n % 0xFF) << 24 | t << 8 | (lasttrackno - firsttrackno + 1)); 533 return ((n % 0xFF) << 24 | t << 8 | (lasttrackno - firsttrackno + 1));
389 } 534 }
390 */ 535 */
391 536
537 void *dae_playing_thread_core(dae_params_t *pdae_params)
538 {
539 unsigned char *buffer = (unsigned char *) malloc(CDDA_DAE_FRAMES * CDIO_CD_FRAMESIZE_RAW);
540
541 cdio_lseek(pcdio, pdae_params->startlsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET);
542
543 gboolean output_paused = FALSE;
544
545 while (pdae_params->pplayback->playing) {
546 /* handle pause status */
547 if (is_paused) {
548 if (!output_paused) {
549 pdae_params->pplayback->output->pause(TRUE);
550 output_paused = TRUE;
551 }
552 usleep(1000);
553 continue;
554 }
555 else
556 if (output_paused) {
557 pdae_params->pplayback->output->pause(FALSE);
558 output_paused = FALSE;
559 }
560
561 /* check if we have to seek */
562 if (pdae_params->seektime != -1) {
563 int newlsn = pdae_params->startlsn + pdae_params->seektime * 75 / 1000;
564 cdio_lseek(pcdio, newlsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET);
565 pdae_params->pplayback->output->flush(pdae_params->seektime);
566 pdae_params->currlsn = newlsn;
567 pdae_params->seektime = -1;
568 }
569
570 /* compute the actual number of sectors to read */
571 int lsncount = CDDA_DAE_FRAMES <= (pdae_params->endlsn - pdae_params->currlsn + 1) ? CDDA_DAE_FRAMES : (pdae_params->endlsn - pdae_params->currlsn + 1);
572 /* check too see if we have reached the end of the song */
573 if (lsncount <= 0)
574 break;
575
576 if (cdio_read_audio_sectors(pcdio, buffer, pdae_params->currlsn, lsncount) != DRIVER_OP_SUCCESS) {
577 fprintf(stderr, "cdaudio-ng: failed to read audio sector\n");
578 /* ok, that's it, we go on */
579 }
580
581 int remainingbytes = lsncount * CDIO_CD_FRAMESIZE_RAW;
582 unsigned char *bytebuff = buffer;
583 while (pdae_params->pplayback->playing && remainingbytes > 0 && pdae_params->seektime == -1) {
584 /* compute the actual number of bytes to play */
585 int bytecount = CDIO_CD_FRAMESIZE_RAW <= remainingbytes ? CDIO_CD_FRAMESIZE_RAW : remainingbytes;
586 /* wait until the output buffer has enough room */
587 while (pdae_params->pplayback->playing && pdae_params->pplayback->output->buffer_free() < bytecount && pdae_params->seektime == -1)
588 usleep(1000);
589 /* play the sound :) */
590 if (pdae_params->pplayback->playing && pdae_params->seektime == -1)
591 produce_audio(pdae_params->pplayback->output->written_time(), FMT_S16_LE, 2, bytecount, bytebuff, &pdae_params->pplayback->playing);
592 remainingbytes -= bytecount;
593 bytebuff += bytecount;
594 }
595 pdae_params->currlsn += lsncount;
596 }
597
598 pdae_params->pplayback->playing = FALSE;
599 playing_track = -1;
600 is_paused = FALSE;
601
602 pdae_params->pplayback->output->close_audio();
603 free(buffer);
604
605 g_thread_exit(NULL);
606 return NULL;
607 }
608
392 int calculate_track_length(int startlsn, int endlsn) 609 int calculate_track_length(int startlsn, int endlsn)
393 { 610 {
394 return ((endlsn - startlsn + 1) * 1000) / 75; 611 return ((endlsn - startlsn + 1) * 1000) / 75;
395 } 612 }
396 613
402 char tracknostr[3]; 619 char tracknostr[3];
403 strncpy(tracknostr, filename + strlen(filename) - 6, 2); 620 strncpy(tracknostr, filename + strlen(filename) - 6, 2);
404 tracknostr[2] = '\0'; 621 tracknostr[2] = '\0';
405 return strtol(tracknostr, NULL, 10); 622 return strtol(tracknostr, NULL, 10);
406 } 623 }
624
625 void cleanup_on_error()
626 {
627 if (pcdio != NULL) {
628 if (playing_track != -1 && !use_dae)
629 cdio_audio_stop(pcdio);
630 }
631 if (trackinfo != NULL) {
632 free(trackinfo);
633 trackinfo = NULL;
634 }
635 playing_track = -1;
636 }