Advertisement
Guest User

Untitled

a guest
May 24th, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 4.07 KB | None | 0 0
  1. use strict;
  2. use MIDI;
  3. use Math::Trig;
  4. use warnings;
  5.  
  6. my $tick_length = 1536;
  7. my $z = 8;
  8. my $num_cycles = 8;
  9. my $track_length = 16*$num_cycles*$tick_length*4;
  10.  
  11. my @score_events;
  12.  
  13. my $track1_dur = (sub {
  14.     my $t = $_[0] <= $track_length/2 ? $_[0] : $track_length-$_[0];
  15.     my $m = $_[0] <= $track_length/2 ? 1 : -1;
  16.     return 3.0*2.0**($z+$m*($t/($track_length/$num_cycles))
  17.              *sin($t*2.0*pi/($track_length/$num_cycles)));});
  18.  
  19. my $track2_dur = (sub {
  20.     my $t = $_[0] <= $track_length/2 ? $_[0] : $track_length-$_[0];
  21.     my $m = $_[0] <= $track_length/2 ? -1 : 1;
  22.     return 3.0*2.0**($z+$m*($t/($track_length/$num_cycles))
  23.              *sin($t*2.0*pi/($track_length/$num_cycles)));});
  24.  
  25. my $track3_dur = (sub {
  26.     my $t = $_[0] <= $track_length/2 ? $_[0] : $track_length-$_[0];
  27.     return 3.0*2.0**($z+($t/($track_length/$num_cycles))
  28.              *cos($t*2.0*pi/($track_length/$num_cycles)));});
  29.  
  30. my $track4_dur = (sub {
  31.     my $t = $_[0] <= $track_length/2 ? $_[0] : $track_length-$_[0];
  32.     return 3.0*2.0**($z-($t/($track_length/$num_cycles))
  33.              *cos($t*2.0*pi/($track_length/$num_cycles)));});
  34.  
  35.  
  36. for ([0,$track1_dur],[1,$track2_dur],[2,$track3_dur],[3,$track4_dur]) {
  37.     my ($channel,$f) = @{$_};
  38.     my $i = 0;
  39.     my @channel_starts;
  40.     while ($i < $track_length) {
  41.     push @channel_starts,int($i);
  42.     $i+=&{$f}($i);
  43.     }
  44.     for (my $j = 0; $j < $#channel_starts-1; $j++) {
  45.     push @score_events, ['note',$channel_starts[$j],$channel_starts[$j+1]- $channel_starts[$j],$channel,60,120];
  46.     }
  47. }
  48.  
  49. sub midi_note {
  50.     my $raw = 57+12*log($_[0]/440.0)/log(2);
  51.     my $offset = $raw - int($raw);
  52.     my $note = sprintf("%.0f",$raw);
  53.     return [$note,$offset >=0.5 ? $offset-1 : $offset];
  54. }
  55.  
  56. my @colundi_freqs = (70,105,172,210,264,342,431,528,630,685,852,1052);
  57. my %all_freqs_hash;
  58. for my $i (1..4) {
  59.     for my $f (@colundi_freqs) {
  60.     my $note_info = midi_note($f*$i);
  61.     $all_freqs_hash{sprintf "%d %.2f", @{$note_info}}=1;
  62.     }}
  63. my @all_freqs = sort {$a cmp $b} keys %all_freqs_hash;
  64.  
  65. do {
  66.     my @sub_events;
  67.     my $j = int ($#all_freqs/2);
  68.     my $k = int ($#all_freqs/2);
  69.     for (my $i = 0; $i < $track_length/2; $i+=$track_length/$num_cycles/2) {
  70.     my ($note1,$offset1) = split /\s/,$all_freqs[$j];
  71.     my ($note2,$offset2) = split /\s/,$all_freqs[$k];
  72.     push @sub_events,
  73.         ['note',$i,$tick_length,4,$note1,120],
  74.         ['control_change',$i,4,0,int(64*(1-$offset1))],
  75.         ['note',$i,$tick_length,5,$note2,120],
  76.         ['control_change',$i,5,0,int(64*(1-$offset2))];
  77.     #printf "%s %s\n", $all_freqs[$j],$all_freqs[$k];
  78.     $j+=2; $k-=2;
  79.     }
  80.     for (my $i = $track_length/2; $i < $track_length; $i+=$track_length/$num_cycles/2) {
  81.     my ($note1,$offset1) = split /\s/,$all_freqs[$j];
  82.     my ($note2,$offset2) = split /\s/,$all_freqs[$k];
  83.     push @sub_events,
  84.         ['note',$i,$tick_length,4,$note1,120],
  85.         ['control_change',$i,4,0,int(64*(1-$offset1))],
  86.         ['note',$i,$tick_length,5,$note2,120],
  87.         ['control_change',$i,5,0,int(64*(1-$offset2))];
  88.     #printf "%s %s\n", $all_freqs[$j],$all_freqs[$k];
  89.     $j-=2; $k+=2;
  90.     }
  91.     $j=int ($#all_freqs/2)+1;
  92.     $k=int ($#all_freqs/2)-1;
  93.     for (my $i = $tick_length*16; $i < $track_length; $i+=$track_length/$num_cycles/2) {
  94.     my ($note1,$offset1) = split /\s/,$all_freqs[$j];
  95.     my ($note2,$offset2) = split /\s/,$all_freqs[$k];
  96.     push @sub_events,
  97.         ['note',$i,$tick_length,6,$note1,120],
  98.         ['control_change',$i,6,0,int(64*(1-$offset1))],
  99.         ['note',$i,$tick_length,7,$note2,120],
  100.         ['control_change',$i,7,0,int(64*(1-$offset2))];
  101.     $j+=($i<$track_length/2) ? 2 : -2;
  102.     $k-=($i<$track_length/2) ? 2 : -2;
  103.     }
  104.     push @score_events,@sub_events;
  105. };
  106.  
  107. my $track = MIDI::Track->new;
  108. $track->events(@{MIDI::Score::score_r_to_events_r(\@score_events)});
  109. my $opus = MIDI::Opus->new({ 'tracks' => [ $track ], 'ticks' => $tick_length });
  110. $opus->write_to_file('cycle1.mid');
  111.  
  112. #print &{$note_dur_fn1}($tick_length*4*$_),"\n" for 0..40;
  113.  
  114. #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