0

我有钢琴键盘上 88 个键中每个键的声音文件。

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

我希望将它们重命名为它们的 MIDI 音符编号:

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 是钢琴上最低音符的 MIDI 编号)

虽然 88 可能更像是“手工”大小,但我很好奇它是否可以在几行 Bash 中实现自动化

如果:

'C'  ~ 0  
'Db' ~ 1  
'D'  ~ 2  
:  
'B'  ~ 11  

然后我可以这样做:

MidiNote = NumberForPitchclass( pitchclassstring ) + 12 * octave

但是 Bash 有执行此操作的设备吗?

4

1 回答 1

2

如果您有 bash 4,则可以使用关联数组:

   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

如果您没有 bash 4,则可以通过循环遍历每个文件的注释而不是在开始时仅循环一次来更手动地执行此操作:

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

但是,这给 A0 数字 10,你说它是 21,所以你显然需要在这些数字上加上 11。

于 2013-11-15T02:31:22.697 回答