#!/bin/sh # Launcher script to work around limitations in vgmplay: # OSS only - detects oss wrapper and allows explicit selection # Config must be in working dir - automatically cd/mktemps as needed # Can't open release packs - plays from temporary directories # # Original script by ZekeSulastin # 7z support by Valley Bell trap '[ -n "$_tmpdir" ] && rm -rf "$_tmpdir"; [ -w "$_log_path/vgmplay.ini" ] && rm "$_log_path/vgmplay.ini"' EXIT trap '[ -n "$_tmpdir" ] && rm -rf "$_tmpdir"; [ -w "$_log_path/vgmplay.ini" ] && rm "$_log_path/vgmplay.ini"; reset' HUP INT QUIT TERM SEGV _set_output= _output= _pulse_server= _log_path= _binary= _config= _unpacker= _pwd="$(pwd)" _host="$(hostname)" _ext= _unpacker= _tmpdir= _music_file= _m3u_stub= XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" XDG_CONFIG_DIRS="${XDG_CONFIG_DIRS:-/etc/xdg}" _padsp="$(command -v padsp 2>/dev/null)" _aoss="$(command -v aoss 2>/dev/null)" _help () { cat <, --pulse-server= set alternate PulseAudio server (implies --padsp) -l, --log outputs to wav files in current directory --log-path= outputs to wav files in (implies --log) WARNING: If you plan to log using this script, use --log or --log-path! Do NOT set logging on in a custom config, else the script logic will remove your logs! --binary= use alternate vgmplay binary --config= use alternate configuration file Keys (In-Player): Left/Right seek 5 seconds backward/forward Ctrl + Left/Right seek 60 seconds backward/forward Space pause Escape (twice) or Q quit program F fade out current track R restart current track PageUp or B previous track in playlist PageDown or N next track in playlist EOF exit 0 } _to_stderr () { echo "$0: $2" 1>&2 exit $1 } _die () { case $1 in too_many_outputs ) _to_stderr 64 "can only force one output type" ;; no_pulse_server ) _to_stderr 64 "--pulse-server requires server parameter" ;; no_log_path ) _to_stderr 64 "--log-to requires path parameter" ;; unknown_option ) _to_stderr 64 "unrecognized option '$2'\nTry 'vgm-player --help' for more information." ;; no_aoss ) _to_stderr 69 "alsa output forced but aoss not found" ;; no_oss ) _to_stderr 74 "oss output forced but /dev/dsp unwritable or not present" ;; no_pulse ) _to_stderr 69 "pulse output forced but padsp not found" ;; too_many_files ) _to_stderr 64 "only one music file should be specified" ;; file_unreadable ) _to_stderr 66 "unable to read specified input - does it exist?" ;; invalid_format ) _to_stderr 66 "format unsupported" ;; invalid_binary ) _to_stderr 69 "invalid binary specified" ;; no_binary ) _to_stderr 64 "--binary requires binary parameter" ;; no_config ) _to_stderr 64 "--config requires config parameter" ;; noread_config ) _to_stderr 69 "specified config unreadable - does it exist?" ;; invalid_config ) _to_stderr 64 "invalid config specified" ;; vgmplay_not_found ) _to_stderr 69 "vgmplay binary not found" ;; no_unpacker ) _to_stderr 69 "no suitable unpacker found" ;; tmpdir_failed ) _to_stderr 70 "unable to create/use temporary working directory" ;; no_output ) _to_stderr 69 "no usable otuput detected" ;; log_path_nowrite ) _to_stderr 73 "log path unwriteable" ;; esac } _set_output () { if [ -n "$_set_output" ] && [ "$1" != "$_set_output" ]; then _die too_many_outputs fi _set_output=$1 case "$_set_output" in alsa ) [ -x "$_aoss" ] || _die no_aoss ;; oss ) [ -w /dev/dsp ] || _die no_oss ;; pulse ) [ -n "$_padsp" ] || _die no_pulse ;; * ) ;; esac } # Set terminal title for xterm/rxvt case $TERM in xterm* | rxvt* ) printf '%b\n' '\033]2;VGM Player\007' ;; * ) ;; esac # Parse command line options # All single-letter options are exclusive while :; do case $1 in --help ) _help ;; --version ) echo "VGMPlay 0.40.3 supporting VGM 1.70" exit 0 ;; -a | --alsa ) _set_output alsa shift ;; -o | --oss ) _set_output oss shift ;; -p | --pulse ) _set_output pulse shift ;; --pulse-server=* ) _set_output pulse _pulse_server="${1#*=}" [ -n "$_pulse_server" ] || _die no_pulse_server shift ;; -s* ) _set_output pulse _pulse_server="${1#-s}" if [ -z "$_pulse_server" ]; then _pulse_server="$2" shift fi [ -n "$_pulse_server" ] || _die no_pulse_server shift ;; -l | --log ) _set_output log _log_path="$_pwd" shift ;; --log-path=* ) _set_output log _log_path="${1#*=}" [ -d "$_log_path" ] || _die no_log_path shift ;; --config=* ) _config="${1#*=}" [ -n "$_config" ] || _die no_binary [ -r "$_config" ] || _die noread_config file "$_config" | grep -q "ASCII" || _die invalid_config shift ;; --binary=* ) _binary="${1#*=}" [ -n "$_binary"] || _die no_binary if [ ! -x "$_binary" ] || [ ! "${binary##*/}" = "vgmplay" ]; then die _invalid_binary fi shift ;; -* ) _die unknown_option "$1" ;; -- ) shift ;; "" ) _die no_music_file ;; * ) [ -z "$2" ] || _die too_many_files _ext="$(echo ${1##*.} | tr [:upper:] [:lower:])" case $_ext in vgm | vgz | cmf | dro | m3u | zip | 7z | vgm7z ) [ -r "$1" ] || _die file_unreadable _music_file="$1";; * ) _die invalid_format esac case $_music_file in ~* | /* ) break ;; * ) _music_file="$_pwd/$_music_file" ;; esac break ;; esac done # Does `vgmplay` exist if --binary not specified? # Prefers vgmplay in working dir over any others if [ -n "$_binary" ]; then break elif [ -x "$_pwd/vgmplay" ]; then _binary="$_pwd/vgmplay" else _binary="$(command -v vgmplay 2>/dev/null)" fi [ -n "$_binary" ] || _die vgmplay_not_found # If a compressed pack, does a suitable unpacker exist? case $_ext in zip ) command -v unzip 2>/dev/null || _die no_unpacker ;; 7z | vgm7z ) command -v 7z 2>/dev/null || _die no_unpacker ;; vgm | vgz | cmf | dro | m3u ) break ;; * ) _die invalid_format ;; esac # Select config if [ -r "$_config" ]; then break else for i in "$_pwd" "$XDG_CONFIG_HOME/vgmplay" "$HOME/.config/vgmplay" "$XDG_CONFIG_DIRS/vgmplay" "/etc/xdg/vgmplay" "/usr/local/share/vgmplay" "/usr/share/vgmplay"; do _config="$i/vgmplay.ini" [ -r "$_config" ] && break done fi # vgmplay will function without a config, but will warn the user thus from inside the program # Make temporary working directory for vgmplay # Logdir availability checked here ... # Uses $XDG_RUNTIME_DIR, $TMPDIR, /tmp # Uses mktemp program for my sanity's sake # Assumes user isn't going to try to log into a directory w/ a preexisting vgmplay.ini # Seriously, if you're going to do that why would you use this helper to start with if [ -d "$_log_path" ]; then command sed "s/^LogSound.*/LogSound = 1/" < "$_config" > "$_log_path/vgmplay.ini" || _die log_path_nowrite elif [ -n "$XDG_RUNTIME_DIR" ]; then _tmpdir="$(command mktemp -d --tmpdir="$XDG_RUNTIME_DIR")" || _die tmpdir_fail command cp "$_config" "$_tmpdir/vgmplay.ini" || _die tmpdir_fail else #mktemp defaults to tmpdir then /tmp! _tmpdir="$(command mktemp -d)" || _die tmpdir_fail command cp "$_config" "$_tmpdir/vgmplay.ini" || _die tmpdir_fail fi # Determine output to use if not forced # Also sets pulse-server if detected # PULSE_SERVER, oss, padsp, aoss, log set, error if [ -n $_set_output ]; then if [ -n "$PULSE_SERVER" ] && [ -x "$_padsp" ]; then _set_output="pulse-server" elif [ -w /dev/dsp ]; then _set_output="oss" elif [ -x "$_padsp" ] && command pulseaudio --check ; then _set_output="pulse" elif [ -x "$_aoss" ]; then _set_output="alsa" elif [ -n "$_log_path" ]; then _set_output="log" else _die no_output fi fi [ -n "$_pulse_server" ] && _set_output=pulse-server # Extract packs to tmpdir. if [ $_ext = "zip" ]; then if [ "$_set_output" = log ]; then ( [ -d "$_log_path" ] && cd "$_log_path" || _die log_path_nowrite command unzip "$_music_file" >"$_log_path/extractlog" ) _m3u_stub="$(command grep < "$_log_path/extractlog" m3u | command sed 's/ inflating: \| extracting: //g')" _music_file="$_log_path/${_m3u_stub%% }" command rm "$_log_path/extractlog" else ( [ -d "$_tmpdir" ] && cd "$_tmpdir" || _die tmpdir_failed command unzip "$_music_file" >"$_tmpdir/extractlog" ) _m3u_stub="$(command grep < "$_tmpdir/extractlog" m3u | command sed 's/ inflating: \| extracting: //g')" _music_file="$_tmpdir/${_m3u_stub%% }" fi elif [ $_ext = "7z" ] || [ $_ext = "vgm7z" ]; then if [ "$_set_output" = log ]; then ( [ -d "$_log_path" ] && cd "$_log_path" || _die log_path_nowrite command 7z x "$_music_file" >"$_log_path/extractlog" ) _m3u_stub="$(command grep < "$_log_path/extractlog" m3u | command sed 's/Extracting //g')" _music_file="$_log_path/${_m3u_stub%% }" command rm "$_log_path/extractlog" else ( [ -d "$_tmpdir" ] && cd "$_tmpdir" || _die tmpdir_failed command 7z x "$_music_file" >"$_tmpdir/extractlog" ) _m3u_stub="$(command grep < "$_tmpdir/extractlog" m3u | command sed 's/Extracting //g')" _music_file="${_m3u_stub%% }" #echo "Test:$_music_file|" if [ "$_music_file" == "" ]; then _music_file="List.m3u" #echo "Test:$_music_file|" command grep < "$_tmpdir/extractlog" vgm | command sed 's/Extracting //g' >"$_tmpdir/$_music_file" #exec cat "$_music_file" fi _music_file="$_tmpdir/$_music_file" fi fi _music_file=`echo "$_music_file" | sed -e "s/\\s*$//g"` # Plays back song with specified everything case $_set_output in log ) ( cd "$_log_path" "$_binary" "$_music_file" ) command mv "${_music_file%/*}/"*.wav "${_log_path}" [ -n "$_music_stub" ] && rm -rf "$_log_path/$_music_stub" ;; pulse-server ) _pulse_server="${_pulse_server:-$PULSE_SERVER}" ( cd "$_tmpdir" exec "$_padsp" -s "$_pulse_server" -n "VGM Player" -m "OSS Emulation (from $_host)" "$_binary" "$_music_file" ) ;; pulse ) ( cd "$_tmpdir" exec "$_padsp" -n "VGM Player" -m "OSS Emulation" "$_binary" "$_music_file" ) ;; alsa ) ( cd "$_tmpdir" exec "$_aoss" "$_binary" "$_music_file" ) ;; oss ) ( cd "$_tmpdir" exec "$_binary" "$_music_file" ) ;; esac #read waitvar # vim:ts=4:sw=4:et