Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use strict;
- use MIDI;
- use Math::Trig;
- use warnings;
- my $tick_length = 1536;
- my $z = 8;
- my $num_cycles = 8;
- my $track_length = 16*$num_cycles*$tick_length*4;
- my @score_events;
- my $track1_dur = (sub {
- my $t = $_[0] <= $track_length/2 ? $_[0] : $track_length-$_[0];
- my $m = $_[0] <= $track_length/2 ? 1 : -1;
- return 3.0*2.0**($z+$m*($t/($track_length/$num_cycles))
- *sin($t*2.0*pi/($track_length/$num_cycles)));});
- my $track2_dur = (sub {
- my $t = $_[0] <= $track_length/2 ? $_[0] : $track_length-$_[0];
- my $m = $_[0] <= $track_length/2 ? -1 : 1;
- return 3.0*2.0**($z+$m*($t/($track_length/$num_cycles))
- *sin($t*2.0*pi/($track_length/$num_cycles)));});
- my $track3_dur = (sub {
- my $t = $_[0] <= $track_length/2 ? $_[0] : $track_length-$_[0];
- return 3.0*2.0**($z+($t/($track_length/$num_cycles))
- *cos($t*2.0*pi/($track_length/$num_cycles)));});
- my $track4_dur = (sub {
- my $t = $_[0] <= $track_length/2 ? $_[0] : $track_length-$_[0];
- return 3.0*2.0**($z-($t/($track_length/$num_cycles))
- *cos($t*2.0*pi/($track_length/$num_cycles)));});
- for ([0,$track1_dur],[1,$track2_dur],[2,$track3_dur],[3,$track4_dur]) {
- my ($channel,$f) = @{$_};
- my $i = 0;
- my @channel_starts;
- while ($i < $track_length) {
- push @channel_starts,int($i);
- $i+=&{$f}($i);
- }
- for (my $j = 0; $j < $#channel_starts-1; $j++) {
- push @score_events, ['note',$channel_starts[$j],$channel_starts[$j+1]- $channel_starts[$j],$channel,60,120];
- }
- }
- sub midi_note {
- my $raw = 57+12*log($_[0]/440.0)/log(2);
- my $offset = $raw - int($raw);
- my $note = sprintf("%.0f",$raw);
- return [$note,$offset >=0.5 ? $offset-1 : $offset];
- }
- my @colundi_freqs = (70,105,172,210,264,342,431,528,630,685,852,1052);
- my %all_freqs_hash;
- for my $i (1..4) {
- for my $f (@colundi_freqs) {
- my $note_info = midi_note($f*$i);
- $all_freqs_hash{sprintf "%d %.2f", @{$note_info}}=1;
- }}
- my @all_freqs = sort {$a cmp $b} keys %all_freqs_hash;
- do {
- my @sub_events;
- my $j = int ($#all_freqs/2);
- my $k = int ($#all_freqs/2);
- for (my $i = 0; $i < $track_length/2; $i+=$track_length/$num_cycles/2) {
- my ($note1,$offset1) = split /\s/,$all_freqs[$j];
- my ($note2,$offset2) = split /\s/,$all_freqs[$k];
- push @sub_events,
- ['note',$i,$tick_length,4,$note1,120],
- ['control_change',$i,4,0,int(64*(1-$offset1))],
- ['note',$i,$tick_length,5,$note2,120],
- ['control_change',$i,5,0,int(64*(1-$offset2))];
- #printf "%s %s\n", $all_freqs[$j],$all_freqs[$k];
- $j+=2; $k-=2;
- }
- for (my $i = $track_length/2; $i < $track_length; $i+=$track_length/$num_cycles/2) {
- my ($note1,$offset1) = split /\s/,$all_freqs[$j];
- my ($note2,$offset2) = split /\s/,$all_freqs[$k];
- push @sub_events,
- ['note',$i,$tick_length,4,$note1,120],
- ['control_change',$i,4,0,int(64*(1-$offset1))],
- ['note',$i,$tick_length,5,$note2,120],
- ['control_change',$i,5,0,int(64*(1-$offset2))];
- #printf "%s %s\n", $all_freqs[$j],$all_freqs[$k];
- $j-=2; $k+=2;
- }
- $j=int ($#all_freqs/2)+1;
- $k=int ($#all_freqs/2)-1;
- for (my $i = $tick_length*16; $i < $track_length; $i+=$track_length/$num_cycles/2) {
- my ($note1,$offset1) = split /\s/,$all_freqs[$j];
- my ($note2,$offset2) = split /\s/,$all_freqs[$k];
- push @sub_events,
- ['note',$i,$tick_length,6,$note1,120],
- ['control_change',$i,6,0,int(64*(1-$offset1))],
- ['note',$i,$tick_length,7,$note2,120],
- ['control_change',$i,7,0,int(64*(1-$offset2))];
- $j+=($i<$track_length/2) ? 2 : -2;
- $k-=($i<$track_length/2) ? 2 : -2;
- }
- push @score_events,@sub_events;
- };
- my $track = MIDI::Track->new;
- $track->events(@{MIDI::Score::score_r_to_events_r(\@score_events)});
- my $opus = MIDI::Opus->new({ 'tracks' => [ $track ], 'ticks' => $tick_length });
- $opus->write_to_file('cycle1.mid');
- #print &{$note_dur_fn1}($tick_length*4*$_),"\n" for 0..40;
- #do {my $i = $_; print( join " ", map {my $f = $_; sprintf("%.2f",&{$f}($i*4*$tick_length));} ($track1_dur,$track2_dur,$track3_dur,$track4_dur));print "\n"} for (0..40);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement