/* * Example program for libcda. * * Jean-Yves Levesque */ /*----------------------------------------------------------------------*/ /* D E F I N E S */ /*----------------------------------------------------------------------*/ #define true 1 #define false 0 #define PGM "cda" #define VERSION "V0.1" #define COPYRGT "(C)2000 Peter Wang (tjaden@users.sourceforge.net)" #define TRACK "Track" #define INFO "TrackInfo" #define FROM "From " #define TO "To " #define VOL_L "Left Volume" #define VOL_R "Right Volume" #define CANCEL "Command Cancelled" #define ERROR "Error occurred (%s)\n" #define AUDIO(t) ( cd_is_audio(t) ? "Audio" : "Data" ) /*----------------------------------------------------------------------*/ /* I N C L U D E S */ /*----------------------------------------------------------------------*/ #include #include "libcda.h" #include #include #include /*----------------------------------------------------------------------*/ /* T Y P E D E F S */ /*----------------------------------------------------------------------*/ typedef struct { char c ; char string[15] ; void (*func)() ; char helptext[30] ; } cmdStruct ; typedef struct { int first_track ; int last_track ; } track_info ; /*----------------------------------------------------------------------*/ /* Internal Functions Prototypes */ /*----------------------------------------------------------------------*/ static void back_track() ; static void done_playing() ; static void forward_track() ; static void pause_resume() ; static void play_from() ; static void play_range() ; static void play_track() ; static void random_track() ; static void set_volume() ; static void show_audio() ; static void show_info() ; static void show_status() ; static void show_toc() ; static void show_usage() ; static void show_volume() ; static void show_version() ; static void show_error( const char *fmt, ...) ; static int input_int( const char * prompt ) ; static int valid_input_int( const char * prompto, int min, int max ) ; static char read_cmd() ; static int valid_cmd( char c ) ; /*----------------------------------------------------------------------*/ /* Table of Function Pointers */ /*----------------------------------------------------------------------*/ cmdStruct myCmdStruct[] = { { 'a', "audio" , show_audio , "Check if track is audio" } , { 'c', "close" , cd_close , "closes the CD tray" } , { 'd', "dir" , show_toc , "lists the CD directory" } , { 'e', "eject" , cd_eject , "opens the CD tray" } , { 'F', "FromTrack", play_from , "Play from track to end of CD" } , { 'h', "help" , show_usage , "displays this message" } , { 'i', "info" , show_info , "minimal info on the current CD" } , { 'I', "Info S/W" , show_version , "Displays software version" } , { 'p', "play" , play_track , "Plays track from CD" } , { 'r', "random" , random_track , "Plays random track from CD" } , { 'R', "Range" , play_range , "Plays range of tracks from CD" } , { 's', "stop" , cd_stop , "stops the CD player" } , { 'S', "Status" , show_status , "Show Paused Status" } , { 'v', "volume" , set_volume , "Sets Volume" } , { 'V', "Volume" , show_volume , "Shows Current Volume" } , { 'w', "wait" , pause_resume , "Pause/resume the CD" } , { '+', "forward" , forward_track, "play the next track on CD" } , { '-', "back" , back_track , "play the previous track on CD" } , { 'q', "Quit" , done_playing , "Quit" } } ; /*----------------------------------------------------------------------*/ /* GLobal Variables */ /*----------------------------------------------------------------------*/ static int tLength = sizeof( myCmdStruct ) / sizeof( myCmdStruct[0] ) ; /* * Main procedure loops over user requests. */ int main() { int i = 0 ; char c ; // Command Read From Input. // Open CD ROM Drive. if ( cd_init() < 0 ) { show_error( ERROR, cd_error ) ; return 1; } // Shows possible commands. show_usage(); // While Not Quit. while ((c = read_cmd()) != 'q' ) { if (( i = valid_cmd( c )) == -1 ) { printf("Unrecognised command: `%c'\n", c ) ; } else { (*myCmdStruct[i].func)() ; } } // Stop Device. cd_exit(); return 0 ; } /* * Description: Sets Boolean to break the loop and quit. * * Returns: c - First character in buffer. */ static char read_cmd() { char cmd[20] ; fprintf( stdout, PGM "-> " ) ; fflush ( stdout ) ; scanf( "%s", cmd ) ; return cmd[0] ; } /* * Description: Sets Boolean to break the loop and quit. * * Returns: n - Line in table where command is. * -1 - Not Found. */ static int valid_cmd( char c ) { int rc = -1 ; int i = 0 ; // Search Command. for ( i = 0; i < tLength; i++ ) { if ( myCmdStruct[i].c == c ) { rc = i ; } } return rc ; } /* * Description: Sets Boolean to break the loop and quit. */ static void done_playing() { } /* * Description: Get First and Last Track number from the CD. * * Returns: true if success, false other wise. */ static int get_track_info( track_info * ptrack_info ) { int rc = false ; int first_track = 0 ; int last_track = 0 ; if ( cd_get_tracks ( &first_track, &last_track ) ) { show_error( INFO, cd_error ) ; } else { ptrack_info->first_track = first_track ; ptrack_info->last_track = last_track ; rc = true ; } return rc ; } /* * Description: Displays the various available commands. */ static void show_usage () { int i ; show_version() ; printf( "Available Commands are:\n\n" ) ; for ( i = 0; i < tLength; i++ ) { printf( "\t%c %-15s %-30s\n", myCmdStruct[i].c , myCmdStruct[i].string , myCmdStruct[i].helptext ) ; } } /* * Description: Displays the software version. */ static void show_version () { printf( PGM " - " VERSION " - " COPYRGT "\n" ) ; } /* * Description: Displays the CD Table Of Contents */ static void show_toc () { int i ; int no ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } no = tInfo.last_track - tInfo.first_track + 1 ; printf( TRACK " Type (%d tracks)\n", no ) ; for ( i = tInfo.first_track; i <= tInfo.last_track; i++ ) { printf( " %2d %s\n", i, AUDIO(i) ) ; } } /* * Description: Displays minimal information regardin gthe current track. */ static void show_info () { int i ; int no ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } i = cd_current_track() ; no = tInfo.last_track - tInfo.first_track + 1 ; if ( i > 0 ) { printf ("Playing track %d (%d tracks)\n", i, no ) ; } else { printf ("Not playing (%d tracks)\n", no ) ; } } /* * Description: Plays a track from the CD. */ static void play_track () { int trk ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } else if ((trk = valid_input_int( TRACK , tInfo.first_track , tInfo.last_track ) ) == -1 ) { show_error( CANCEL ) ; } else if ( cd_play( trk ) != 0 ) { show_error( ERROR, cd_error ) ; } } /* * Description: Plays a range of tracks from the CD. */ static void play_from () { int trk ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } else if ((trk = valid_input_int ( FROM TRACK , tInfo.first_track , tInfo.last_track ) ) == -1 ) { show_error( CANCEL ) ; } else if ( cd_play_from( trk ) != 0 ) { show_error( ERROR, cd_error ) ; } } /* * Description: Plays a range of tracks from the CD. */ static void play_range () { int first ; int last ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } else if ((first = valid_input_int( FROM TRACK , tInfo.first_track , tInfo.last_track ) ) == -1 ) { show_error( CANCEL ) ; } else if ((last = valid_input_int( TO TRACK , tInfo.first_track , tInfo.last_track ) ) == -1 ) { show_error( CANCEL ) ; } else if ( cd_play_range( first, last ) != 0 ) { show_error( ERROR, cd_error ) ; } } /* * Description: Pause or Resume the Current Track. */ static void pause_resume () { if ( cd_is_paused ()) { cd_eject() ; } else if ( cd_current_track ()) { cd_close() ; } } /* * Description: Pause or Resume the Current Track. */ static void open_close() { if ( cd_is_paused ()) { cd_resume (); } else if ( cd_current_track ()) { cd_pause (); } } /* * Description: Plays the next track from the CD. */ static void forward_track () { int ct ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } ct = ( cd_current_track() + 1 ) % tInfo.last_track ; if ( ct < 1 ) { ct = tInfo.last_track ; } if ( cd_play_from( ct ) != 0 ) { show_error( ERROR, cd_error ) ; } } /* * Description: Plays the previous track from the CD. */ static void back_track () { int ct ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } ct = ( cd_current_track() - 1 ) % tInfo.last_track ; if ( ct < 1 ) { ct = tInfo.last_track ; } if ( cd_play_from( ct ) != 0 ) { show_error( ERROR, cd_error ) ; } } /* * Description: Plays a random track from the CD. */ static void random_track () { int ct ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } srand ( time (NULL ) ) ; ct = (( rand () % ( tInfo.last_track + 1 - tInfo.first_track ) ) + tInfo.first_track ) ; if ( cd_play_from( ct ) != 0 ) { show_error( ERROR, cd_error ) ; } } /* * Description: Shows the current volume settings. */ static void show_volume() { int lVol ; // left volume int rVol ; // right volume cd_get_volume( &lVol, &rVol ) ; printf( VOL_L ": %d\n" VOL_R ": %d\n", lVol, rVol ) ; } /* * Description: Changes the volume settings. */ static void set_volume() { int lVol ; // left volume int rVol ; // right volume if ((lVol = valid_input_int( VOL_L , 1, 255 ) ) == -1 ) { show_error( CANCEL ) ; } else if ((rVol = valid_input_int( VOL_R , 1, 255 ) ) == -1 ) { show_error( CANCEL ) ; } else { cd_set_volume( lVol, rVol ) ; } } /* * Description: Shows the current track type. */ static void show_audio() { int trk ; track_info tInfo ; if ( get_track_info( &tInfo ) == false ) { return ; } else if ((trk = valid_input_int( TRACK , tInfo.first_track , tInfo.last_track ) ) == -1 ) { show_error( CANCEL ) ; } else { printf( TRACK " %d is %s\n", trk, AUDIO(trk) ) ; } } /* * Description: Shows the current track type. */ static void show_status() { printf( ( cd_is_paused() ) ? "Paused\n" : "Not Paused\n" ) ; } /* * Description: Gets Integer From User Via a Prompt. * * Parameters: prompt - To Ask User. * Returns: a - Number imput */ static int input_int( const char * prompt ) { int a ; fprintf( stdout, "%s: ", prompt ) ; fflush ( stdout ) ; scanf("%d", &a ) ; return a ; } /* * Description: Gets Integer From User Via a Prompt. * * Parameters: prompt - To Ask User. * min - Minimum Value Requested * max - Maximum Value Requested * Returns: a - Number imput */ static int valid_input_int( const char * prompt, int min, int max ) { int a = -1 ; char cmd[20] ; while ( 1 ) { a = -1 ; fprintf( stdout, "%s [%d-%d] or 'q' to quit: ", prompt, min, max ) ; fflush ( stdout ) ; scanf( "%s", cmd ) ; if ( cmd[0] == 'q' ) { break ; } a = atoi ( cmd ) ; if ( a >= min && a <= max ) { break ; } else { fprintf( stdout, "Invalid Value %d\n", a ) ; fflush ( stdout ) ; } } return a ; } /* * Description: Shows the error encountered. */ static void show_error( const char *fmt, ... ) { va_list ap; va_start( ap, fmt); vfprintf( stderr, fmt, ap ) ; va_end ( ap ) ; }