#native_company# #native_desc#
#native_cta#

dynamic scale/chord generation

By Jake Hofman
on July 18, 2002

Version: 0.1

Type: Full Script

Category: Other

License: GNU General Public License

Description: this is a simple little script that generates scales/chords in a given key on the fly. maybe someone can use this to do something that’s a little more interesting – perhaps even useful.

<?php
//contact [email protected] for questions/comments

class Scale {
  var $notes;
  var $currIndex;
  var $currNote;
  var $scales;
  var $triads;

  function Scale() {
    $this->notes = array("C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B");
    $this->currIndex = 0;
    $this->currNote = $this->notes[0];

    $this->scales["major"] = array(2, 2, 1, 2, 2, 2, 1);
    $this->scales["major pentatonic"] = array(2, 2, 3, 2, 3);
    $this->scales["minor pentatonic"] = array(3, 2, 2, 3, 2);
    $this->scales["blues"] = array(3, 2, 1, 1, 3, 2);
    $this->scales["harmonic minor"] = array(2, 1, 2, 2, 1, 3, 1);

    $this->triads["major"] = array(0, 0, 0);
    $this->triads["minor"] = array(0, -1, 0);
    $this->triads["diminished"] = array(0, -1, -1);
    $this->triads["augmented"] = array(0, 0, 1);
  }

  function setCurrIndex ($newIndex) {
    $newIndex %= 12;
    
    $this->currIndex = $newIndex;
   }

  function getCurrIndex () {
    return $this->currIndex;
  }

  function halfStep($numSteps = 1) {
    $this->setCurrIndex($this->getCurrIndex() + $numSteps);
  }

  function getNoteIndex ($note) {
    $i = 0;

    $origIndex = $this->getCurrIndex();

    while($this->getCurrNote() != $note)
      $this->halfStep();

    $finalIndex = $this->getCurrIndex();

    $this->setCurrIndex($origIndex);

    return $finalIndex;
  }

  function getCurrNote () {
    return $this->notes[$this->currIndex];
  }

  function setCurrNote($note) {
    $this->setCurrIndex($this->getNoteIndex($note));
  }
  
  function getScale($key, $pattern) {
    $this->setCurrNote($key);
    $i = 0;

    $scale = array();
    do {
      array_push($scale, $this->getCurrNote());
      $this->halfStep($pattern[$i++]);
    } while($this->getCurrNote() != $key);
    

    return $scale;
  }

  function printScale($key, $scaleName) {
    $scale = $this->getScale($key, $this->scales[$scaleName]);

    echo join(" ", $scale);
  }

  function printTriads($key) {
    $scale = $this->getScale($key, $this->scales["major"]);
    
    echo "<table border=1>n";

    while(list($tkey, $triad) = each($this->triads)) {
    echo "<tr>";

    echo "<td><b>$tkey</b></td>";

    $first = $this->notes[$this->getNoteIndex($scale[0]) + $triad[0]];
        $second = $this->notes[$this->getNoteIndex($scale[2]) + $triad[1]];
        $third = $this->notes[$this->getNoteIndex($scale[4]) + $triad[2]];

    echo "<td>$first $second $third</td>";

    echo "</tr>";
   }

   echo "</table>n";
  }

  function getNotes() {
    //return join(", ", $this->notes);
    return $this->notes;
  }

  function getScales() {
    $scaleArr = array();

    while(list($key, $value) = each($this->scales)) {
      array_push($scaleArr, $key);
    }

    //return join(", ", $scaleArr);
    return $scaleArr;
  }
}

function buildSelectBox($name, $array) {
  echo "<select name=$name>n";

  foreach($array as $entry)
    echo "<option>$entryn";

  echo "</select>n";
}

function printScaleForm($myScale) {
  global $PHP_SELF;

  echo "<form action=$PHP_SELF method=get>n";

  buildSelectBox("key", $myScale->getNotes());
  buildSelectBox("scaleName", $myScale->getScales());

  echo "<br><input type=submit name=submit value=submit>n";
  echo "<input type=hidden name=hidden value=1>n";

  echo "</form>";
}

echo "<center>n";

$myScale = new Scale();

if(isset($hidden)) {
  echo "<b>$key $scaleName: </b>";
  $myScale->printScale($key, $scaleName);
  echo "<br><br>n";

  echo "<b>$key triads:</b><br>n";  
  $myScale->printTriads($key);

  echo "<br><br>n";
}

printScaleForm($myScale);

echo "</center>n";
?>