forked from ology/Music
-
Notifications
You must be signed in to change notification settings - Fork 0
/
note-transition-sync
61 lines (44 loc) · 1.37 KB
/
note-transition-sync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env perl
use strict;
use warnings;
# Run this, to produce a freq file, then run stat-walk-sync with it.
use Data::Dumper::Compact qw(ddc);
use MIDI;
use Statistics::Frequency;
use Storable;
my $file = shift || die "Usage: perl $0 tune.mid\n";
my $opus = MIDI::Opus->new({ from_file => $file });
my %events;
for my $i ( 0 .. scalar( $opus->tracks ) - 1 ) {
my $track = [ $opus->tracks ]->[$i];
push @{ $events{$i} }, ( grep { $_->[0] eq 'note_on' } $track->events );
}
# Setup the transition buckets
my $transitions = {};
# Gather the transitions
for my $key ( keys %events ) {
my $event = $events{$key};
my $previous;
for my $e ( @$event ) {
my $next = $e->[3];
if ( $previous ) {
push @{ $transitions->{$key}{$previous} }, $next;
}
$previous = $next;
}
}
#warn 'Note transitions: ', ddc($transitions);
# Frequency bucket
my $frequencies = {};
# Gather the proportional frequencies of each transition
for my $track ( keys %$transitions ) {
my $notes = $transitions->{$track};
for my $note ( keys %$notes ) {
my $stat = Statistics::Frequency->new;
$stat->add_data( @{ $notes->{$note} } );
$frequencies->{$track}{$note} = { $stat->proportional_frequencies };
$stat->clear_data;
}
}
warn 'Transition frequencies: ', ddc($frequencies);
store $frequencies, "$0.dat";