Mercurial > audlegacy-plugins
comparison src/cdaudio-ng/cdaudio-ng.c @ 1313:28df54b3eaea
Ejecting the cd while playing no longer crashes the player.
author | Calin Crisan ccrisan@gmail.com |
---|---|
date | Sat, 21 Jul 2007 03:48:57 +0300 |
parents | 2a7c9e0b9c0f |
children | b93270e2b7e4 |
comparison
equal
deleted
inserted
replaced
1312:c0b5b291bc64 | 1313:28df54b3eaea |
---|---|
1 | 1 |
2 /* | 2 /* |
3 todo: | 3 todo: |
4 - fileinfo dialog | |
5 - about dialog | 4 - about dialog |
6 */ | 5 */ |
7 | 6 |
8 #include <string.h> | 7 #include <string.h> |
9 #include <stdlib.h> | 8 #include <stdlib.h> |
47 static int playing_track = -1; | 46 static int playing_track = -1; |
48 static dae_params_t *pdae_params = NULL; | 47 static dae_params_t *pdae_params = NULL; |
49 static gboolean debug = FALSE; | 48 static gboolean debug = FALSE; |
50 static char cddb_server[DEF_STRING_LEN]; | 49 static char cddb_server[DEF_STRING_LEN]; |
51 static int cddb_port; | 50 static int cddb_port; |
51 static InputPlayback *pglobalinputplayback = NULL; | |
52 | 52 |
53 static void cdaudio_init(); | 53 static void cdaudio_init(); |
54 static void cdaudio_about(); | 54 static void cdaudio_about(); |
55 static void cdaudio_configure(); | 55 static void cdaudio_configure(); |
56 static gint cdaudio_is_our_file(gchar *filename); | 56 static gint cdaudio_is_our_file(gchar *filename); |
62 static gint cdaudio_get_time(InputPlayback *pinputplayback); | 62 static gint cdaudio_get_time(InputPlayback *pinputplayback); |
63 static gint cdaudio_get_volume(gint *l, gint *r); | 63 static gint cdaudio_get_volume(gint *l, gint *r); |
64 static gint cdaudio_set_volume(gint l, gint r); | 64 static gint cdaudio_set_volume(gint l, gint r); |
65 static void cdaudio_cleanup(); | 65 static void cdaudio_cleanup(); |
66 static void cdaudio_get_song_info(gchar *filename, gchar **title, gint *length); | 66 static void cdaudio_get_song_info(gchar *filename, gchar **title, gint *length); |
67 static void cdaudio_file_info_box(gchar *filename); | |
68 static TitleInput *cdaudio_get_song_tuple(gchar *filename); | 67 static TitleInput *cdaudio_get_song_tuple(gchar *filename); |
69 | 68 |
70 static void *dae_playing_thread_core(dae_params_t *pdae_params); | 69 static void *dae_playing_thread_core(dae_params_t *pdae_params); |
71 static int calculate_track_length(int startlsn, int endlsn); | 70 static int calculate_track_length(int startlsn, int endlsn); |
72 static int find_trackno_from_filename(char *filename); | 71 static int find_trackno_from_filename(char *filename); |
94 NULL, | 93 NULL, |
95 NULL, | 94 NULL, |
96 NULL, | 95 NULL, |
97 NULL, | 96 NULL, |
98 cdaudio_get_song_info, | 97 cdaudio_get_song_info, |
99 NULL /*cdaudio_file_info_box*/, // todo: implement a file info dialog | 98 NULL, |
100 NULL, | 99 NULL, |
101 cdaudio_get_song_tuple | 100 cdaudio_get_song_tuple |
102 }; | 101 }; |
103 | 102 |
104 InputPlugin *cdaudio_iplist[] = { &inputplugin, NULL }; | 103 InputPlugin *cdaudio_iplist[] = { &inputplugin, NULL }; |
182 printf("cdaudio-ng: no cd information, scanning\n"); | 181 printf("cdaudio-ng: no cd information, scanning\n"); |
183 cdaudio_scan_dir(CDDA_DEFAULT); | 182 cdaudio_scan_dir(CDDA_DEFAULT); |
184 } | 183 } |
185 | 184 |
186 /* reload the cd information if the media has changed */ | 185 /* reload the cd information if the media has changed */ |
187 if (cdio_get_media_changed(pcdio)) { | 186 if (cdio_get_media_changed(pcdio) && pcdio != NULL) { |
188 if (debug) | 187 if (debug) |
189 printf("cdaudio-ng: cd changed, rescanning\n"); | 188 printf("cdaudio-ng: cd changed, rescanning\n"); |
190 cdaudio_scan_dir(CDDA_DEFAULT); | 189 cdaudio_scan_dir(CDDA_DEFAULT); |
190 } | |
191 | |
192 if (pcdio == NULL) { | |
193 if (debug) | |
194 printf("cdaudio-ng: \"%s\" is not our file\n", filename); | |
195 return FALSE; | |
191 } | 196 } |
192 | 197 |
193 /* check if the requested track actually exists on the current audio cd */ | 198 /* check if the requested track actually exists on the current audio cd */ |
194 int trackno = find_trackno_from_filename(filename); | 199 int trackno = find_trackno_from_filename(filename); |
195 if (trackno < firsttrackno || trackno > lasttrackno) { | 200 if (trackno < firsttrackno || trackno > lasttrackno) { |
229 return NULL; | 234 return NULL; |
230 } | 235 } |
231 } | 236 } |
232 else { | 237 else { |
233 char **ppcd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false); | 238 char **ppcd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false); |
234 if (ppcd_drives != NULL) { /* we have at least one audio capable cd drive */ | 239 pcdio = NULL; |
240 if (ppcd_drives != NULL && *ppcd_drives != NULL) { /* we have at least one audio capable cd drive */ | |
235 pcdio = cdio_open(*ppcd_drives, DRIVER_UNKNOWN); | 241 pcdio = cdio_open(*ppcd_drives, DRIVER_UNKNOWN); |
236 if (pcdio == NULL) { | 242 if (pcdio == NULL) { |
237 fprintf(stderr, "cdaudio-ng: failed to open cd\n"); | 243 fprintf(stderr, "cdaudio-ng: failed to open cd\n"); |
238 cleanup_on_error(); | 244 cleanup_on_error(); |
239 return NULL; | 245 return NULL; |
240 } | 246 } |
247 if (debug) | |
248 printf("cdaudio-ng: found cd drive \"%s\" with audio capable media\n", *ppcd_drives); | |
241 } | 249 } |
242 else { | 250 else { |
243 fprintf(stderr, "cdaudio-ng: unable find or access a cdda capable drive\n"); | 251 fprintf(stderr, "cdaudio-ng: unable find or access a cdda capable drive\n"); |
244 cleanup_on_error(); | 252 cleanup_on_error(); |
245 return NULL; | 253 return NULL; |
246 } | 254 } |
247 if (debug) | |
248 printf("cdaudio-ng: found cd drive \"%s\" with audio capable media\n", *ppcd_drives); | |
249 cdio_free_device_list(ppcd_drives); | 255 cdio_free_device_list(ppcd_drives); |
250 } | 256 } |
251 | 257 |
252 /* limit read speed */ | 258 /* limit read speed */ |
253 if (limitspeed > 0 && !use_dae) { | 259 if (limitspeed > 0 && !use_dae) { |
423 | 429 |
424 void cdaudio_play_file(InputPlayback *pinputplayback) | 430 void cdaudio_play_file(InputPlayback *pinputplayback) |
425 { | 431 { |
426 if (debug) | 432 if (debug) |
427 printf("cdaudio-ng: cdaudio_play_file(\"%s\")\n", pinputplayback->filename); | 433 printf("cdaudio-ng: cdaudio_play_file(\"%s\")\n", pinputplayback->filename); |
434 | |
435 pglobalinputplayback = pinputplayback; | |
428 | 436 |
429 if (trackinfo == NULL) { | 437 if (trackinfo == NULL) { |
430 if (debug) | 438 if (debug) |
431 printf("cdaudio-ng: no cd information, scanning\n"); | 439 printf("cdaudio-ng: no cd information, scanning\n"); |
432 cdaudio_scan_dir(CDDA_DEFAULT); | 440 cdaudio_scan_dir(CDDA_DEFAULT); |
503 | 511 |
504 void cdaudio_stop(InputPlayback *pinputplayback) | 512 void cdaudio_stop(InputPlayback *pinputplayback) |
505 { | 513 { |
506 if (debug) | 514 if (debug) |
507 printf("cdaudio-ng: cdaudio_stop(\"%s\")\n", pinputplayback != NULL ? pinputplayback->filename : "N/A"); | 515 printf("cdaudio-ng: cdaudio_stop(\"%s\")\n", pinputplayback != NULL ? pinputplayback->filename : "N/A"); |
516 | |
517 pglobalinputplayback = NULL; | |
518 | |
519 if (playing_track == -1) | |
520 return; | |
508 | 521 |
509 if (pinputplayback != NULL) | 522 if (pinputplayback != NULL) |
510 pinputplayback->playing = FALSE; | 523 pinputplayback->playing = FALSE; |
511 playing_track = -1; | 524 playing_track = -1; |
512 is_paused = FALSE; | 525 is_paused = FALSE; |
519 } | 532 } |
520 } | 533 } |
521 else { | 534 else { |
522 if (cdio_audio_stop(pcdio) != DRIVER_OP_SUCCESS) { | 535 if (cdio_audio_stop(pcdio) != DRIVER_OP_SUCCESS) { |
523 fprintf(stderr, "cdaudio-ng: failed to stop analog cd\n"); | 536 fprintf(stderr, "cdaudio-ng: failed to stop analog cd\n"); |
524 cleanup_on_error(); | |
525 return; | 537 return; |
526 } | 538 } |
527 } | 539 } |
528 } | 540 } |
529 | 541 |
589 if (!use_dae) { | 601 if (!use_dae) { |
590 cdio_subchannel_t subchannel; | 602 cdio_subchannel_t subchannel; |
591 if (cdio_audio_read_subchannel(pcdio, &subchannel) != DRIVER_OP_SUCCESS) { | 603 if (cdio_audio_read_subchannel(pcdio, &subchannel) != DRIVER_OP_SUCCESS) { |
592 fprintf(stderr, "cdaudio-ng: failed to read analog cd subchannel\n"); | 604 fprintf(stderr, "cdaudio-ng: failed to read analog cd subchannel\n"); |
593 cleanup_on_error(); | 605 cleanup_on_error(); |
594 return -1; | 606 return 0; |
595 } | 607 } |
596 int currlsn = cdio_msf_to_lsn(&subchannel.abs_addr); | 608 int currlsn = cdio_msf_to_lsn(&subchannel.abs_addr); |
597 | 609 |
598 /* check to see if we have reached the end of the song */ | 610 /* check to see if we have reached the end of the song */ |
599 if (currlsn == trackinfo[playing_track].endlsn) { | 611 if (currlsn == trackinfo[playing_track].endlsn) { |
600 cdaudio_stop(pinputplayback); | 612 //cdaudio_stop(pinputplayback); |
601 return -1; | 613 return -1; |
602 } | 614 } |
603 | 615 |
604 return calculate_track_length(trackinfo[playing_track].startlsn, currlsn); | 616 return calculate_track_length(trackinfo[playing_track].startlsn, currlsn); |
605 } | 617 } |
705 | 717 |
706 *title = thetitle; | 718 *title = thetitle; |
707 *length = calculate_track_length(trackinfo[trackno].startlsn, trackinfo[trackno].endlsn); | 719 *length = calculate_track_length(trackinfo[trackno].startlsn, trackinfo[trackno].endlsn); |
708 } | 720 } |
709 | 721 |
710 void cdaudio_file_info_box(gchar *filename) | |
711 { | |
712 if (debug) | |
713 printf("cdaudio-ng: cdaudio_file_info_box(\"%s\")\n", filename); | |
714 } | |
715 | |
716 TitleInput *cdaudio_get_song_tuple(gchar *filename) | 722 TitleInput *cdaudio_get_song_tuple(gchar *filename) |
717 { | 723 { |
718 if (debug) | 724 if (debug) |
719 printf("cdaudio-ng: cdaudio_get_song_tuple(\"%s\")\n", filename); | 725 printf("cdaudio-ng: cdaudio_get_song_tuple(\"%s\")\n", filename); |
720 | 726 |
749 if (debug) | 755 if (debug) |
750 printf("cdaudio-ng: dae thread started\n"); | 756 printf("cdaudio-ng: dae thread started\n"); |
751 cdio_lseek(pcdio, pdae_params->startlsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET); | 757 cdio_lseek(pcdio, pdae_params->startlsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET); |
752 | 758 |
753 gboolean output_paused = FALSE; | 759 gboolean output_paused = FALSE; |
760 int read_error_counter = 0; | |
754 | 761 |
755 while (pdae_params->pplayback->playing) { | 762 while (pdae_params->pplayback->playing) { |
756 /* handle pause status */ | 763 /* handle pause status */ |
757 if (is_paused) { | 764 if (is_paused) { |
758 if (!output_paused) { | 765 if (!output_paused) { |
790 if (lsncount <= 0) | 797 if (lsncount <= 0) |
791 break; | 798 break; |
792 | 799 |
793 if (cdio_read_audio_sectors(pcdio, buffer, pdae_params->currlsn, lsncount) != DRIVER_OP_SUCCESS) { | 800 if (cdio_read_audio_sectors(pcdio, buffer, pdae_params->currlsn, lsncount) != DRIVER_OP_SUCCESS) { |
794 fprintf(stderr, "cdaudio-ng: failed to read audio sector\n"); | 801 fprintf(stderr, "cdaudio-ng: failed to read audio sector\n"); |
795 /* ok, that's it, we go on */ | 802 read_error_counter++; |
796 } | 803 if (read_error_counter >= 2) { |
804 fprintf(stderr, "cdaudio-ng: this cd can no longer be played, stopping\n"); | |
805 break; | |
806 } | |
807 } | |
808 else | |
809 read_error_counter = 0; | |
797 | 810 |
798 int remainingbytes = lsncount * CDIO_CD_FRAMESIZE_RAW; | 811 int remainingbytes = lsncount * CDIO_CD_FRAMESIZE_RAW; |
799 unsigned char *bytebuff = buffer; | 812 unsigned char *bytebuff = buffer; |
800 while (pdae_params->pplayback->playing && remainingbytes > 0 && pdae_params->seektime == -1) { | 813 while (pdae_params->pplayback->playing && remainingbytes > 0 && pdae_params->seektime == -1) { |
801 /* compute the actual number of bytes to play */ | 814 /* compute the actual number of bytes to play */ |
841 return strtol(tracknostr, NULL, 10); | 854 return strtol(tracknostr, NULL, 10); |
842 } | 855 } |
843 | 856 |
844 void cleanup_on_error() | 857 void cleanup_on_error() |
845 { | 858 { |
846 if (pcdio != NULL) { | 859 if (playing_track != -1) { |
847 if (playing_track != -1 && !use_dae) | 860 playing_track = -1; |
861 //playback_stop(); | |
862 if (pglobalinputplayback != NULL) { | |
863 pglobalinputplayback->error = 1; | |
864 playback_stop(); | |
865 } | |
866 if (pcdio != NULL && !use_dae) | |
848 cdio_audio_stop(pcdio); | 867 cdio_audio_stop(pcdio); |
849 } | 868 } |
869 | |
850 if (trackinfo != NULL) { | 870 if (trackinfo != NULL) { |
851 free(trackinfo); | 871 free(trackinfo); |
852 trackinfo = NULL; | 872 trackinfo = NULL; |
853 } | 873 } |
854 playing_track = -1; | 874 } |
855 } | 875 |
856 |