Код: Выделить всё
#
# MIDI player by MikroTourette 2017
# with enhancements by jgro 2022
#
# notes is array of MIDI notes with optional length: note/length
# Length is number of ticks. If omitted, length will be set to $defaultTicks.
# Use 0 for rests.
:local notes 65,65,65,62/16,0,64,64,64,61/32;
# Tempo
# Because clock resolution is only 10ms, you need much longer ticks than standard MIDI
:local tick 50ms; # length of a tick
:local defaultTicks 4; # default number of ticks for a note
:local stacc 10ms; # length of break between notes
:local transpose 0; # number to add to or subtract from each note (12 is 1 octave)
# MIDI player
# Frequencies from C9 (MIDI 120) through B9 (beyond MIDI top note of 127)
:local frqtab 8372,8869,9397,9956,10548,11175,11839,12543,13288,14080,14916,15804;
:local n0; :local n;
:local d0; :local d;
:local l;
:local midi;
:local i;
:local octa;
:local frq;
:local tones;
:local durations;
:for i from=0 to= ([:len $notes]-1) do={
:local entry [:pick $notes $i];
:local div [:find $entry "/"];
:if ([:typeof $div] = "nil") do={
:set tones ($tones, $entry);
:set durations ($durations, $defaultTicks);
} else={
:set tones ($tones, [:pick $entry 0 $div]);
:set durations ($durations, [:pick $entry ($div + 1) [:len $entry]]);
}
}
:for i from=0 to= ([:len $notes]-1) do={
:set midi [:pick $tones $i];
:set midi ($midi + $transpose);
:set octa 0;
:while ($midi < 120) do={:set midi ($midi + 12); :set octa ($octa + 1); };
:set midi ($midi % 12);
:set frq [:tonum [:pick $frqtab $midi]];
:set frq ($frq>>($octa));
:set d0 [:pick $durations $i];
:set d ($d0 * $tick );
:set l ($d0 * ($tick - $stacc));
# :put $midi;
# :put $frq;
# :put $octa;
if ($frq >= 20) do={
:beep frequency=$frq length=$l;
}
:delay $d;
}