11

音楽のコードを移調するためのJavaScript関数をどのように作成するのだろうかと思っていました。

ここでは誰もがミュージシャンになるとは思っていないので、音楽理論でどのように機能するかを説明しようと思います。私は何かを忘れないことを願っています。はいの場合、ミュージシャン、訂正してください。

1)シンプルなコード

シンプルなコードはアルファベットとほぼ同じくらいシンプルで、次のようになります。

C、C#、D、D#、E、F、F#、G、G#、A、A#B

BからCに再びループします。したがって、元のコードがEであり、+ 1を転置したい場合、結果のコードはFです。+4を転置すると、結果のコードは。になりG#ます。

2)拡張されたコード

これらは単純なコードとほとんど同じように機能しますが、移調時に無視しても問題ない文字がいくつか含まれています。例えば:

Cmi、C#7、Dsus7、Emi、Fsus4、F#mi、G..。

繰り返しますが、単純なコードの場合と同様に、Dsus7+3=を転置するとFsus7

3)非ルートベーストーン

低音が和音のルート音とは異なる音を演奏する場合、問題が発生します。これはコードの後に​​スラッシュでマークされており、移調する必要もあります。例:

C / G、Dmi / A、F#sus7 / A#

例1と2と同様に、すべてが同じですが、スラッシュの後の部分も転置する必要があります。したがって、次のようになります。

C/G+ 5 =F/C

F#sus7/A#+ 1 =Gsus7/B

何か忘れない限り、これで全部だと思います。

したがって、基本的に、と呼ばれるjavascript変数とchord転置値があると想像してくださいtranspose。どのコードがコードを転置しますか?

例:

var chord = 'F#sus7/C#';
var transpose = 3; // remember this value also may be negative, like "-4"
... code here ...
var result; // expected result = 'Asus7/E';
4

8 に答える 8

12

このようなちょっとしたことはどうですか:

function transposeChord(chord, amount) {
  var scale = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
  return chord.replace(/[CDEFGAB]#?/g,
                       function(match) {
                         var i = (scale.indexOf(match) + amount) % scale.length;
                         return scale[ i < 0 ? i + scale.length : i ];
                       });
}

alert(transposeChord("Dm7/G", 2)); // gives "Em7/A"
alert(transposeChord("Fmaj9#11", -23)); // gives "F#maj9#11"

"F#maj9#11" の例を追加したのは、有効なコード名を構成する要素に関してさらに考えてもらうためであることに注意してください。この場合は "11" に属します)。

そして、明らかに、私の関数はフラットではなくシャープのみを理解し、キーを理解していないため、たとえば、transposeChord("C/E", 1)実際には「C#/E#」であるべきときに「C#/F」を返します。

于 2011-10-29T04:22:41.257 に答える
2
function transpose(chord, increment)
{
    var cycle = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
    var el = chord.charAt(0);
    if(chord.length > 1 && chord.charAt(1) == '#')
    {
        el += "#";   
    }
    var ind = cycle.indexOf(el);
    var newInd = (ind + increment + cycle.length) % cycle.length;
    var newChord = cycle[newInd];
    return newChord + chord.substring(el.length);
}

I'll let you figure out the bass part, since it's really just calling the function twice.

Also, you can add the code here before the function for old browsers that don't support indexOf.

I put a demo on jsFiddle.

EDIT: The issue was with negative modulus. The above will work as long as long as the negative isn't more than the length (e.g. you can't transpose 100 steps down).

于 2011-10-29T03:40:17.453 に答える
1

オブジェクトを使用してキーを定義します。

var keys = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"];

コードを正規表現で解析します。

var matches = /([A-G]#?)([^\/]*)(?:\/([A-G]#?))?/.exec(chord);
var key = matches[1];
var descriptor = matches[2];
var bass = matches[3];

少し計算して新しいキーを取得します。

var newKey = keys[(keys.indexOf(key) + transpose) % keys.length];
var newBass = keys[(keys.indexOf(bass) + transpose) % keys.length];

すべてを元に戻します。

var newChord = newKey + descriptor;
if (newBass) {
    newChord += "/" + newBass;
}
return newChord;
于 2011-10-29T03:56:18.637 に答える
0
function transposechord(chord, amount){
   var scale = ["C","Cb","C#","D","Db","D#","E","Eb","E#","F","Fb","F#","G","Gb","G#",
         "A","Ab","A#","B","Bb","B#"];
   var transp = ["Cb","C","C#","Bb","Cb","C","C","C#","D","Db","D","D#","C","Db","D",
                 "D","D#","E","Eb","E","F","D","Eb","E", "E","E#","F#", "E","F","F#",
                 "Eb","Fb","F","F","F#","G","Gb","G","G#","F","Gb","G", "G","G#","A", 
                 "Ab","A","A#","G","Ab","A","A","A#","B","Bb","B","C","A","Bb","B", 
                 "B","B#","C#"];
   var subst = chord.match(/[^b#][#b]?/g);
   for(var ax in subst){
      if(scale.indexOf(subst[ax])!==-1){
         if(amount>0){
            for(ix=0;ix<amount;ix++){
                var pos = scale.indexOf(subst[ax]);
                var transpos = 3*pos-2+3;
                subst[ax] = transp[transpos+1];
            }
         }
         if(amount<0){
            for(ix=0;ix>amount;ix--){
                var pos = scale.indexOf(subst[ax]);
                var transpos = 3*pos-2+3;
                subst[ax] = transp[transpos-1];
                }
            }
       } 
   }
   chord=subst.join("");
}

chord = C/B、amount = 1: C#/C または chord = Gm7、amount 2: Am7

于 2013-09-25T02:57:12.327 に答える
0

ギター/ウクレレのソング シートのコード ラインの移調が必要で、スペースが許せば間隔を維持し、7/dim/sus4 タイプの情報を再利用する次の関数を思い付きました。

    function transposeChord( chord, amount ) {
        const sharpnotes = ["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"];
        const flatnotes  = ["A","Bb","B","C","Db","D","Eb","E","F","Gb","G","Ab"];
        let rootChord = chord[0];
        if(chord[1] === '#' || chord[1] == 'b') {
            rootChord += chord[1];
        }
        amount = (amount % sharpnotes.length) || 1;
        if(amount < 0) { amount += sharpnotes.length; }
        for(let note=0; note < sharpnotes.length; ++note) {
            if(rootChord === sharpnotes[note]) {
                return( (sharpnotes[(note + amount) % sharpnotes.length]) + chord.substr(rootChord.length) );
            }
            if(rootChord === flatnotes[note]) {
                return( (flatnotes[(note + amount) % flatnotes.length]) + chord.substr(rootChord.length) );
            }
        }
        return ('???');
    }

    function transposeChordLine( line, amount ) {
        amount = amount || 1;
        let count = 0;
        let newLine = '';

        while(count < line.length) {
            if(line[count] >= 'A' && line[count] <= 'G') {
                let chord = line[count++];
                while (count < line.length && line[count] !== ' ' && (line[count] < 'A' || line[count] > 'G')) {
                    chord += line[count++];
                }
                let newChord = transposeChord(chord, amount);
                if(newChord.length < chord.length) {    // pad if shorter
                    newChord += " ";
                }
                if(newChord.length > chord.length && count < line.length && (line[count] < 'A' || line[count] > 'G')) { // trim if there's space
                    count++;
                }
                newLine += newChord;
            } else {
                newLine += line[count++];
            }
        }
        return(newLine);
    }

だから(例えば)

transposeChordLine("     C          D7    Dm7    Gb7 ", 4)

出力

"     E          F#7   F#m7   Bb7 "

フラットとシャープは、必要に応じて転置しても b/# のままであると推定されます。

于 2021-07-30T20:31:39.927 に答える