forked from ology/Music
-
Notifications
You must be signed in to change notification settings - Fork 0
/
voss-method
55 lines (39 loc) · 1.01 KB
/
voss-method
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
#!/usr/bin/env perl
# "Musimathics" pg. 358 - Voss's Method
use strict;
use warnings;
use Math::Random::OO::Uniform;
=for curiosity
for my $n ( 0 .. 15 ) {
for my $k ( 0 .. 3 ) {
my $x = 2 ** $k;
my $y = $n % $x;
print "$n % 2 ** $k ($x) = $y\n";
print "\t*\n" if $y == 0;
}
}
exit;
=cut
my $max = shift || 16;
my @notes = @ARGV ? @ARGV : qw( C5 Ds5 F5 G5 A5 );
my $zero_to_one = Math::Random::OO::Uniform->new;
my $neg_one_to_one = Math::Random::OO::Uniform->new( -1, 1 );
my @seed = map { $zero_to_one->next } 1 .. 4;
my @result;
for my $n ( 0 .. $max - 1 ) {
my $x = voss( $n, \@seed );
my $y = sprintf '%.0f', $x; # XXX This is questionable
$result[$n] = $notes[$y];
warn "$x => $y => $result[$n]\n";
}
sub voss {
my ( $n, $list ) = @_;
my $sum = 0;
for my $k ( 0 .. @$list - 1 ) {
if ( $n % ( 2 ** $k ) == 0 ) {
$list->[$k] = $neg_one_to_one->next;
}
$sum += $list->[$k];
}
return $sum;
}