Mercurial > audlegacy-plugins
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 } |