-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmid2beep
executable file
·154 lines (135 loc) · 2.75 KB
/
mid2beep
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
144
145
146
147
148
149
150
151
152
153
154
#!/bin/bash
containsElement () {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
compute () {
LANG=POSIX
LC_NUMERIC=POSIX
printf '%.2f' $(bc -l <<< "$1")
}
#IFS=$'\n'
displayinfos=NO
quiet=NO
channel=1
userspeed=1
showbeep=YES
showprogress=YES
midifile=""
usage=" $(basename "$0") [-b] [-c=n] [-h] [-i] [-p] [-q] [-s=n] -m=file\n
Program to play a midi track on the PC speaker/buzzer\n
where:\n
\t\t-b Do not display beep command\n
\t\t-c Choose the MIDI channel you want to play (default : 1)\n
\t\t-h Display this help\n
\t\t-i Display infos about the MIDI file (useful for finding channels)\n
\t\t-m MIDI file to play (mandatory)\n
\t\t-p Do not display progress info\n
\t\t-q Doesn't play a sound\n
\t\t-s Modify the speed of playback (not limited to int)"
for i in "$@"
do
case $i in
-s=*|--speed=*)
userspeed="${i#*=}"
shift
;;
-m=*|--midi=*)
midifile="${i#*=}"
shift
;;
-c=*|--channel=*)
channel="${i#*=}"
shift
;;
-q|--quiet)
quiet=YES
shift
;;
-b|--hidebeep)
showbeep=NO
shift
;;
-p|--noprogress)
showprogress=NO
shift
;;
-i|--infos)
displayinfos=YES
shift
;;
-h|--help)
echo -e $usage
exit
;;
*)
# unknown option
;;
esac
done
if [[ $midifile == "" ]]; then
echo -e $usage
exit
fi
command=""
factor=1
tracks=()
{
IFS=$'\n'
tab=( $(midi2abc $midifile -midigram) )
}
{
IFS=$''
infos=( $(midi2abc $midifile -sum) )
}
ticks=`od -An -j 12 -N 2 --endian=big -vd $midifile | xargs`
bpm=`echo "${infos[@]}" | grep Tempo | awk '{print $2}'`
factor=`compute "60000/($bpm*$ticks)"`
lastend=10000000
lastfirst=10000000
for (( i=0; i<=${#tab[@]}; i++ ))
do
if [[ $showprogress == YES ]]; then
echo -ne " Done $i notes on ${#tab[@]} \r"
fi
{
IFS=' '
arr=( ${tab[$i]} )
}
first=${arr[0]}
track=${arr[3]}
if [[ $displayinfos == YES ]]; then
containsElement "$track" "${tracks[@]}"
if [[ $? -eq 1 ]]; then
tracks+=(${track})
fi
fi
if [ "$track" = "$channel" ] && [ $lastfirst -ne $first ]; then
second=${arr[1]}
midinote=${arr[4]}
delay=`compute "$userspeed*$factor*($first-$lastend)"`
note=`compute "440*e((($midinote-69)/12)*l(2))"`
time=`compute "$userspeed*$factor*($second-$first)"`
if (( $(bc <<< "$delay > 0") )); then
command="$command -D $delay"
fi
command="$command -n -f $note -l $time"
lastend=$second
lastfirst=$first
fi
done
if [[ $displayinfos == YES ]]; then
output="Length ${#tab[@]} ; Ticks $ticks ; BPM $bpm ; Speed factor $factor ; NbChannels ${#tracks[@]} :"
for (( i=0; i<=${#tracks[@]}; i++ ))
do
output="$output ${tracks[$i]}"
done
echo "$output"
fi
if [[ $showbeep == YES ]]; then
echo "beep `echo $command | cut -b1-`"
fi
if [[ $quiet == NO ]]; then
echo $command | cut -b1- | xargs beep
fi