public
Created

samplescan.sh - converts directories with audiosamples into symbolically linked trees sorted on harmonic key/scale

  • Download Gist
gistfile1.sh
Shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
#!/bin/bash
#
# Samplescan - scans directories with wav-files on harmonic content
#
# (By determining the keys, and a symbolically linked directory structure)
#
# pre-requisites: vamp-plugin-sdk package (http://www.vamp-plugins.org)
#
###########################################################################
#
# Copyright (C) 2012 Coder of Salvation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
 
# <indir> <outdir> [prefix] [sleep] # this will scan the given directory for keys
keys(){
if [ ${#1} == 0 ]; then echo "$CMDS" | echo "Usage: "; _usage; fi
if [ ${#2} == 0 ]; then echo "$CMDS" | echo "Usage: "; _usage; fi
local dirinput="$1"
local diroutput="$2"
local prefix="$3"
local sleep="$4"
local recurse="$5"
local i=0
if [ ! -d "$diroutput" ]; then
mkdir "$diroutput"
create_outputdir "$diroutput"
fi
if [ "$recurse" != 1 ]; then
echo "[x] caching already scanned files using mlocate (please wait)"
updatedb -o $diroutput/.mlocate -U $diroutput
fi
for file in "$dirinput/*"; do
if [ -d "$file" ]; then
if [ "$file" != "$diroutput" ]; then keys "$file" "$diroutput" "$prefix" "$sleep" "1"; fi
else
key "$file" "$diroutput" "$prefix" "$sleep";
fi
# if [ ${#sleep} != 0 ]; then nice -n19 sleep $sleep; fi
# ((i=i+1))
# if [ $i == 5 ]; then exit; fi
done
}
 
# <file> <outdir> [prefix] [sleep] # this will scan the given file for keys
key(){
local tmp=/tmp/samplescan.tmp
local input=$(echo "$1"| sed "s/\.\///g")
local inputbase=$(basename "$input")
local inputismp3=$(echo "$inputbase" | grep -i "mp3")
local outputdir="$2"
local prefix="$3"
local sleep="$4"
printf "\r[x] checking $input"
local scanned=$(locate -d "$outputdir/.mlocate" "$inputbase" | grep "$outputdir" )
if [ ${#scanned} != 0 ]; then return; fi
if [ ${#inputismp3} != 0 ]; then
sox -V1 "$input" /tmp/samplescan.wav
local output=$(vamp-simple-host qm-vamp-plugins.so:qm-keydetector "/tmp/samplescan.wav" -o "$tmp" 1> /dev/null 2>&1 )
else
local output=$(vamp-simple-host qm-vamp-plugins.so:qm-keydetector "$input" -o "$tmp" 1> /dev/null 2>&1 )
fi
if [ -f "$tmp" ]; then
cat "$tmp" | while read key; do
local key=$( key_to_string "$key" )
local out="$outputdir/$key/$inputbase"
if [ ! -f "$out" ] ; then
if [ ! -e "$out" ]; then ln -s "$prefix$input" "$out"; fi
fi
printf "\n[x] '$key' -> $out\n"
done
rm "$tmp";
fi
}
 
create_outputdir(){
local i=1
local dir="$1"
while [ "$i" != 25 ]; do
local dirname=$(key_to_string "$i")
mkdir "$dir/$dirname" 1> /dev/null 2>&1
((i=i+1))
done
}
 
key_to_string(){
# The estimated key for each key change, returned as a single-valued feature
# at the point where the key change is detected, with value counted from 1 to 24
# where 1-12 are the major keys and 13-24 are the minor keys, such that C major is
# 1, C# major is 2, and so on up to B major which is 12; then C minor is 13, Db
# minor is 14, and so on up to B minor which is 24.
local key=$(echo "$1" | sed "s/ //g;s/.*://g")
if [ "$key" == "1" ] ; then key="C" ; fi
if [ "$key" == "2" ] ; then key="Cmaj" ; fi
if [ "$key" == "3" ] ; then key="D" ; fi
if [ "$key" == "4" ] ; then key="Dmaj" ; fi
if [ "$key" == "5" ] ; then key="E" ; fi
if [ "$key" == "6" ] ; then key="F" ; fi
if [ "$key" == "7" ] ; then key="Fmaj" ; fi
if [ "$key" == "8" ] ; then key="G" ; fi
if [ "$key" == "9" ] ; then key="Gmaj" ; fi
if [ "$key" == "10" ] ; then key="A" ; fi
if [ "$key" == "11" ] ; then key="Amaj" ; fi
if [ "$key" == "12" ] ; then key="B" ; fi
if [ "$key" == "13" ] ; then key="C" ; fi
if [ "$key" == "14" ] ; then key="Cmin" ; fi
if [ "$key" == "15" ] ; then key="D" ; fi
if [ "$key" == "16" ] ; then key="Dmin" ; fi
if [ "$key" == "17" ] ; then key="E" ; fi
if [ "$key" == "18" ] ; then key="F" ; fi
if [ "$key" == "19" ] ; then key="Fmin" ; fi
if [ "$key" == "20" ] ; then key="G" ; fi
if [ "$key" == "21" ] ; then key="Gmin" ; fi
if [ "$key" == "22" ] ; then key="A" ; fi
if [ "$key" == "23" ] ; then key="Amin" ; fi
if [ "$key" == "24" ] ; then key="B" ; fi
echo "$key"
}
 
_usage(){
grep "^[^_].\+(){$" $0 | while read line; do
local cmd=$(echo "$line" | sed "s/(){//g")
local info=$(grep -C0 -A0 -B1 "$cmd(){" $0 | sed "N;s/\n.*//g" )
printf " $0 %-5s %-40s\n" "$cmd" "$info" | grep "#"
done;
printf "\n example: samplescan keys . sorted-by-key \"../../\"\n\n"
exit
}
 
# run arguments as commands if any, or show Usage
"$@"
if [ ${#1} == 0 ]; then echo "$CMDS" | echo "Usage: "; _usage; fi

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.