Created
February 26, 2012 11:58
-
-
Save coderofsalvation/1916306 to your computer and use it in GitHub Desktop.
samplescan.sh - converts directories with audiosamples into symbolically linked trees sorted on harmonic key/scale
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment