Reputation: 30684
I have sound files for each of the 88 keys on a piano keyboard.
p-book:OUT pi$ ls
Piano.ff.A0.aiff Piano.ff.Bb7.aiff Piano.ff.Eb1.aiff
Piano.ff.A1.aiff Piano.ff.C1.aiff Piano.ff.Eb2.aiff
Piano.ff.A2.aiff Piano.ff.C2.aiff Piano.ff.Eb3.aiff
Piano.ff.A3.aiff Piano.ff.C3.aiff Piano.ff.Eb4.aiff
Piano.ff.A4.aiff Piano.ff.C4.aiff Piano.ff.Eb5.aiff
Piano.ff.A5.aiff Piano.ff.C5.aiff Piano.ff.Eb6.aiff
Piano.ff.A6.aiff Piano.ff.C6.aiff Piano.ff.Eb7.aiff
Piano.ff.A7.aiff Piano.ff.C7.aiff Piano.ff.F1.aiff
Piano.ff.Ab1.aiff Piano.ff.C8.aiff Piano.ff.F2.aiff
Piano.ff.Ab2.aiff Piano.ff.D1.aiff Piano.ff.F3.aiff
Piano.ff.Ab3.aiff Piano.ff.D2.aiff Piano.ff.F4.aiff
Piano.ff.Ab4.aiff Piano.ff.D3.aiff Piano.ff.F5.aiff
Piano.ff.Ab5.aiff Piano.ff.D4.aiff Piano.ff.F6.aiff
Piano.ff.Ab6.aiff Piano.ff.D5.aiff Piano.ff.F7.aiff
Piano.ff.Ab7.aiff Piano.ff.D6.aiff Piano.ff.G1.aiff
Piano.ff.B0.aiff Piano.ff.D7.aiff Piano.ff.G2.aiff
Piano.ff.B1.aiff Piano.ff.Db1.aiff Piano.ff.G3.aiff
Piano.ff.B2.aiff Piano.ff.Db2.aiff Piano.ff.G4.aiff
Piano.ff.B3.aiff Piano.ff.Db3.aiff Piano.ff.G5.aiff
Piano.ff.B4.aiff Piano.ff.Db4.aiff Piano.ff.G6.aiff
Piano.ff.B5.aiff Piano.ff.Db5.aiff Piano.ff.G7.aiff
Piano.ff.B6.aiff Piano.ff.Db6.aiff Piano.ff.Gb1.aiff
Piano.ff.B7.aiff Piano.ff.Db7.aiff Piano.ff.Gb2.aiff
Piano.ff.Bb0.aiff Piano.ff.E1.aiff Piano.ff.Gb3.aiff
Piano.ff.Bb1.aiff Piano.ff.E2.aiff Piano.ff.Gb4.aiff
Piano.ff.Bb2.aiff Piano.ff.E3.aiff Piano.ff.Gb5.aiff
Piano.ff.Bb3.aiff Piano.ff.E4.aiff Piano.ff.Gb6.aiff
Piano.ff.Bb4.aiff Piano.ff.E5.aiff Piano.ff.Gb7.aiff
Piano.ff.Bb5.aiff Piano.ff.E6.aiff
Piano.ff.Bb6.aiff Piano.ff.E7.aiff
I wish to rename them to their MIDI note number:
Piano.ff.A0.aiff -> 21.aiff
Piano.ff.Bb0.aiff -> 22.aiff
Piano.ff.B0.aiff -> 23.aiff
Piano.ff.C1.aiff -> 24.aiff
:
(21 is the MIDI number for the lowest note on a piano)
While 88 is probably more a 'do it by hand' size, I'm curious whether it can be automated in a few lines of Bash
If:
'C' ~ 0
'Db' ~ 1
'D' ~ 2
:
'B' ~ 11
Then I could do:
MidiNote = NumberForPitchclass( pitchclassstring ) + 12 * octave
But does Bash have the apparatus for this operation?
Upvotes: 0
Views: 217
Reputation: 95252
If you have bash 4, using associative arrays would be the way to go:
noteNames=(C Db D Eb E F Gb G Ab A Bb B)
declare -A noteNumbers
for (( i=0; i<${#noteNames[@]}; ++i )); do
noteNumbers[${noteNames[i]}]=$i
done
for f in *.aiff; do
note="${f#Piano.ff.}"
note="${note%.aiff}"
name="${note%%[0-9]*}"
octave="${note#$name}"
if [ ! -n "${noteNumbers[$name]}" ]; then
echo >&2 "$0: not renaming $f - note not found"
else
let midiNote=${noteNumbers[$name]}+12*octave
mv "$f" "$midiNote.aiff"
fi
done
If you don't have bash 4, you can do it more manually by looping through the notes for every file instead of just once at the beginning:
noteNames=(C Db D Eb E F Gb G Ab A Bb B)
for f in *.aiff; do
note="${f#Piano.ff.}"
note="${note%.aiff}"
name="${note%%[0-9]*}"
octave="${note#$name}"
for (( base=0; base<${#noteNames[@]}; ++base )); do
if [[ "${noteNames[base]}" == $name ]]; then
break
fi
done
if (( base >= ${#noteNames[@]} )); then
echo >&2 "$0: not renaming $f - note not found"
else
let midiNote=base+12*octave
mv "$f" "$midiNote.aiff"
fi
done
However, that gives A0 the number 10, where you said it was 21, so you apparently need to add 11 to those numbers.
Upvotes: 2