Music-Chord-Positions
view release on metacpan or search on metacpan
t/Schoenberg.t view on Meta::CPAN
#!perl
#
# Test whether can reproduce Schoenberg's allowed close and open
# position chords via this module (which by default generates more
# voicings than he allowed).
#
# (Standard deviation of the pitch sets, after the fundamental is
# removed, is almost a good approximation for allowed voicings,
# though there are a few oddities that do not fit with what
# Schoenberg allows for.)
use strict;
use warnings;
use Test::More tests => 1;
eval 'use Test::Differences'; # display convenience
my $deeply = $@ ? \&is_deeply : \&eq_or_diff;
use Music::Chord::Positions;
# From "Theory of Harmony", p.37. All are close position, excepting the
# final three.
my %scho_allowed = (
'0 4 7 12' => undef,
'0 7 12 16' => undef,
'0 12 16 19' => undef,
'0 16 19 24' => undef,
'12 16 19 24' => undef,
'0 19 24 28' => undef,
'12 19 24 28' => undef,
'0 7 16 24' => undef,
'0 12 19 28' => undef,
'0 16 24 31' => undef,
);
my $mcp = Music::Chord::Positions->new;
my $chords = $mcp->chord_pos(
[qw/0 4 7/],
allow_transpositions => 1, # as SATB can transpose up
no_partial_closed => 1, # exclude half open/closed positions
pitch_max => -1, # avoids 36 in Soprano
voice_count => 4, # SATB
);
# Ranges of voices relative to C3 as 0 so can see if any of the pitches
# are out of line.
#
# Bass (-8) -5 to 11 (14)
# Tenor (0) 2 to 19 (23)
# Alto (7) 9 to 24 (28)
# Soprano (12) 14 to 29 (33)
#
# With the limited ranges, many chords excluded; at extremes listed by
# S. only the 12 24 28 31 pitch set is excluded. (non-C-based chords
# would be more likely to run into limits) - so really depends on the
# abilities of the vocalists: maybe the tenor can hit that high C,
# maybe they can't.
#my @ranges = (
# { min => -5, max => 14 },
# { min => 0, max => 23 },
# { min => 7, max => 28 },
# { min => 12, max => 33 },
#);
#
#for my $ps (@$chords) {
# for my $i ( 0 .. $#$ps ) {
# if ( $ps->[$i] < $ranges[$i]->{min} or $ps->[$i] > $ranges[$i]->{max} ) {
# diag "out of range: @$ps";
# }
# }
#}
my %results;
@results{ map { "@$_" } @$chords } = ();
# NOTE - this one transposition of (allowed) 0 12 16 19, excluded due to
( run in 1.654 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )