#!/bin/ksh # # CD Player frontend for CDDA2WAV # # Programmed during the rainy feb 12, 2005 # (c) Peter van Eerten - free for all use # # 1.0: Initial release # 1.1: Fixes for CDDA2WAV on OpenBSD (june 1 2005) # 1.2: Now combobox synchronizes with track (june 4 2005) # 1.2a: Fixes for CD's with more than 10 tracks (september 9, 2005) # 1.3: -Removed ' character from titles (october 18, 2005) # -Support for intern. characters (october 18, 2005) #------------------------------------------------------------------------------------- # # Minimalistic frontend to play audio CD's # # Required tools: # -cdda2wav # -GNU Awk # -rexima OR aumix # -...and of course coreutils like 'cat' and 'tr'. # #------------------------------------------------ CHECK function Check_Software { # Check on availability of AWK AWK=`which gawk 2>/dev/null` if [[ -z $AWK ]] then echo "GNU Awk not found on your system! Exiting..." exit 1 fi # Check on availability of REXIMA or AUMIX MIXER=`which rexima 2>/dev/null` if [[ -z $MIXER || $MIXER = "rexima: Command not found." ]] then MIXER=`which aumix 2>/dev/null` if [[ -z $MIXER || $MIXER = "aumix: Command not found." ]] then echo "No mixer found! Exiting..." exit 1 fi fi # Check on availability of cdda2wav CDDA2WAV=`which cdda2wav 2>/dev/null` if [[ -z $CDDA2WAV ]] then echo "cdda2wav not found on your system! Exiting..." exit 1 fi } # Check on availability of 'sleep' SLEEP=`which sleep 2>/dev/null` if [[ -z $SLEEP ]] then echo "GNU sleep not found on your system! High CPU load granted." SLEEP=sleep fi #------------------------------------------------ GTK # Communication function; $1 contains the string to be send function gtk { print -p $1 read -p RESULT } #------------------------------------------------ GUI function Build_Gui { # Setup environment for GTK server #export LC_ALL=nl_NL export LD_LIBRARY_PATH=/usr/X11R6/lib:/usr/lib:/usr/local/lib # Start GTK-server in STDIN mode gtk-server stdin |& # Check GTK version gtk "gtk_check_version 2 4 0" if [[ -n $RESULT ]] then echo "Your GTK installation is too old!" echo "GTK version 2.4.0 or higher is required. Exiting..." gtk "gtk_exit 0" exit 1 fi # Define GUI - mainwindow gtk "gtk_init NULL NULL" gtk "gtk_window_new 0" WINDOW=$RESULT gtk "gtk_window_set_title $WINDOW \"CD Player\"" gtk "gtk_window_set_position $WINDOW 1" # Buttons gtk "gtk_button_new_from_stock gtk-stop" G_BUTTON_STOP=$RESULT gtk "gtk_button_new_from_stock gtk-refresh" G_BUTTON_REFRESH=$RESULT gtk "gtk_button_new_from_stock gtk-quit" G_BUTTON_QUIT=$RESULT gtk "gtk_button_new_from_stock gtk-help" G_BUTTON_HELP=$RESULT # Volume slider gtk "gtk_vscale_new_with_range 0 100 1" G_VOLUME=$RESULT gtk "gtk_scale_set_draw_value $G_VOLUME 0" gtk "gtk_range_set_value $G_VOLUME 50" # Combobox with titles of CD gtk "gtk_combo_box_new_text" G_COMBO=$RESULT # Create layout gtk "gtk_hbox_new 0 0" H1BOX=$RESULT gtk "gtk_box_pack_start $H1BOX $G_BUTTON_STOP 1 1 1" gtk "gtk_box_pack_start $H1BOX $G_BUTTON_REFRESH 1 1 1" gtk "gtk_box_pack_start $H1BOX $G_BUTTON_HELP 1 1 1" gtk "gtk_box_pack_end $H1BOX $G_BUTTON_QUIT 1 1 1" gtk "gtk_vbox_new 0 0" VBOX=$RESULT gtk "gtk_box_pack_start $VBOX $H1BOX 1 1 1" gtk "gtk_box_pack_start $VBOX $G_COMBO 1 1 1" gtk "gtk_hbox_new 0 0" HTOPBOX=$RESULT gtk "gtk_box_pack_start $HTOPBOX $VBOX 1 1 1" gtk "gtk_box_pack_start $HTOPBOX $G_VOLUME 0 0 0" gtk "gtk_container_add $WINDOW $HTOPBOX" gtk "gtk_widget_show_all $WINDOW" # Create ABOUT box gtk "gtk_server_version" TMP="\t*** A simple CD player for XFCE ***\r\rProgrammed with KSH and $RESULT.\r\r Visit http://www.gtk-server.org/ for more info!" gtk "gtk_message_dialog_new $WINDOW 0 0 2 \"$TMP\"" ABOUT=$RESULT } #------------------------------------------------ CDLOOKUP function Lookup_CD { # First remove existing tracks from widget if [[ $TRACKS -gt 0 ]] then COUNTER=0 until [[ $COUNTER -eq $TRACKS ]] do gtk "gtk_combo_box_remove_text $G_COMBO 0" let COUNTER=$COUNTER+1 done fi # Lookup information from CDDB $CDDA2WAV -D $CDROM -J -v titles -L 1 -N -H 2>&1 | tr -d "'" | $AWK '/Album/ {print} /Track/ {print}' > /tmp/CD.txt # Determine amount of tracks (includes album title) TRACKS=`cat /tmp/CD.txt | wc -l` # If no tracks then reread CD if [[ $TRACKS -lt 2 ]] then # Restore default title if [[ $TRACKS -eq 1 ]] then L_TITLE=`cat /tmp/CD.txt | $AWK '/Album/ {print substr($0, index($0, ":") + 1)}'` gtk "gtk_window_set_title $WINDOW \"$L_TITLE\"" else gtk "gtk_window_set_title $WINDOW \"CD Player\"" fi # Find amount of tracks on CD $CDDA2WAV -D $CDROM -J -v toc -L 1 -N -H 2>&1 | tr -d "'" | $AWK 'BEGIN {ORS=""} /[0-9]:[0-9]/ {print}' > /tmp/CD.txt TRACKS=`cat /tmp/CD.txt | $AWK 'BEGIN {RS=","} {print}' | wc -l` # Add track numbering to combobox COUNTER=0 until [[ $COUNTER -eq $TRACKS ]] do let TMP=$COUNTER+1 L_TRACK="$TMP - Unknown track" gtk "gtk_combo_box_append_text $G_COMBO \"$L_TRACK\"" let COUNTER=$COUNTER+1 done else # Add CD title to window title L_TITLE=`cat /tmp/CD.txt | $AWK '/Album/ {print substr($0, index($0, ":") + 1)}'` gtk "gtk_window_set_title $WINDOW \"$L_TITLE\"" # Add tracks to combobox COUNTER=1 until [[ $COUNTER -eq $TRACKS ]] do L_TRACK=`grep "Track $COUNTER" /tmp/CD.txt` if [[ -z $L_TRACK ]] then L_TRACK=`grep "Track $COUNTER" /tmp/CD.txt` fi TMP=`echo $L_TRACK | $AWK '{gsub(/"/, ""); print}'` gtk "g_locale_to_utf8 \"$TMP\" -1 NULL NULL NULL" L_TRACK=$RESULT gtk "gtk_combo_box_append_text $G_COMBO \"$L_TRACK\"" let COUNTER=$COUNTER+1 done # Put amount of tracks to real value ((TRACKS-=1)) fi # Put first item as active one gtk "gtk_combo_box_set_active $G_COMBO 0" } #------------------------------------------------ STOP function Stop_CD { # Only if PID exists, kill process if [[ -n $P_PID ]] then STOPPED=1 kill -9 $P_PID >/dev/null 2>&1 $SLEEP 1 P_PID="" fi } #------------------------------------------------ PLAY function Play_CD { # Get selected track from combo gtk "gtk_combo_box_get_active $G_COMBO" let P_TRACK=$RESULT+1 # Kill existing playing process first Stop_CD # Start playing and save PID $CDDA2WAV -D $CDROM -q -e -t$P_TRACK -d0 -N >/dev/null 2>&1 & # Unset stopped flag STOPPED=0 # Save ProcessID P_PID=`jobs -p | head -1` } #------------------------------------------------ SELECT NEXT TRACK function Action_Track { # Find out if track currently is being played TMP=`jobs -l | grep $P_PID 2>/dev/null` # If not, and not stopped, goto next track if [[ -z $TMP && $STOPPED -eq 0 ]] then # Get selected track from combo gtk "gtk_combo_box_get_active $G_COMBO" let P_TRACK=$RESULT+1 # Put to next track if [[ $P_TRACK -lt $TRACKS ]] then # Put combobox to next track, inducing signal gtk "gtk_combo_box_set_active $G_COMBO $P_TRACK" fi fi } #------------------------------------------------ VOLUME function Adjust_Volume { # Get current value gtk "gtk_range_get_value $G_VOLUME" let V_VOL=100-`$AWK -v VAR=$RESULT 'BEGIN {print int(VAR)}'` case $MIXER in `which rexima 2>/dev/null`) $MIXER pcm $V_VOL;; `which aumix 2>/dev/null`) $MIXER -w $V_VOL;; esac } #------------------------------------------------ MAIN # Set global variables CDROM=/dev/cdrom # Check available packages Check_Software # Create GUI Build_Gui # Get CD info Lookup_CD # Put volume to default Adjust_Volume # Initialize variables EVENT=0 # Mainloop while [[ $EVENT -ne $WINDOW && $EVENT -ne $G_BUTTON_QUIT ]] do # Wait for event gtk "gtk_server_callback UPDATE" EVENT=$RESULT # Check events case $EVENT in # If refresh button is pressed $G_BUTTON_REFRESH) Lookup_CD;; # If help button is pressed $G_BUTTON_HELP) gtk "gtk_widget_show $ABOUT";; # If OK button in HELP dialog is pressed $ABOUT) gtk "gtk_widget_hide $ABOUT";; # If stop button is pressed $G_BUTTON_STOP) Stop_CD;; # If volume slider is moved $G_VOLUME) Adjust_Volume;; # If combobox is changed $G_COMBO) Play_CD;; esac # Check if we need to go to next track Action_Track # Avoid 99% CPU load $SLEEP 0.05 done # Before exiting, stop playing CD Stop_CD # Remove temporary file rm /tmp/CD.txt # Exit GTK gtk "gtk_exit 0"