#!/usr/bin/env perl
mess around with trig functions, producing MIDI of dubious merit
use 5.36.0;
use MIDI;
my @events;
my $out_file = shift // 'out.midi';
how fine or coarse to check on the output of the equation (will depend
on the equation, how many notes you want, how much silence from
overchecking for zero-crossings, etc)
my $step = 0.05;
how long to carry the steps for
my $max_step = 101;
how long of a MIDI event to generate (also used for silence
accumulation). the MIDI tempo could also be played around with,
or $step could be used as a real-time value to sleep for, with a
live synth
my $tick = 8;
sub equation ($t) {
#sin( $t * 5 ) + cos( $t * 2 );
sin( $t * 5 ) + cos( ( $t + sin( $t / 1 ) ) * 7 );
}
sub add_note ($dtime, $x) {
my @n = qw(48 49 48 48 48 49 49 48);
state $i = 0;
my $n = $n[$i++ % @n];
#my @n = qw(48 49 53 55 56);
#my $n = $n[abs($x * @n)];
#$n = 48;
push @events,
[ note_on => $dtime, 0, $n, 100 ],
[ note_off => $tick, 0, $n, 0 ];
}
my $t = 0;
my $z = 0;
my $swaps = 0;
my $dtime = 0;
while ( $t < $max_step ) {
my $x = equation($t);
highlander with the previous value in a perhaps dubious use of xor
but it works so here we are
if ( ( $x >= 0 ) ^ ( $z >= 0 ) ) {
$swaps++;
#say "$t $x $prev";
add_note($dtime, $x);
$dtime = 0;
} else {
$dtime += $tick;
}
$t += $step;
$z = $x;
}
say "swaps $swaps";
sub make_tracks () { [ MIDI::Track->new( { events => \@events } ) ] }
MIDI::Opus->new(
{ format => 0, ticks => 96, tracks => make_tracks() } )
->write_to_file($out_file);
Source