0

PHPで和音の移調を行おうとしていますが、和音の値の配列は次のとおりです...

$chords1 = array('C','C#','D','D#','E','F','F#','G','G#','A','A#','B','C','Db','D','Eb','E','F','Gb','G','Ab','A','Bb','B','C');

例はD6/F#です。配列値を一致させてから、配列内の特定の数値位置で転置したいと考えています。これが私がこれまでに持っているものです...

function splitChord($chord){ // The chord comes into the function
    preg_match_all("/C#|D#|F#|G#|A#|Db|Eb|Gb|Ab|Bb|C|D|E|F|G|A|B/", $chord, $notes); // match the item
    $notes = $notes[0];
    $newArray = array();
    foreach($notes as $note){ // for each found item as a note
        $note = switchNotes($note); // switch the not out
        array_push($newArray, $note); // and push it into the new array
    }
    $chord = str_replace($notes, $newArray, $chord); // then string replace the chord with the new notes available
    return($chord);
}
function switchNotes($note){
    $chords1 = array('C','C#','D','D#','E','F','F#','G','G#','A','A#','B','C','Db','D','Eb','E','F','Gb','G','Ab','A','Bb','B','C');

    $search = array_search($note, $chords1);////////////////Search the array position D=2 & F#=6
    $note = $chords1[$search + 4];///////////////////////then make the new position add 4 = F# and A#
    return($note);
}

これは機能しますが、 (D6/F#)のようなスプリット コードを使用すると、コードが A#6/A# に移調されるという問題を除いては機能します。最初の音符 (D) を (F#) に置き換え、次に両方の (F#) を (A#) に置き換えます。

問題は...どうすればこの冗長性が発生しないようにすることができますか? 望ましい出力はF#6/A#です。ご協力ありがとうございました。解決策が投稿された場​​合は、回答済みとしてマークします。

4

2 に答える 2

1

preg_replace_callback 関数を使用できます

function transposeNoteCallback($match) {
    $chords = array('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B', 'C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B', 'C');
    $pos = array_search($match[0], $chords) + 4;
    if ($pos >= count($chords)) {
        $pos = $pos - count($chords);
    }
    return $chords[$pos];
}

function transposeNote($noteStr) {
    return preg_replace_callback("/C#|D#|F#|G#|A#|Db|Eb|Gb|Ab|Bb|C|D|E|F|G|A|B/", 'transposeNoteCallback', $noteStr);
}

テスト

echo transposeNote("Eb6 Bb B Ab D6/F#");

戻り値

G6 C# Eb CF#6/A#

于 2012-09-29T18:35:11.117 に答える