@ 2014-09-03T23:00:04Z <?php
$mt = new music_theory();
var_dump($mt->get_scale_by_name("C"));
/*************************************************************
* This script is developed by Arturs Sosins aka ar2rsawseen, http://webcodingeasy.com
* Fee free to distribute and modify code, but keep reference to its creator
*
* This class implements music theory for generating scales and chords
* based on interval patterns between notes. User can add custom scale and chord pattern.
* This class can generate scale notes based on provided scale name and type,
* generate chord notes based on provided chord name and type,
* transpose scales, transpose chords,
* generate all chords that include provided notes,
* generate all scales that include provided notes,
*
* For more information, examples and online documentation visit:
* http://webcodingeasy.com/PHP-classes/Implement-music-theory-to-generate-scale-and-chord-notes
**************************************************************/
class music_theory
{
//use sharps or flats
private $alt = "sharp";
//array with sharp and flat type notes
private $note = array(
"sharp" => array("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"),
"flat" => array("C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B")
);
//array with scale patterns
private $scales = array(
"major" => array(2,2,1,2,2,2,1),
"ionian" => array(2,2,1,2,2,2,1),
"minor" => array(2,1,2,2,1,2,2),
"aeolian" => array(2,1,2,2,1,2,2),
"dorian" => array(2,1,2,2,2,1,2),
"phrygian" => array(1,2,2,2,1,2,2),
"lydian" => array(2,2,2,1,2,2,1),
"mixolydian" => array(2,2,1,2,2,1,2),
"locrian" => array(1,2,2,1,2,2,2),
"melodic minor asc" => array(2,1,2,2,2,2,1),
"melodic minor desc" => array(2,1,2,2,1,2,2),
"chromatic" => array(1,1,1,1,1,1,1,1,1,1,1,1),
"pentatonic major" => array(2,2,3,2,3),
"whole tone" => array(2,2,2,2,2,2),
"pentatonic minor" => array(3,2,2,3,2),
"pentatonic blues" => array(3,2,1,1,3),
"pentatonic neutral" => array(2,3,2,3,2),
"lydian augmented" => array(2,2,2,2,1,2,1),
"lydian minor" => array(2,2,2,1,1,2,2),
"lydian diminished" => array(2,1,3,1,2,2,1),
"major blues" => array(2,1,1,3,2,3),
"dominant pentatonic" => array(2,2,3,3,2),
"blues" => array(3,2,1,1,3,2)
);
private $chords = array(
"major" => array(4,3),
"minor" => array(3,4),
"5" => array(7),
"aug" => array(4,4),
"dim" => array(3,3),
"7" => array(4,3,3),
"sus4" => array(5,2),
"sus2" => array(2,5),
"7sus4" => array(5,2,3),
"6" => array(4,3,2),
"maj7" => array(4,3,4),
"9" => array(4,3,3,4),
"add9" => array(4,3,7),
"m6" => array(3,4,2),
"m7" => array(3,4,3),
"mmaj7" => array(3,4,4),
"m9" => array(3,4,3,4),
"11" => array(4,3,3,4,3),
"13" => array(4,3,3,4,3,4),
"6add9" => array(4,3,2,5),
"-5" => array(4,2),
"7-5" => array(4,2,4),
"7maj5" => array(4,4,2),
"maj9" => array(4,3,4,3)
);
private $errors = array();
//return array with all notes
public function get_notes(){
return $this->note[$this->alt];
}
//use flat notation
public function set_flat(){
$this->alt = "flat";
}
//use sharp notation
public function set_sharp(){
$this->alt = "sharp";
}
//return array with all defined scale types
public function get_scale_types(){
return array_keys($this->scales);
}
//return array with all defined chord types
public function get_chord_types(){
return array_keys($this->chords);
}
//return all errors and empty error array
public function get_errors(){
$arr = $this->errors;
$this->errors = array();
return $arr;
}
//check if all notes are in array
private function is_in($notes, $arr)
{
$is_in = true;
foreach($notes as $note)
{
if(!in_array(ucfirst(strtolower($note)), $arr))
{
$is_in = false;
}
}
return $is_in;
}
/**
* add new scale type with interval pattern
* Example input:
* $type = "ionian"; //new scale type name
* $pattern_array = array(2,2,1,2,2,2,1); //interval pattern
**/
public function add_scale_type($type, $pattern_array){
$type = strtolower($type);
if(!in_array($type, array_keys($this->scales)))
{
$this->scales[$type] = $pattern_array;
}
else
{
$this->errors[] = "Scale type name already used";
return false;
}
}
/**
* add new chord type with interval pattern
* Example input:
* $type = "major"; //new chord type name
* $pattern_array = array(4,3); //interval pattern
**/
public function add_chord_type($type, $pattern_array){
$type = strtolower($type);
if(!in_array($type, array_keys($this->chords)))
{
$this->chords[$type] = $pattern_array;
}
else
{
$this->errors[] = "Chord type name already used";
return false;
}
}
/**
* Get scale notes by name and type (optional transpose)
* Example input:
* $name = "C"; //scale name
* $type = "ionian"; //scale type
* $transpose = -1 //intervals to transpose to (default value 0 doesn't transpose), negative number tranposes down, positive - up
* Example output:
* Array
* (
* [0] => B
* [1] => C#
* [2] => D#
* [3] => E
* [4] => F#
* [5] => G#
* [6] => A#
* [7] => B
* )
**/
public function get_scale_by_name($name, $type, $transpose = 0){
$name = strtolower($name);
$name = ucfirst($name);
$type = strtolower($type);
if(!in_array($name, $this->note['sharp']))
{
if(!in_array($name, $this->note['flat']))
{
$this->errors[] = "Invalid scale name";
return array();
}
else
{
$notes = $this->note["flat"];
}
}
else
{
$notes = $this->note["sharp"];
}
if(!in_array($type, array_keys($this->scales)))
{
$this->errors[] = "Invalid scale type";
return array();
}
$scale = array();
$start = array_keys($notes, $name);
$note_sum = sizeof($notes)-1;
if($start[0] + $transpose < 0)
{
$current = ($start[0] + $transpose) + $note_sum + 1;
}
else if($start[0] + $transpose > $note_sum)
{
$current = (($start[0] + $transpose) - $note_sum) -1;
}
else
{
$current = $start[0] + $transpose;
}
$scale[] = $this->note[$this->alt][$current];
foreach($this->scales[$type] as $num)
{
$current += $num;
if($current > $note_sum)
{
$current -= ($note_sum + 1);
}
$scale[] = $this->note[$this->alt][$current];
}
return $scale;
}
/**
* Get chord notes by name and type (optional transpose)
* Example input:
* $name = "C"; //chord name
* $type = "major"; //chord type
* $transpose = 2 //intervals to transpose to (default value 0 doesn't transpose), negative number tranposes down, positive - up
* Example output:
* Array
* (
* [0] => D
* [3] => F#
* [5] => A
* )
*/
public function get_chord_by_name($name, $type, $transpose = 0){
$name = strtolower($name);
$name = ucfirst($name);
$type = strtolower($type);
if(!in_array($name, $this->note['sharp']))
{
if(!in_array($name, $this->note['flat']))
{
$this->errors[] = "Invalid chord name";
return array();
}
else
{
$notes = $this->note["flat"];
}
}
else
{
$notes = $this->note["sharp"];
}
if(!in_array($type, array_keys($this->chords)))
{
$this->errors[] = "Invalid chord type";
return array();
}
$chord = array();
$start = array_keys($notes, $name);
$note_sum = sizeof($notes)-1;
if($start[0] + $transpose < 0)
{
$current = ($start[0] + $transpose) + $note_sum + 1;
}
else if($start[0] + $transpose > $note_sum)
{
$current = (($start[0] + $transpose) - $note_sum) -1;
}
else
{
$current = $start[0] + $transpose;
}
$chord[] = $this->note[$this->alt][$current];
foreach($this->chords[$type] as $num)
{
$current += $num;
if($current > $note_sum)
{
$current -= ($note_sum + 1);
}
$chord[] = $this->note[$this->alt][$current];
}
return $chord;
}
/**
* Get chord names and types by notes
* Example input:
* $notes = array("A","F","C", "E"); //notes
* Example output:
* Array
* (
* [0] => Array
* (
* [name] => C
* [type] => 13
* )
*
* [1] => Array
* (
* [name] => D
* [type] => m9
* )
* ...
* )
*/
public function get_chords_by_notes($notes){
if(!is_array($notes))
{
$notes = array($notes);
}
$possible = array();
$chords = $this->get_chord_types();
for($i = 0; $i < 12; $i++)
{
foreach($chords as $chord)
{
$temp = $this->get_chord_by_name("C", $chord, $i);
if($this->is_in($notes, $temp))
{
$count = sizeof($possible);
$possible[$count]["name"] = current($temp);
$possible[$count]["type"] = $chord;
}
}
}
return $possible;
}
/**
* Get scale names and types by notes
* Example input:
* $notes = array("C","D","E","G#","C#"); //notes
* Example output:
* Array
* (
* [0] => Array
* (
* [name] => C
* [type] => chromatic
* )
*
* [1] => Array
* (
* [name] => C#
* [type] => chromatic
* )
* ...
* )
*/
public function get_scales_by_notes($notes){
if(!is_array($notes))
{
$notes = array($notes);
}
$possible = array();
$scales = $this->get_scale_types();
for($i = 0; $i < 12; $i++)
{
foreach($scales as $scale)
{
$temp = $this->get_scale_by_name("C", $scale, $i);
if($this->is_in($notes, $temp))
{
$count = sizeof($possible);
$possible[$count]["name"] = current($temp);
$possible[$count]["type"] = $scale;
}
}
}
return $possible;
}
/**
* Get scale names and types by chord names/types
* Provide different chord names with types,
* and receive array with all scale names/types which suits provided chords
*
* Example input:
* $chords = array(array("name" => "C", "type" => "major"), array("name" => "A", "type" => "minor")); //chord array
* Example output:
* Array
* (
* [0] => Array
* (
* [name] => C
* [type] => major
* )
*
* [1] => Array
* (
* [name] => C
* [type] => ionian
* )
* ...
* )
*/
public function get_scales_by_chords($chords){
$notes = array();
foreach($chords as $chord)
{
$chord_notes = $this->get_chord_by_name(ucfirst(strtolower($chord["name"])), $chord["type"]);
$notes = array_merge($notes, $chord_notes);
}
$notes = array_unique($notes);
$possible = array();
$scales = $this->get_scale_types();
for($i = 0; $i < 12; $i++)
{
foreach($scales as $scale)
{
$temp = $this->get_scale_by_name("C", $scale, $i);
if($this->is_in($notes, $temp))
{
$count = sizeof($possible);
$possible[$count]["name"] = current($temp);
$possible[$count]["type"] = $scale;
}
}
}
return $possible;
}
/**
* Get chord names and types by scale
* Provide scale name and type
* and receive all chord names/types which suits provided scale
*
* Example input:
* $scale_name = "C"; //scale name
* $scale_type = "ionian" //scale type
* Example output:
* Array
* (
* [0] => Array
* (
* [name] => C
* [type] => minor
* )
*
* [1] => Array
* (
* [name] => C
* [type] => 5
* )
* ...
* )
*/
public function get_chords_by_scale($scale_name, $scale_type){
$scale_notes = $this->get_scale_by_name(ucfirst(strtolower($scale_name)), strtolower($scale_type));
if(!empty($scale_notes))
{
$possible = array();
$chords = $this->get_chord_types();
for($i = 0; $i < 12; $i++)
{
foreach($chords as $chord)
{
$temp = $this->get_chord_by_name("C", $chord, $i);
if($this->is_in($temp, $scale_notes))
{
$count = sizeof($possible);
$possible[$count]["name"] = current($temp);
$possible[$count]["type"] = $chord;
}
}
}
return $possible;
}
}
}
?>
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 8.3.6 0.008 0.008 16.88 8.3.5 0.009 0.007 22.93 8.3.4 0.011 0.004 18.92 8.3.3 0.009 0.006 19.27 8.3.2 0.004 0.004 20.41 8.3.1 0.005 0.003 23.56 8.3.0 0.000 0.008 19.38 8.2.18 0.006 0.010 17.00 8.2.17 0.007 0.011 22.96 8.2.16 0.014 0.000 20.66 8.2.15 0.004 0.004 24.18 8.2.14 0.003 0.006 24.66 8.2.13 0.008 0.000 26.16 8.2.12 0.004 0.004 21.01 8.2.11 0.003 0.006 21.14 8.2.10 0.004 0.008 17.84 8.2.9 0.004 0.004 19.50 8.2.8 0.006 0.003 17.97 8.2.7 0.006 0.003 17.63 8.2.6 0.008 0.000 17.93 8.2.5 0.003 0.006 18.07 8.2.4 0.003 0.005 18.29 8.2.3 0.004 0.004 18.12 8.2.2 0.008 0.000 17.72 8.2.1 0.004 0.004 18.14 8.2.0 0.003 0.006 17.84 8.1.28 0.004 0.012 25.92 8.1.27 0.008 0.000 23.92 8.1.26 0.000 0.008 26.35 8.1.25 0.008 0.000 28.09 8.1.24 0.010 0.003 17.36 8.1.23 0.003 0.009 21.07 8.1.22 0.000 0.008 17.79 8.1.21 0.004 0.007 19.04 8.1.20 0.000 0.009 17.48 8.1.19 0.000 0.008 17.35 8.1.18 0.003 0.005 18.10 8.1.17 0.008 0.000 18.81 8.1.16 0.000 0.008 18.86 8.1.15 0.004 0.004 19.00 8.1.14 0.005 0.003 17.57 8.1.13 0.006 0.003 18.02 8.1.12 0.000 0.007 17.46 8.1.11 0.000 0.007 17.54 8.1.10 0.003 0.006 17.59 8.1.9 0.004 0.004 17.54 8.1.8 0.004 0.004 17.63 8.1.7 0.002 0.005 17.55 8.1.6 0.006 0.003 17.64 8.1.5 0.003 0.005 17.59 8.1.4 0.004 0.004 17.61 8.1.3 0.005 0.003 17.83 8.1.2 0.005 0.003 17.85 8.1.1 0.008 0.000 17.75 8.1.0 0.008 0.000 17.68 8.0.30 0.003 0.007 20.03 8.0.29 0.000 0.010 16.75 8.0.28 0.000 0.007 18.42 8.0.27 0.003 0.003 17.30 8.0.26 0.000 0.007 17.36 8.0.25 0.000 0.007 17.00 8.0.24 0.004 0.004 17.13 8.0.23 0.008 0.000 16.97 8.0.22 0.005 0.003 17.08 8.0.21 0.004 0.004 16.91 8.0.20 0.003 0.003 16.98 8.0.19 0.003 0.006 17.13 8.0.18 0.003 0.006 17.09 8.0.17 0.008 0.000 16.98 8.0.16 0.004 0.004 17.02 8.0.15 0.007 0.000 16.99 8.0.14 0.002 0.005 16.94 8.0.13 0.006 0.000 13.51 8.0.12 0.000 0.008 17.05 8.0.11 0.000 0.007 16.95 8.0.10 0.000 0.008 17.01 8.0.9 0.005 0.002 17.17 8.0.8 0.007 0.010 17.05 8.0.7 0.003 0.006 16.99 8.0.6 0.003 0.005 16.96 8.0.5 0.000 0.008 17.00 8.0.3 0.005 0.015 17.19 8.0.2 0.015 0.008 17.49 8.0.1 0.000 0.007 17.04 8.0.0 0.005 0.012 16.89 7.4.33 0.003 0.003 15.00 7.4.32 0.000 0.006 16.74 7.4.30 0.003 0.003 16.78 7.4.29 0.008 0.000 16.60 7.4.28 0.000 0.011 16.57 7.4.27 0.003 0.005 16.77 7.4.26 0.005 0.005 16.66 7.4.25 0.004 0.004 16.64 7.4.24 0.001 0.007 16.68 7.4.23 0.004 0.004 16.86 7.4.22 0.007 0.014 16.77 7.4.21 0.008 0.008 16.87 7.4.20 0.000 0.007 16.86 7.4.16 0.009 0.012 16.65 7.4.15 0.016 0.003 17.40 7.4.14 0.007 0.010 17.86 7.4.13 0.013 0.006 16.75 7.4.12 0.007 0.011 16.75 7.4.11 0.010 0.014 16.63 7.4.10 0.009 0.006 16.72 7.4.9 0.009 0.009 16.61 7.4.8 0.009 0.012 19.39 7.4.7 0.015 0.009 16.66 7.4.6 0.012 0.006 16.63 7.4.5 0.000 0.004 16.42 7.4.4 0.007 0.011 16.71 7.4.3 0.010 0.007 16.79 7.4.0 0.007 0.010 14.91 7.3.33 0.006 0.000 13.31 7.3.32 0.005 0.003 13.50 7.3.31 0.008 0.000 16.54 7.3.30 0.000 0.007 16.57 7.3.29 0.003 0.013 16.45 7.3.28 0.008 0.008 16.54 7.3.27 0.010 0.007 17.40 7.3.26 0.007 0.011 16.72 7.3.25 0.012 0.008 16.52 7.3.24 0.013 0.005 16.77 7.3.23 0.014 0.003 16.57 7.3.21 0.009 0.009 16.74 7.3.20 0.010 0.013 19.39 7.3.19 0.007 0.017 16.75 7.3.18 0.011 0.006 16.72 7.3.17 0.006 0.012 16.66 7.3.16 0.008 0.008 16.50 7.2.33 0.015 0.006 16.83 7.2.32 0.009 0.012 16.82 7.2.31 0.010 0.007 16.61 7.2.30 0.006 0.012 16.53 7.2.29 0.000 0.016 16.70 7.2.6 0.009 0.006 16.95 7.2.0 0.003 0.007 19.34 7.1.20 0.003 0.006 15.62 7.1.10 0.000 0.013 17.65 7.1.7 0.000 0.007 17.07 7.1.6 0.016 0.010 19.40 7.1.5 0.003 0.010 16.87 7.1.0 0.003 0.073 22.29 7.0.20 0.000 0.012 14.76 7.0.14 0.007 0.070 21.95 7.0.11 0.010 0.040 19.91 7.0.10 0.010 0.040 20.01 7.0.9 0.017 0.040 20.13 7.0.8 0.013 0.043 19.93 7.0.7 0.017 0.040 20.14 7.0.6 0.007 0.047 19.98 7.0.5 0.017 0.040 20.14 7.0.4 0.007 0.043 19.64 7.0.3 0.017 0.033 19.73 7.0.2 0.007 0.040 19.68 7.0.1 0.013 0.040 19.70 7.0.0 0.003 0.047 19.81 5.6.28 0.003 0.073 21.16 5.6.26 0.003 0.043 20.70 5.6.25 0.010 0.030 20.73 5.6.24 0.013 0.040 20.94 5.6.23 0.007 0.043 20.74 5.6.22 0.003 0.050 20.75 5.6.21 0.017 0.037 20.76 5.6.20 0.003 0.053 21.03 5.6.19 0.003 0.043 21.20 5.6.18 0.010 0.040 21.22 5.6.17 0.020 0.027 21.26 5.6.16 0.003 0.050 21.16 5.6.15 0.010 0.043 21.20 5.6.14 0.007 0.037 21.04 5.6.13 0.010 0.040 20.54 5.6.12 0.000 0.053 20.54 5.6.11 0.003 0.050 20.54 5.6.10 0.013 0.040 20.52 5.6.9 0.007 0.047 20.69 5.6.8 0.007 0.033 20.16 5.6.7 0.003 0.047 20.07 5.6.6 0.007 0.037 19.96 5.6.5 0.003 0.037 20.14 5.6.4 0.003 0.033 20.07 5.6.3 0.010 0.027 20.03 5.6.2 0.013 0.037 20.00 5.6.1 0.013 0.030 20.00 5.6.0 0.003 0.040 20.70 5.5.38 0.007 0.047 20.43 5.5.37 0.010 0.037 20.57 5.5.36 0.000 0.053 20.46 5.5.35 0.003 0.043 20.53 5.5.34 0.013 0.037 21.00 5.5.33 0.007 0.047 21.02 5.5.32 0.007 0.040 20.95 5.5.31 0.007 0.047 21.04 5.5.30 0.007 0.043 21.08 5.5.29 0.003 0.037 21.09 5.5.28 0.000 0.047 20.78 5.5.27 0.003 0.053 21.05 5.5.26 0.007 0.047 20.75 5.5.25 0.000 0.053 20.77 5.5.24 0.000 0.050 20.39 5.5.23 0.010 0.030 20.32 5.5.22 0.003 0.047 20.45 5.5.21 0.007 0.037 20.41 5.5.20 0.007 0.030 20.11 5.5.19 0.000 0.037 20.25 5.5.18 0.000 0.037 20.38 5.5.16 0.017 0.030 20.11 5.5.15 0.013 0.037 20.36 5.5.14 0.010 0.043 20.20 5.5.13 0.007 0.040 20.34 5.5.12 0.007 0.043 20.35 5.5.11 0.007 0.043 20.21 5.5.10 0.003 0.033 20.06 5.5.9 0.007 0.030 20.31 5.5.8 0.000 0.037 20.15 5.5.7 0.007 0.047 20.31 5.5.6 0.003 0.037 20.29 5.5.5 0.000 0.040 20.04 5.5.4 0.013 0.037 20.18 5.5.3 0.007 0.043 20.11 5.5.2 0.000 0.043 20.20 5.5.1 0.003 0.040 20.07 5.5.0 0.003 0.040 20.14 5.4.45 0.007 0.037 19.31 5.4.44 0.003 0.040 19.50 5.4.43 0.000 0.050 19.35 5.4.42 0.010 0.040 19.71 5.4.41 0.017 0.027 19.24 5.4.40 0.010 0.037 19.01 5.4.39 0.007 0.043 19.05 5.4.38 0.000 0.040 19.20 5.4.37 0.000 0.037 19.07 5.4.36 0.003 0.033 19.02 5.4.35 0.003 0.030 19.22 5.4.34 0.007 0.040 19.10 5.4.32 0.007 0.043 19.00 5.4.31 0.010 0.030 19.23 5.4.30 0.003 0.043 19.04 5.4.29 0.007 0.040 19.23 5.4.28 0.007 0.040 19.04 5.4.27 0.007 0.040 19.22 5.4.26 0.003 0.037 19.16 5.4.25 0.000 0.033 18.98 5.4.24 0.003 0.043 19.06 5.4.23 0.007 0.043 19.04 5.4.22 0.003 0.047 19.01 5.4.21 0.007 0.043 19.30 5.4.20 0.007 0.033 19.04 5.4.19 0.000 0.040 19.02 5.4.18 0.000 0.047 19.25 5.4.17 0.010 0.033 19.03 5.4.16 0.003 0.047 19.14 5.4.15 0.000 0.050 19.00 5.4.14 0.007 0.043 16.54 5.4.13 0.003 0.040 16.36 5.4.12 0.000 0.040 16.51 5.4.11 0.003 0.043 16.52 5.4.10 0.000 0.043 16.45 5.4.9 0.000 0.043 16.58 5.4.8 0.010 0.033 16.59 5.4.7 0.000 0.047 16.59 5.4.6 0.003 0.037 16.61 5.4.5 0.003 0.043 16.57 5.4.4 0.003 0.040 16.53 5.4.3 0.010 0.030 16.69 5.4.2 0.003 0.043 16.59 5.4.1 0.013 0.037 16.59 5.4.0 0.000 0.037 15.84
preferences:dark mode live preview
102.21 ms | 401 KiB | 5 Q