#!/usr/bin/perl -w

#
# $Id: music.pl,v 1.2 2002-09-10 21:47:05-05 bobn Exp bobn $
#
# generate guitar tab of scales 

# use warnings;
use strict;
use Storable qw(nstore store_fd nstore_fd freeze thaw dclone);

use Data::Dumper;
select STDERR; $|++;
select STDOUT; $|++;
use Getopt::Long;

use Guitar;
my $m = new Guitar;
my @STRINGS;

use vars qw( $NUMERIC $SHO_USAGE $DEBUG @SCALES $TUNING %OPT_CTL $LEFTIE $NUMERIC $MARKER $COMPARE 
				$LIST_CHORDS %TUNINGS $LIST_TUNINGS);

%OPT_CTL = (       
   	"numeric_output_instead_of_note_names|n!", \$NUMERIC,
              			"show_usage_-_print_this_message|h!", \$SHO_USAGE,
              				"debug|d!", \$DEBUG,
	    	      "scales_to_show|s=s@", \@SCALES,
   						 "tuning_-_default_is_e_a_d_g_b_e|t=s", \$TUNING,
						 "left_handed_-_strings_backwards|l!", \$LEFTIE,
						 "numeric|n!", \$NUMERIC,
						 "marker|m!", \$MARKER,
						 "compare_2_scales_showing_differences_and_similarities|c!", \$COMPARE,
						 "list_chords_and_scales|lc!", \$LIST_CHORDS,
						 "list_tunings|lt!", \$LIST_TUNINGS,
);


if ( not GetOptions(%OPT_CTL) or $SHO_USAGE ) { usage() }



# 'self-document' switch options
sub usage
{
    my (@f, %switch, $out, ) = ( );

	$out = "\nUsage: $0 [ -t g,d,g,d,b ] -s e,major,penatatonic  [ -l ] \n

			Options are:\n\n";

	$out =~ s/^[\cI ]*//mg;
	$out .= "\n";

    for ( keys %OPT_CTL )
    {
        @f = split(/\||=|!/);
        $switch{$f[1]} = $f[0];
    }
    for ( sort keys %switch )
    {
        my $def = $switch{$_};
        $def =~ s/\_/ /g;
        $_ = '-' . $_;
        $out .= sprintf "%4s: %s\n", $_, $def;
    }
    print "$out\n";
    exit;
}
 
$m->define_scale('t1', '', ' 0 1 2 7   ' );
$m->define_scale('t2', '', ' 2 3 4 7 ' );
$m->define_scale('t3', '', ' 4 5 6  7 ' );

$m->show_all() if $DEBUG;

my $i = 0;

my @TUNING;

# let user give a predefined tuning name, or specify their own or use the default.
if ( $TUNING )
{
	@TUNING = (  $m->get_tuning($TUNING) ? @{$m->get_tuning($TUNING)} :  split(/,/, $TUNING) );
}
else 
{
	@TUNING = @{$m->get_tuning('standard')};
}

@TUNING = ( $LEFTIE ? reverse @TUNING : @TUNING ); # invert string order for left-handed

for ( @TUNING )
{
	my @notes =  $m->notes($_);
	unshift @STRINGS, [ @notes, @notes, $notes[0] ];
}

my (%outstuff, @outkeys);

for my $scale ( @SCALES )
{
	my ( $key, $tone, $subtype ) = split(/,/, $scale);

	my @notes;
	@notes = $m->scale($key, $tone, $subtype);
	my $outkey = "$key $tone $subtype";
	push @outkeys, $outkey;
	$outstuff{$outkey}{strings} = [];

	my %notes;

	my $i = 0;
	for ( @notes)  { $notes{$_} = ++$i }

	$outstuff{$outkey}{notes} = { %notes };
}

my @frets = ( 'O', 1,'',3,'',5,'',7,'',9,'','',12,13,'',15,'',17,'',19,'',21,'','',24 );
@frets = map { $_ . ( ' ' x (2 - length($_)) ) } @frets;


if ( $LIST_CHORDS )
{
	print "$_\n" for $m->do_list_scales;
}

print_tunings() if $LIST_TUNINGS;

for my $outkey (@outkeys)
{
	my %notes = %{ $outstuff{$outkey}{notes} };
	print_scale(\%notes, \@STRINGS, $outkey);
	
}

if ( $COMPARE )
{
	my (%notes_diff, );
	my %same_notes = %{ dclone($outstuff{$outkeys[0]}{notes}) };

	# notes common to all scales/keys given - good for any number of scales/keys
	for my $key_out ( @outkeys )
	{
		for (keys %same_notes) 
		{
			delete $same_notes{$_} unless exists  $outstuff{$key_out}{notes}{$_};
		}
	}

	# for each key given,  build a list of the notes contained in all the other keys
	my @all_others;
	my $len_outkeys = $#outkeys;
	for  my $key_out ( 0..$len_outkeys )
	{
		$all_others[$key_out] ={};
		my @indices = map { $_ % scalar(@outkeys) } ( ($key_out+1)..($key_out + ($len_outkeys ) )  );
		
		for my $this ( @indices )
		{
			my %tmp_hr =  map { $_ }  %{ $outstuff{$outkeys[$this]}{notes} }  ;
			$all_others[$key_out] =  { ( %tmp_hr, %{$all_others[$key_out]} )  };
		}
	}

	# using the lists of the notes contained in all the other keys,
	# list the notes that are unique to each key
	my @diff_notes;
	for my $this ( 0..$len_outkeys )
	{
		my %scale = %{ $outstuff{$outkeys[$this]}{notes} };
		
		for ( keys %scale ) { delete $scale{$_} if exists $all_others[$this]->{$_}; }

		$diff_notes[$this] = { %scale };
	}

	# use the lists of  notes that are unique to each key
	# to assign a number to each note for which key it's in 
	# the number comes from the order in which the user listed the scales/chords
	my $i = 1;
	for  ( @diff_notes )
	{
		for ( keys %$_ ) { $notes_diff{$_} = $i; }

		$i++;
	}

	# if numeric output requested, then also add in the notes
	# common to all scales/chords denoted by '0'
	if ($NUMERIC) { for ( keys %same_notes ) { $notes_diff{$_} = 0 }; }

	if ( $DEBUG )
	{
		print STDERR doc_it( \%outstuff, '%outstuff', \@outkeys, '@outkeys', \@STRINGS, '@STRINGS', );
		print STDERR doc_it( \%notes_diff, '%notes_diff', \@diff_notes, '@diff_notes', );
		print STDERR doc_it( \%same_notes, '%same_notes', \@all_others, '@all_others', );
	}

	my $s;
	if ( $NUMERIC )
	{
		$s = "
		notes that are different between @outkeys
		'0' denotes notes that are in all of @outkeys
		";
		my $i = 1;
		for ( @outkeys )
		{
			$s .= "'$i' shows notes only in $_\n";
			$i++;
		}
	}
	else
	{
		$s = "notes that are different between @outkeys";	
	}
	$s =~s/^\s+//mg;
	print_scale( \%notes_diff, \@STRINGS, $s );
	
	if ( $NUMERIC )
	{
		$s = "
		Numbers are for note position in $outkeys[0]
		notes that are in all of: @outkeys";	
	}
	else
	{
		$s = "notes that are in all of: @outkeys";	
	}
	$s =~s/^\s+//mg;
	print_scale( \%same_notes, \@STRINGS, $s);
}

sub print_scale
{
	my %notes = %{ shift() }; 
	my @STRINGS = @{ shift() }; 
	my $outkey = shift(); 
	print "$outkey\n";
	for ( @STRINGS )
	{
		my @save = ();
		@save = map { ( exists $notes{$_} ? $_ : '-' ) } 			@$_ unless $NUMERIC;
		@save = map { ( exists $notes{$_} ? $notes{$_} : '-' ) } 	@$_ if $NUMERIC;
		@save = map { ( exists $notes{$_} ? 'm' : '-' ) } 			@$_ if $MARKER;
		@save = map { $_ . ( ' ' x (2 - length($_)) ) } @save;
		print "@save\n";
	}
	print "@frets\n\n";
}

sub print_tunings
{
	print "\nAvailable pre-defiend tunings are:\n";
	my ($len, @out) = (0, ());
	my %h = %{$m->get_all_tunings()};
	for ( keys %h )
	{
		$len = ( length($_) > $len ? length($_) : $len );
		push @out, [ $_, $h{$_} ];
	}
	# print Dumper(\@out);
	for ( keys %h )
	{
		my $spacer = ' ' x (($len + 2) - length($_));
		print "$_ $spacer @{$h{$_}} \n";
	}
	print "\n";
}


sub doc_it
{
	my $ret = '';
	while ( @_ )
	{
		my ($ref, $name) = ( shift, shift);
		my $s = Dumper($ref);
		$s =~ s/\$VAR1 =/$name =/;
		$ret .= "$s\n";
	}
	return $ret;
}
	
		
		
__END__

#
# $Log: music.pl,v $
# Revision 1.2  2002-09-10 21:47:05-05  bobn
# whatever
#
# Revision 1.1  2002-09-05 21:28:11-05  bobn
# Initial revision
#
#
#


running this program as:

./music.tst.pl -s c,major, -s d,major,  -d d,major, -c

produces these structures:

%outstuff = {
          'c major ' => {
                          'notes' => {
                                       'a' => 6,
                                       'b' => 7,
                                       'c' => 1,
                                       'd' => 2,
                                       'e' => 3,
                                       'f' => 4,
                                       'g' => 5
                                     },
                          'strings' => []
                        },
          'd major ' => {
                          'notes' => {
                                       'f#' => 3,
                                       'a' => 5,
                                       'b' => 6,
                                       'd' => 1,
                                       'e' => 2,
                                       'c#' => 7,
                                       'g' => 4
                                     },
                          'strings' => []
                        }
        };

@outkeys = [
          'c major ',
          'd major '
        ];

@STRINGS = [
          [
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e'
          ],
          [
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b'
          ],
          [
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g'
          ],
          [
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd'
          ],
          [
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a'
          ],
          [
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e'
          ]
        ];

%notes_diff = {
          'f#' => 2,
          'c' => 1,
          'c#' => 2,
          'f' => 1
        };

@diff_notes = [
          {
            'c' => 1,
            'f' => 4
          },
          {
            'f#' => 3,
            'c#' => 7
          }
        ];

%same_notes = {
          'a' => 6,
          'b' => 7,
          'd' => 2,
          'e' => 3,
          'g' => 5
        };

@all_others = [
          {
            'f#' => 3,
            'a' => 5,
            'b' => 6,
            'd' => 1,
            'e' => 2,
            'c#' => 7,
            'g' => 4
          },
          {
            'a' => 6,
            'b' => 7,
            'c' => 1,
            'd' => 2,
            'e' => 3,
            'f' => 4,
            'g' => 5
          }
        ];

%scales = (
            't1' => {
                      '' => [
                              '0',
                              1,
                              2,
                              7
                            ]
                    },
            'wholetone' => {
                             '' => [
                                     '0',
                                     2,
                                     4,
                                     6,
                                     8,
                                     10
                                   ]
                           },
            'minor' => {
                         'seventhC' => [
                                         '0',
                                         3,
                                         7,
                                         10
                                       ],
                         '' => [
                                 '0',
                                 2,
                                 3,
                                 5,
                                 7,
                                 8,
                                 10
                               ],
                         'harmonic' => [
                                         '0',
                                         2,
                                         3,
                                         5,
                                         7,
                                         8,
                                         11
                                       ],
                         'diatonic' => [
                                         '0',
                                         2,
                                         3,
                                         5,
                                         7,
                                         8,
                                         10
                                       ],
                         'pentatonic' => [
                                           '0',
                                           3,
                                           5,
                                           7,
                                           10
                                         ],
                         '7thC' => [
                                     '0',
                                     3,
                                     7,
                                     10
                                   ]
                       },
            't2' => {
                      '' => [
                              2,
                              3,
                              4,
                              7
                            ]
                    },
            't3' => {
                      '' => [
                              4,
                              5,
                              6,
                              7
                            ]
                    },
            'all' => {
                       '' => [
                               '0',
                               1,
                               2,
                               3,
                               4,
                               5,
                               6,
                               7,
                               8,
                               9,
                               10,
                               11
                             ]
                     },
            'major' => {
                         '' => [
                                 '0',
                                 2,
                                 4,
                                 5,
                                 7,
                                 9,
                                 11
                               ],
                         'seventhC' => [
                                         '0',
                                         4,
                                         7,
                                         11
                                       ],
                         'diatonic' => [
                                         '0',
                                         2,
                                         4,
                                         5,
                                         7,
                                         9,
                                         11
                                       ],
                         'pentatonic' => [
                                           '0',
                                           2,
                                           4,
                                           7,
                                           9
                                         ],
                         '7thC' => [
                                     '0',
                                     4,
                                     7,
                                     11
                                   ]
                       },
            'dominant' => {
                            '9thC' => [
                                        '0',
                                        4,
                                        7,
                                        10,
                                        14
                                      ],
                            'seventhC' => [
                                            '0',
                                            4,
                                            7,
                                            10
                                          ],
                            'ninethC' => [
                                           '0',
                                           4,
                                           7,
                                           10,
                                           14
                                         ],
                            'thirteenthC' => [
                                               '0',
                                               4,
                                               7,
                                               10,
                                               21
                                             ],
                            '13thC' => [
                                         '0',
                                         4,
                                         7,
                                         10,
                                         21
                                       ],
                            '7thC' => [
                                        '0',
                                        4,
                                        7,
                                        10
                                      ]
                          },
            'diminished' => {
                              '' => [
                                      '0',
                                      2,
                                      3,
                                      5,
                                      6,
                                      8,
                                      9,
                                      11
                                    ]
                            },
            'mixolydian' => {
                              '' => [
                                      '0',
                                      2,
                                      4,
                                      5,
                                      7,
                                      9,
                                      10
                                    ]
                            }
          );
%note_number = (
                 'V+' => 8,
                 'II' => 2,
                 'ii' => 1,
                 'V' => 7,
                 'v' => 6,
                 'VII' => 11,
                 'vii' => 10,
                 'I' => '0',
                 'IV+' => 6,
                 'iii' => 3,
                 'III' => 4,
                 'VI' => 9,
                 'vi' => 8,
                 'IV' => 5
               );


And produces this output:

c major 
e  f  -  g  -  a  -  b  c  -  d  -  e  f  -  g  -  a  -  b  c  -  d  -  e 
b  c  -  d  -  e  f  -  g  -  a  -  b  c  -  d  -  e  f  -  g  -  a  -  b 
g  -  a  -  b  c  -  d  -  e  f  -  g  -  a  -  b  c  -  d  -  e  f  -  g 
d  -  e  f  -  g  -  a  -  b  c  -  d  -  e  f  -  g  -  a  -  b  c  -  d 
a  -  b  c  -  d  -  e  f  -  g  -  a  -  b  c  -  d  -  e  f  -  g  -  a 
e  f  -  g  -  a  -  b  c  -  d  -  e  f  -  g  -  a  -  b  c  -  d  -  e 
O  1     3     5     7     9        12 13    15    17    19    21       24

d major 
e  -  f# g  -  a  -  b  -  c# d  -  e  -  f# g  -  a  -  b  -  c# d  -  e 
b  -  c# d  -  e  -  f# g  -  a  -  b  -  c# d  -  e  -  f# g  -  a  -  b 
g  -  a  -  b  -  c# d  -  e  -  f# g  -  a  -  b  -  c# d  -  e  -  f# g 
d  -  e  -  f# g  -  a  -  b  -  c# d  -  e  -  f# g  -  a  -  b  -  c# d 
a  -  b  -  c# d  -  e  -  f# g  -  a  -  b  -  c# d  -  e  -  f# g  -  a 
e  -  f# g  -  a  -  b  -  c# d  -  e  -  f# g  -  a  -  b  -  c# d  -  e 
O  1     3     5     7     9        12 13    15    17    19    21       24

notes that are different between c major  d major 
-  f  f# -  -  -  -  -  c  c# -  -  -  f  f# -  -  -  -  -  c  c# -  -  - 
-  c  c# -  -  -  f  f# -  -  -  -  -  c  c# -  -  -  f  f# -  -  -  -  - 
-  -  -  -  -  c  c# -  -  -  f  f# -  -  -  -  -  c  c# -  -  -  f  f# - 
-  -  -  f  f# -  -  -  -  -  c  c# -  -  -  f  f# -  -  -  -  -  c  c# - 
-  -  -  c  c# -  -  -  f  f# -  -  -  -  -  c  c# -  -  -  f  f# -  -  - 
-  f  f# -  -  -  -  -  c  c# -  -  -  f  f# -  -  -  -  -  c  c# -  -  - 
O  1     3     5     7     9        12 13    15    17    19    21       24

notes that are in all of: c major  d major 
e  -  -  g  -  a  -  b  -  -  d  -  e  -  -  g  -  a  -  b  -  -  d  -  e 
b  -  -  d  -  e  -  -  g  -  a  -  b  -  -  d  -  e  -  -  g  -  a  -  b 
g  -  a  -  b  -  -  d  -  e  -  -  g  -  a  -  b  -  -  d  -  e  -  -  g 
d  -  e  -  -  g  -  a  -  b  -  -  d  -  e  -  -  g  -  a  -  b  -  -  d 
a  -  b  -  -  d  -  e  -  -  g  -  a  -  b  -  -  d  -  e  -  -  g  -  a 
e  -  -  g  -  a  -  b  -  -  d  -  e  -  -  g  -  a  -  b  -  -  d  -  e 
O  1     3     5     7     9        12 13    15    17    19    21       24


Running this program as:

./music.tst.pl -s c,major, -s d,major, -c -n

produces these structures:


%outstuff = {
          'c major ' => {
                          'notes' => {
                                       'a' => 6,
                                       'b' => 7,
                                       'c' => 1,
                                       'd' => 2,
                                       'e' => 3,
                                       'f' => 4,
                                       'g' => 5
                                     },
                          'strings' => []
                        },
          'd major ' => {
                          'notes' => {
                                       'f#' => 3,
                                       'a' => 5,
                                       'b' => 6,
                                       'd' => 1,
                                       'e' => 2,
                                       'c#' => 7,
                                       'g' => 4
                                     },
                          'strings' => []
                        }
        };

@outkeys = [
          'c major ',
          'd major '
        ];

@STRINGS = [
          [
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e'
          ],
          [
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b'
          ],
          [
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g'
          ],
          [
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd'
          ],
          [
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a'
          ],
          [
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e',
            'f',
            'f#',
            'g',
            'g#',
            'a',
            'a#',
            'b',
            'c',
            'c#',
            'd',
            'd#',
            'e'
          ]
        ];

%notes_diff = {
          'a' => '0',
          'b' => '0',
          'c' => 1,
          'd' => '0',
          'e' => '0',
          'c#' => 2,
          'f' => 1,
          'g' => '0',
          'f#' => 2
        };

@diff_notes = [
          {
            'c' => 1,
            'f' => 4
          },
          {
            'f#' => 3,
            'c#' => 7
          }
        ];

%same_notes = {
          'a' => 6,
          'b' => 7,
          'd' => 2,
          'e' => 3,
          'g' => 5
        };

@all_others = [
          {
            'f#' => 3,
            'a' => 5,
            'b' => 6,
            'd' => 1,
            'e' => 2,
            'c#' => 7,
            'g' => 4
          },
          {
            'a' => 6,
            'b' => 7,
            'c' => 1,
            'd' => 2,
            'e' => 3,
            'f' => 4,
            'g' => 5
          }
        ];

%scales = (
            't1' => {
                      '' => [
                              '0',
                              1,
                              2,
                              7
                            ]
                    },
            'wholetone' => {
                             '' => [
                                     '0',
                                     2,
                                     4,
                                     6,
                                     8,
                                     10
                                   ]
                           },
            'minor' => {
                         'seventhC' => [
                                         '0',
                                         3,
                                         7,
                                         10
                                       ],
                         '' => [
                                 '0',
                                 2,
                                 3,
                                 5,
                                 7,
                                 8,
                                 10
                               ],
                         'harmonic' => [
                                         '0',
                                         2,
                                         3,
                                         5,
                                         7,
                                         8,
                                         11
                                       ],
                         'diatonic' => [
                                         '0',
                                         2,
                                         3,
                                         5,
                                         7,
                                         8,
                                         10
                                       ],
                         'pentatonic' => [
                                           '0',
                                           3,
                                           5,
                                           7,
                                           10
                                         ],
                         '7thC' => [
                                     '0',
                                     3,
                                     7,
                                     10
                                   ]
                       },
            't2' => {
                      '' => [
                              2,
                              3,
                              4,
                              7
                            ]
                    },
            't3' => {
                      '' => [
                              4,
                              5,
                              6,
                              7
                            ]
                    },
            'all' => {
                       '' => [
                               '0',
                               1,
                               2,
                               3,
                               4,
                               5,
                               6,
                               7,
                               8,
                               9,
                               10,
                               11
                             ]
                     },
            'major' => {
                         '' => [
                                 '0',
                                 2,
                                 4,
                                 5,
                                 7,
                                 9,
                                 11
                               ],
                         'seventhC' => [
                                         '0',
                                         4,
                                         7,
                                         11
                                       ],
                         'diatonic' => [
                                         '0',
                                         2,
                                         4,
                                         5,
                                         7,
                                         9,
                                         11
                                       ],
                         'pentatonic' => [
                                           '0',
                                           2,
                                           4,
                                           7,
                                           9
                                         ],
                         '7thC' => [
                                     '0',
                                     4,
                                     7,
                                     11
                                   ]
                       },
            'dominant' => {
                            '9thC' => [
                                        '0',
                                        4,
                                        7,
                                        10,
                                        14
                                      ],
                            'seventhC' => [
                                            '0',
                                            4,
                                            7,
                                            10
                                          ],
                            'ninethC' => [
                                           '0',
                                           4,
                                           7,
                                           10,
                                           14
                                         ],
                            'thirteenthC' => [
                                               '0',
                                               4,
                                               7,
                                               10,
                                               21
                                             ],
                            '13thC' => [
                                         '0',
                                         4,
                                         7,
                                         10,
                                         21
                                       ],
                            '7thC' => [
                                        '0',
                                        4,
                                        7,
                                        10
                                      ]
                          },
            'diminished' => {
                              '' => [
                                      '0',
                                      2,
                                      3,
                                      5,
                                      6,
                                      8,
                                      9,
                                      11
                                    ]
                            },
            'mixolydian' => {
                              '' => [
                                      '0',
                                      2,
                                      4,
                                      5,
                                      7,
                                      9,
                                      10
                                    ]
                            }
          );
%note_number = (
                 'V+' => 8,
                 'II' => 2,
                 'ii' => 1,
                 'V' => 7,
                 'v' => 6,
                 'VII' => 11,
                 'vii' => 10,
                 'I' => '0',
                 'IV+' => 6,
                 'iii' => 3,
                 'III' => 4,
                 'VI' => 9,
                 'vi' => 8,
                 'IV' => 5
               );



and this output:

c major 
3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3 
7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7 
5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5 
2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2 
6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6 
3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3 
O  1     3     5     7     9        12 13    15    17    19    21       24

d major 
2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2 
6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6 
4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4 
1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1 
5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5 
2  -  3  4  -  5  -  6  -  7  1  -  2  -  3  4  -  5  -  6  -  7  1  -  2 
O  1     3     5     7     9        12 13    15    17    19    21       24

notes that are different between c major  d major 
'0' denotes notes that are in all of c major  d major 
'1' shows notes only in c major 
'2' shows notes only in d major 

0  1  2  0  -  0  -  0  1  2  0  -  0  1  2  0  -  0  -  0  1  2  0  -  0 
0  1  2  0  -  0  1  2  0  -  0  -  0  1  2  0  -  0  1  2  0  -  0  -  0 
0  -  0  -  0  1  2  0  -  0  1  2  0  -  0  -  0  1  2  0  -  0  1  2  0 
0  -  0  1  2  0  -  0  -  0  1  2  0  -  0  1  2  0  -  0  -  0  1  2  0 
0  -  0  1  2  0  -  0  1  2  0  -  0  -  0  1  2  0  -  0  1  2  0  -  0 
0  1  2  0  -  0  -  0  1  2  0  -  0  1  2  0  -  0  -  0  1  2  0  -  0 
O  1     3     5     7     9        12 13    15    17    19    21       24

Numbers are for note position in c major 
notes that are in all of: c major  d major 
3  -  -  5  -  6  -  7  -  -  2  -  3  -  -  5  -  6  -  7  -  -  2  -  3 
7  -  -  2  -  3  -  -  5  -  6  -  7  -  -  2  -  3  -  -  5  -  6  -  7 
5  -  6  -  7  -  -  2  -  3  -  -  5  -  6  -  7  -  -  2  -  3  -  -  5 
2  -  3  -  -  5  -  6  -  7  -  -  2  -  3  -  -  5  -  6  -  7  -  -  2 
6  -  7  -  -  2  -  3  -  -  5  -  6  -  7  -  -  2  -  3  -  -  5  -  6 
3  -  -  5  -  6  -  7  -  -  2  -  3  -  -  5  -  6  -  7  -  -  2  -  3 
O  1     3     5     7     9        12 13    15    17    19    21       24

