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