NAME

MIDI::Ngram - Find the top repeated note phrases of MIDI files

VERSION

version 0.1808

SYNOPSIS

use MIDI::Ngram;

# Analyze a tune and build a new MIDI file of repetitions
my $mng = MIDI::Ngram->new(
  in_file      => [ 'eg/twinkle_twinkle.mid' ],
  ngram_size   => 3,
  min_phrases  => 3,
  max_phrases  => 0, # Analyze all events
  patches      => [qw( 68 69 70 71 72 73 )],
  random_patch => 1,
);

$mng->process;

# Analyze
print Dumper $mng->dura_notes;
print Dumper $mng->duras;
print Dumper $mng->notes;

print Dumper $mng->dura_note_net;
print Dumper $mng->dura_net;
print Dumper $mng->note_net;

my $playback = $mng->populate;
print $playback;

$mng->write;

# Convert a MIDI number string to a duration or note name.
my $named = $mng->dura_convert('96'); # qn
$named = $mng->note_convert('60 61,62'); # C4 Cs4,D4

DESCRIPTION

MIDI::Ngram parses a given list of MIDI files, finds the top repeated note phrases, builds the transition networks, and renders to a MIDI file if desired.

Note: This module currently assumes that all given in_files have the same MIDI ppqn (given by the first $opus->ticks seen).

ATTRIBUTES

in_file

Required. An Array reference of MIDI files to process.

ngram_size

Ngram phrase size.

Default: 2

min_phrases

Integer. Allow a minimum of this number of ngram occurrences in both the repetition and network lists.

Default: 2

max_phrases

The maximum number of phrases to analyze/play.

Default: 0

Setting this to a value of 0 analyzes all phrases.

bpm

Beats per minute.

Default: 100

durations

The optional MIDI note durations to choose from (at random).

Default: [] (i.e. use the computed dura phrases instead)

Using a setting of ['qn'] allows you to evenly inspect the phrases during audio playback.

patches

The patches to choose from (at random) if given the random_patch option.

Default: [0 .. 127]

random_patch

Boolean. Choose a random patch from patches for each channel.

Default: 0 (meaning "use the piano patch")

out_file

MIDI output file.

Default: midi-ngram.mid

pause_duration

Insert a rest of the given duration after each phrase.

Default: '' (no resting)

analyze

Array reference of the channels to analyze. If not given, all channels are analyzed.

Default: undef

loop

The number of times to choose a weighted phrase. * This only works in conjunction with the weight option.

Default: 10

weight

Boolean. Play phrases according to the probability of their repetition occurrence with the function "choose_weighted" in List::Util::WeightedChoice.

Default: 0

shuffle_phrases

Boolean. Shuffle the non-weighted phrases before playing them.

Default: 0

one_channel

Boolean. Accumulate phrases onto a single playback channel.

Default: 0

score

The score object in "MAIN-ROUTINES" in MIDI::Simple. Constructed by the populate method.

dura_notes

The hash-reference bucket of duration*note ngrams. Constructed by the process method.

The combination of duration with a note is indicated with the * character. For example: ten*Cs4

notes

The hash-reference bucket of pitch ngrams. Constructed by the process method.

Notes are represented in MIDI format with octave number like, Cs4. A cluster of repeated notes is separated by spaces. Simultaneous notes are separated with a comma (,). For example: A4,Cs5.

dura

The hash-reference bucket of duration ngrams. Constructed by the process method.

Durations are represented in MIDI::Simple style format. For example, hn for a known length and d123 for a tick duration. A cluster of repeated durations is separated by spaces. Simultaneous durations are separated with a comma (,). For example: hn,d85.

dura_net

A hash-reference ngram transition network of the durations.

A dash or hyphen (-) divides nodes. For example: qn,hn qn-qn,hn qn where the nodes are both qn,hn qn and qn,hn qn.

note_net

A hash-reference ngram transition network of the notes.

A dash or hyphen (-) divides nodes. For example: A4 G4,E3-F4,D3 F4 where the nodes are A4 G4,E3 and F4,D3 F4.

dura_note_net

A hash-reference ngram transition network of the durations and notes considered as a unit.

A dash or hyphen (-) divides nodes. For example: qn*C3 qn*G4,hn*E3-qn*G4 qn*F4,hn*F3 where the nodes are qn*C3 qn*G4,hn*E3 and qn*G4 qn*F4,hn*F3.

METHODS

new

$mng = MIDI::Ngram->new(%arguments);

Create a new MIDI::Ngram object.

process

$mng->process;

Find all ngram phrases of durations, notes and both combined.

This method creates the dura_notes, dura, and notes repetition lists.

populate

$playback = $mng->populate;

Add notes to the MIDI score and return the playback notes.

write

$mng->write;

Write out the MIDI file.

dura_convert

$durations = $mng->dura_convert($string);

Convert MIDI numbers to named durations.

note_convert

$notes = $mng->note_convert($string);

Convert MIDI numbers to named notes.

dura_note_convert

$dura_notes = $mng->dura_note_convert($string);

Convert MIDI numbers to named duration*note strings.

SEE ALSO

Moo

Lingua::EN::Ngram

List::Util

List::Util::WeightedChoice

Music::Note

MIDI::Util

AUTHOR

Gene Boggs <gene@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2022 by Gene Boggs.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.