ONO::Lib::Audio::Pro::Music::Theory

package ONO::Lib::Audio::Pro::Music::Theory;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################

use strict;

###############################################################################
# music
###############################################################################

sub notes {

#: Music notes.

return ('C','C#','D','D#','E','F','F#','G','G#','A','A#','B');
}

sub scale_major {

#: Music scale.

return (1,0,1,0,1,1,0,1,0,1,0,1);
}

sub scale_minor {

#: Music scale.

return (1,0,1,1,0,1,0,1,1,0,1,0);
}

sub scale_major_pentatonic {

#: Music scale.

return (1,0,1,0,1,0,0,1,0,1,0,0);
}

sub scale_minor_pentatonic {

#: Music scale.

return (1,0,0,1,0,1,0,1,0,0,1,0);
}

sub scale_major_blues {

#: Music scale.

return (1,0,1,2,1,0,0,1,0,1,0,0);
}

sub scale_minor_blues {

#: Music scale.

return (1,0,0,1,0,1,2,1,0,0,1,0);
}

sub scale_major_flamenco {

#: Music scale.

return (1,0,1,0,1,1,0,1,2,1,0,1);
}

sub scale_minor_flamenco {

#: Music scale.

return (1,0,1,1,0,1,0,1,1,0,1,2);
}

sub scalenotes {

#: Return music scale notes.

my @scale = &scale_major;
if ($_[2] eq "minor") {
@scale = &scale_minor;
}
my @notes = (¬es,¬es);
my $counter = $_[1];
my $LIST;
foreach my $note (@scale) {
if ($note) {
$LIST .= "$notes[$counter] ";
}
$counter++;
}
$LIST =~ s~ $~~;
return $LIST;
}

sub scale_major_rotate {

#: Rotate a major scale.

my @scale = (&scale_major,&scale_major);
if ($_[2] eq "pentatonic") {
@scale = (&scale_major_pentatonic,&scale_major_pentatonic);
}
if ($_[2] eq "blues") {
@scale = (&scale_major_blues,&scale_major_blues);
}
if ($_[2] eq "flamenco") {
@scale = (&scale_major_flamenco,&scale_major_flamenco);
}
splice @scale, 0, (12-$_[1]);
return @scale;
}

sub scale_minor_rotate {

#: Rotate a minor scale.

my @scale = (&scale_minor,&scale_minor);
if ($_[2] eq "pentatonic") {
@scale = (&scale_minor_pentatonic,&scale_minor_pentatonic);
}
if ($_[2] eq "blues") {
@scale = (&scale_minor_blues,&scale_minor_blues);
}
if ($_[2] eq "flamenco") {
@scale = (&scale_minor_flamenco,&scale_minor_flamenco);
}
splice @scale, 0, (12-$_[1]);
return @scale;
}

# chords - 0 = none, 1 = maj, 2 = min, 3 = dim

sub chords_major {

#: Major scale chords.

return (1,0,2,0,2,1,0,1,0,2,0,3);
}

sub chords_minor {

#: Minor scale chords.

return (2,0,3,1,0,2,0,2,1,0,1,0);
}

sub chord_types {

#: Chord types (maj, min, dim).
#:
#: -h human readable

if ($_[1] =~ /h/) {
return ('','Maj','min','dim');
} else {
return ('','maj','min','dim');
}
}

sub chords {

#: Return chords.

my @chords = &chords_major();
if ($_[1] eq "min" || $_[1] eq "minor") {
@chords = &chords_minor();
}
return @chords;
}

###############################################################################
# end of script
###############################################################################

1;

__END__