AI-Gene-Sequence
view release on metacpan or search on metacpan
demo/Musicgene.pm view on Meta::CPAN
package Musicgene;
use strict;
use warnings;
use MIDI::Simple;
BEGIN {
use Exporter ();
use AI::Gene::Sequence;
our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
$VERSION = 0.01;
@ISA = qw(Exporter AI::Gene::Sequence);
@EXPORT = ();
%EXPORT_TAGS = ();
@EXPORT_OK = qw();
}
our @EXPORT_OK;
our @chords = ([qw(A C G)], [qw(A C E)]); # type c
our @octaves = (3..10); # type o
our @notes = ('A'..'G', 'rest'); # type n
our @lengths = (qw(hn qn), ''); # type l
sub new {
my $class = shift;
my $self = ['',[]];
bless $self, ref($class) || $class;
$self->mutate_insert($_[0]) if $_[0];
return $self;
}
sub generate_token {
my $self = shift;
my ($type, $prev) = @_[0,1];
my @rt;
unless ($type) {
my $rand = rand;
if ($rand < .7) {$type = 'n'}
elsif ($rand < .8) {$type = 'l'}
elsif ($rand < .9) {$type = 'o'}
elsif ($rand < 1 ) {$type = 'c'}
else {die "$0: bad probability: $rand"}
}
$rt[0] = $type;
SWITCH: for ($type) {
/n/ && do {$rt[1] = $notes[rand@notes]; last SWITCH};
/c/ && do {$rt[1] = $chords[rand@chords]; last SWITCH};
/l/ && do {$rt[1] = $lengths[rand@lengths]; last SWITCH};
/o/ && do {$rt[1] = $octaves[rand@octaves]; last SWITCH};
die "$0: unknown type: $type";
}
return @rt[0,1];
}
sub valid_gene {length($_[1]) < 50 ? 1 : 0};
sub write_file {
my $self = shift;
my $file_name = $_[0] or die "$0: No file passed to write_file";
my $opus = MIDI::Simple->new_score();
my $note_length = '';
foreach my $pos (0..(length $self->[0])) {
SWITCH: for (substr($self->[0], $pos, 1)) {
/l/ && do {$note_length = $self->[1][$pos] ;last SWITCH};
/n/ && do {$opus->n($note_length, $self->[1][$pos]) ;last SWITCH};
/o/ && do {$opus->noop('o'.$self->[1][$pos]) ;last SWITCH};
/c/ && do {$opus->n($note_length, @{$self->[1][$pos]}) ;last SWITCH};
}
}
$opus->write_score($file_name);
return;
}
## Also override mutation method
# calls mutation method at random
# 0: number of mutations to perform
# 1: ref to hash of probs to use (otherwise uses default mutations and probs)
my %probs = (
insert =>.1,
remove =>.2,
duplicate =>.4,
minor =>.5,
major =>.6,
overwrite =>.7,
reverse =>.75,
switch =>.8,
( run in 1.798 second using v1.01-cache-2.11-cpan-524268b4103 )