#!/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