diff options
-rwxr-xr-x | find_key | 48 | ||||
-rwxr-xr-x | tunebass | 83 | ||||
-rwxr-xr-x | ztunekey | 33 | ||||
-rw-r--r-- | ztunekey.desktop | 9 | ||||
-rw-r--r-- | ztunekey.png | bin | 0 -> 55391 bytes |
5 files changed, 157 insertions, 16 deletions
@@ -55,8 +55,9 @@ $0: Find key of music in audio (or maybe video) files. Usage: $0 [-m|-M] file.wav [file.wav ...] --m: Force major keys to relative minor --M: Force minor keys to relative major +-q: Quiet, only output the most likely key. +-m: Force major keys to relative minor. +-M: Force minor keys to relative major. EOF exit 0; } @@ -70,6 +71,9 @@ for(@ARGV) { $fold_major = 0; $fold_minor = 1; next; + } elsif(/^-q/) { + $quiet++; + next; } my $sec; @@ -79,22 +83,23 @@ for(@ARGV) { $sf = Audio::SndFile->open("<", $_); }; if($@) { - warn "Extracting to tmp.wav\n"; - system("mplayer -vo null -ao pcm:fast:file=tmp.wav \"$_\""); + my $rq = $quiet ? "-really-quiet" : ""; + warn "Extracting to tmp.wav\n" unless $quiet; + system("mplayer $rq -vo null -ao pcm:fast:file=tmp.wav \"$_\""); $sf = Audio::SndFile->open("<", "tmp.wav"); $_ = "tmp.wav"; } $sec = ($sf->frames) * (1 / $sf->samplerate); } - printf "file is %03.2f sec\n", $sec; + printf "file is %03.2f sec\n", $sec unless $quiet; my $oldstamp = -1; my $oldkey = -1; - my $got = `vamp-simple-host qm-vamp-plugins:qm-keydetector "$_" 2`; + my $got = `vamp-simple-host qm-vamp-plugins:qm-keydetector "$_" 2 2>/dev/null`; die "Analysis failed\n" unless defined $got; - print "\n"; + print "\n" unless $quiet; my @got = split "\n", $got; ## for my $line (@got) { @@ -122,24 +127,25 @@ for(@ARGV) { } elsif($fold_minor) { $key = get_relative_minor($key); } - if($key =~ /m$/) { - $relkey = get_relative_major($key); - } else { - $relkey = get_relative_minor($key); - } + $relkey = get_relative_key($key); if($oldstamp != -1) { $times{$oldkey} += ($stamp - $oldstamp); } $oldstamp = $stamp; $oldkey = $key; - print "$stamp: $key ($relkey)\n"; + print "$stamp: $key ($relkey)\n" unless $quiet; } $times{$oldkey} += ($sec - $oldstamp); - print "\n"; - for(sort { $times{$b} <=> $times{$a} } keys %times) { - printf "%3s: %4.2f sec, %4.2f%%\n", $_, $times{$_}, $times{$_} / $sec * 100; + print "\n" unless $quiet; + my @sorted = sort { $times{$b} <=> $times{$a} } keys %times; + if($quiet) { + print $sorted[0] . " (" . get_relative_key($sorted[0]) . ")\n"; + } else { + for(@sorted) { + printf "%3s: %4.2f sec, %4.2f%%\n", $_, $times{$_}, $times{$_} / $sec * 100; + } } } @@ -153,6 +159,16 @@ sub get_relative_minor { return $relative_minors{$key} || $key; } +sub get_relative_key { + my $key = shift || die "missing key"; + if($key =~ /m$/) { + $relkey = get_relative_major($key); + } else { + $relkey = get_relative_minor($key); + } + return $relkey; +} + __END__ Output of plugin: - Estimated key (from C major = 1 to B major = 12 and C minor = 13 to B minor = 24) diff --git a/tunebass b/tunebass new file mode 100755 index 0000000..5394abc --- /dev/null +++ b/tunebass @@ -0,0 +1,83 @@ +#!/bin/bash + +# Ear tuner for guitar and bass. Install tunebass on your $PATH, and +# symlink it to tunegtr. + +# this used to be a one-liner: +#play -n synth 2 pluck ${1:-A2} repeat 99999 + +case "$0" in + *gtr*|*guit*) + notes="E4 B3 G3 D3 A2 E2" + note=6 + lastnote=6 + ;; + *) + notes="G2 D2 A1 E1" + note=4 + lastnote=4 + ;; +esac + +prompt="Space: next string, BkSpc: prev string, 1-$lastnote: strings, q: quit, ?: help" + +# these seem like they ought to be the arrow keys, but they're actually +# \n and \b... kcud1 and kcub1 are the 'application mode' versions, which +# doesn't do us any good here. +#down="$( tput cud1 )" +#left="$( tput cub1 )" + +# these are correct for xterm and derivatives, and for the linux console. +down="$( printf "\x1b\x5bB" )" +left="$( printf "\x1b\x5bD" )" + +up="$( tput cuu1 )" +right="$( tput cuf1 )" +pageup="$( tput kpp )" +pagedown="$( tput knp )" + +esc="$( printf "\x1b" )" +enter=' +' + +oldnote= +pid= +echo "$prompt" +while true; do + narg="$( echo $notes | cut -d' ' -f $note )" + if [ "$oldnote" != "$note" ]; then + [ "$pid" != "" ] && kill "$pid" + echo -e -n "\rString: $note Note: $narg" + tput el + play --buffer 1024 -qn synth 2 pluck $narg repeat - &>/dev/null & + pid="$!" + oldnote="$note" + fi + key= + read -rs -N5 -t 0.1 key + if [ "$key" != "" ]; then + case "$key" in + [1-9]) + [ "$key" -le "$lastnote" ] && note=$key ;; + a|A|h|H|||$left|$pageup) + note=$(( note + 1 )); [ $note -gt $lastnote ] && note=1 ;; + d|D|l|L|' '|' '|$right|$enter|$pagedown) + note=$(( note - 1 )); [ $note = 0 ] && note=$lastnote ;; + s|S|j|J|$down) + note=$lastnote ;; + w|W|k|K|$up) + note=1 ;; + \?) + echo + cat <<EOF +Use space + backspace, arrow keys, pageup/down, WASD, HJKL, or numbers +1 to $lastnote to pick a string. Tune your strings to the notes you hear. +Press Q or Escape to exit. +EOF + ;; + $esc|q|Q) break ;; + esac + fi +done +kill "$pid" +echo diff --git a/ztunekey b/ztunekey new file mode 100755 index 0000000..da69d56 --- /dev/null +++ b/ztunekey @@ -0,0 +1,33 @@ +#!/bin/sh + +# icon from: +# https://vectorified.com/images/guitar-tuner-icon-28.jpg +# ...installed via: +# convert guitar-tuner-icon-28.jpg .local/share/icons/hicolor/256x256/apps/ztunekey.png + +ICON=ztunekey +ZOPT='--width 300 --height 100 --title Tuning/Key' +file="$1" + +if [ "$file" = "" ]; then + file="$( audtool --current-song-filename )" + if [ "$file" = "" ]; then + zenity --error $ZOPT --text="No song is playing!" + exit 1 + fi +fi + +if [ ! -e "$file" ]; then + zenity --error $ZOPT --text="No such file:
$file" + exit 1 +fi + +bn="$( basename "$file" )" + +( find_tuning -q "$file" > /tmp/tuning.$$ & + find_key -q "$file" > /tmp/key.$$ & + wait ) | zenity --progress $ZOPT --icon-name=ztunekey --text="$bn" --pulsate --auto-close + +zenity --info $ZOPT --icon-name=ztunekey --text="$bn
Tuning: $( cat /tmp/tuning.$$ ) cents
Key: $( cat /tmp/key.$$ )" + +rm -f /tmp/tuning.$$ /tmp/key.$$ diff --git a/ztunekey.desktop b/ztunekey.desktop new file mode 100644 index 0000000..184792e --- /dev/null +++ b/ztunekey.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Name=Tuning/Key +Type=Application +Exec=/home/urchlay/bin/ztunekey %f +Icon=ztunekey +Terminal=false +StartupNotify=false +Hidden=false diff --git a/ztunekey.png b/ztunekey.png Binary files differnew file mode 100644 index 0000000..d152c37 --- /dev/null +++ b/ztunekey.png |