<?php
$sharp = array(1=>'C',2=>'C#',3=>'D',4=>'D#',5=>'E',6=>'F',7=>'F#',8=>'G',9=>'G#',10=>'A',11=>'A#',12=>'B',13=>'B#');
$flat = array(1=>'C',2=>'Db',3=>'D',4=>'Eb',5=>'E',6=>'F',7=>'Gb',8=>'G',9=>'Ab',10=>'A',11=>'Bb',12=>'B',13=>'Cb');
$equalKey = array('Cb'=>11,'C'=>0,'C#'=>1,'Db'=>1,'D'=>2,'D#'=>3,'Eb'=>3,'E'=>4,'E#'=>5,'Fb'=>4,'F'=>5,'F#'=>6,'Gb'=>6,'G'=>7,'G#'=>8,'Ab'=>8,'A'=>9,'A#'=>10,'Bb'=>10,'B'=>11,'B#'=>0);
$major = array(2,2,1,2,2,2);
function makeScale($scale,$interval,$pos) {
global $equalKey;
$keyFlag = null;
$stack = array();
$cmp = $scale[$pos][0];
//音階の先頭に主音を設定
$stack[]=$scale[$pos];
// 長音階のキーを取得していく
for($i=0;$i<6;$i++) {
$pos+=$interval[$i];
if ($pos>12) $pos-=12;
$stack[]=$scale[$pos];
}
// 補正処理
for($i=1;$i<7;$i++) {
$cmp = chr(ord($cmp)+1);
if ($cmp>'G') $cmp='A';
$esc=$stack[$i];
if ($stack[$i][0]>$cmp) $stack[$i]=$cmp.'#';
if ($stack[$i][0]<$cmp) $stack[$i]=$cmp.'b';
if ($equalKey[$stack[$i]]!=$equalKey[$esc]) return false;
}
for($i=0,$s=null;$i<7;$i++) $s .= $stack[$i]."→";
$s .= $stack[0];
return $s;
}
// 長音階 #系列
for($i=1;$i<13;$i++) {
if ($ret=makeScale($sharp,$major,$i)) {
if (!strpos($ret,'b')) echo $ret."
\n";
}
}
// 長音階 ♭系列
for($i=2;$i<13;$i++) {
if (!($ret=makeScale($flat,$major,$i))) {
if ($flat[$i]=='B') {
$flat2 = $flat; $flat2[$i]='Cb';
$ret = makeScale($flat2,$major,$i);
}
}
if (($ret)&&(!strpos($ret,'#'))) echo $ret."
\n";
}
?>