javascript - 在 Teoria.js 中反转和弦的规范方法是什么

标签 javascript music-notation

使用 Web MIDI 和 Teoria.JS我正在尝试构建一个基于网络的和弦 Controller 。

感谢teoria-chord-progression,我找到了一种生成音阶和弦的方法然后获取它的 MIDI 代码。现在我想获取同一和弦转位的 MIDI 音符。

到目前为止,我所做的是从原始 MIDI 音符中减去第一个转位的第五个音符,然后是第二个转位的第三个和第五个音符,但我确信有更好的方法。

编辑:这里是我的代码,它仅以非倒置形式播放和弦:

'use strict';

const teoria = require('teoria');
const chordProgression = require('teoria-chord-progression');
const Combokeys = require("combokeys");

const document = global.document;

const cSharpHMinor = teoria.scale('c#', 'harmonicminor');
const chords = chordProgression(cSharpHMinor, [1, 2, 3, 4, 5, 6, 7], 3).chords;
const combokeys = new Combokeys(document.documentElement);


global.navigator.requestMIDIAccess()
    .then((midiAccess) => {
        return Array.from(midiAccess.outputs.values());
    })
    .then((midiOutputs)=> {
        chords.forEach((chord, index) => {
            buildPadForChord(index + 1, chord, midiOutputs);
        });
    });


function createPad(index, chordName, listener) {
    let button = document.createElement('button');
    button.setAttribute('type', 'button');
    button.textContent = `${chordName} (${index})`;
    button.addEventListener('click', listener);

    let autorepeat = false;
    combokeys.bind(index.toString(), () => {
        if (!autorepeat) {
            autorepeat = true;
            listener();
        }
    }, 'keydown');
    combokeys.bind(index.toString(), () => {
        autorepeat = false;
    }, 'keyup');
    document.documentElement.appendChild(button);
}

function buildPadForChord(index, chord, midiOutputs) {

    let listener = () => {
        midiOutputs.forEach((midiOutput) => {
            chord.notes().forEach((note)=> {
                midiOutput.send([0x90, note.midi(), 127]);
                midiOutput.send([0x80, note.midi(), 127], global.performance.now() + 1000.0);
            });
        });
    };

    createPad(index, chord.name, listener);
}

最佳答案

根据this issue on git ,目前 Teoria.js 中尚未实现反转。开发人员一度考虑添加它们,但到目前为止还没有任何进展。

我在自己的代码中的实现是这样的:

// Adds an "invert" function to the Teoria Chord class
teoria.Chord.prototype.invert = function(n){
  // Grabs the current chord voicing. Returns array of intervals.
  var voicing = this.voicing()
  // Reverse the array to work top-down when n is negative
  if(n < 0){
    voicing = voicing.reverse()
  }

  // Loop through each inversion
  var j = Math.abs(n);
  for(let i = 0; i < j; i++){
    // Find which interval we're modifying this loop.
    let index = i % voicing.length;
    if(n > 0){
        // Move the lowest note up a perfect 8th
        voicing[index] = voicing[index].add(teoria.interval('P8'))
      }else{
      // Move the highest note down a perfect 8th
      voicing[index] = voicing[index].add(teoria.interval('P-8'))
    }
  }
  // Change the array into a usable format
  var newVoicing = arrayToSimple(voicing)
  this.voicing(newVoicing)

  // Return the object for chaining
  return this;
}

arrayToSimple 函数:

function arrayToSimple(array){
    var newArray = []
    for(let item of array){
        newArray.push(item.toString())
    }
    return newArray
}

现在,您可以在任何和弦上调用 Chord.invert(n),其中 n 是您的转位编号。如果n为负数,则和弦向下反转,如果n为正,则向上反转。

请注意,上面的 invert() 函数需要一个发音为 [最低音符,...,最高音符] 的和弦,按该顺序。因此,调用 Chord.invert(1).invert(1) 与调用 Chord.invert(2) 不同。如果您需要此功能,您可以使用 Chord.bass() 和/或 Chord.notes() 检测哪些音符最低,然后对元素重新排序。不过,这可能有点过分了。

关于javascript - 在 Teoria.js 中反转和弦的规范方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33956385/

相关文章:

javascript - 在 c3.js - d3.js 中将第 2 个字母以粗体显示

javascript - 如何将事件监听器仅附加到新创建的元素?

javascript - 基于 currentPath 的 Ember 导航栏 UI 条件

wpf - 音乐编辑器的歌词

c# - 从WAV文件中检索振幅数组,不返回完整数据

Python music21 库从流创建 png

javascript - 如何使用 javascript 检测内联链接?

javascript - 将 C# 变量值传递给代码隐藏类中生成的脚本中的 JavaScript 变量

xml - MusicXML 规范和和弦符号

.NET 吉他和弦库