<?php
// produces the expected result
echo transpose("F#sus7/C#",3);
function transpose($chord,$transpose)
{
// the chords
$chords = array("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B");
$result = "";
// get root tone
$root_arr = explode("/",$chord);
$root = strtoupper($root_arr[0]);
// the chord is the first character and a # if there is one
$root = $root[0].((strpos($root, "#") !== false)?"#":"");
// get any extra info
$root_extra_info = str_replace("#","",substr($root_arr[0],1)); // assuming that extra info does not have any #
// find the index on chords array
$root_index = array_search($root,$chords);
// transpose the values and modulo by 12 so we always point to existing indexes in our array
$root_transpose_index = floor(($root_index + $transpose) % 12);
if ($root_transpose_index < 0)
{
$root_transpose_index += 12;
}
$result.= $chords[$root_transpose_index].$root_extra_info;
if(count($root_arr)>1)
{
// get the non root tone
$non_root = $root_arr[1];
// the chord is the first character and a # if there is one
$non_root = strtoupper($non_root[0]).((strpos($non_root, "#") !== false)?"#":"");
// get any extra info
$non_root_extra_info = str_replace("#","",substr($root_arr[1],1)); // assuming that extra info does not have any #
// find the index on chords array
$non_root_index = array_search($non_root,$chords);
// transpose the values and modulo by 12 so we always point to existing indexes in our array
$non_root_transpose_index = floor(($non_root_index + $transpose) % 12);
if ($non_root_transpose_index < 0)
{
$non_root_transpose_index += 12;
}
$result.= "/".$chords[$non_root_transpose_index].$non_root_extra_info;
}
return $result;
}