使用Web和Teoria.JS,我正在尝试建立一个基于web的和弦控制器。
多亏了teoria-chord-progression,我找到了一种为音阶生成和弦的方法,然后获得了它的midi代码。现在我想要得到相同和弦反转的midi音符。
到目前为止,我所做的是从原始midi音符中减去12,第一次反转的第五个音符,然后是第三个反转音符,第二个反转音符的第五个音符,但我相信还有更好的方法。
编辑:这里是我的代码,它只播放未反转形式的和弦:
'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);
}
发布于 2017-05-08 10:52:22
根据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上调用Chord.invert(n),其中n是您的反转号。如果n为负,弦将向下反转,而如果为正,则弦将向上反转。
请注意,上面的invert()函数需要一个发音为[lowest note, ..., highest note]的chord。因此,调用Chord.invert(1).invert(1)与调用Chord.invert(2)是不同的。如果您需要此功能,您可能会使用Chord.bass()和/或Chord.notes()检测哪些注释最低,并重新排序元素。不过,这可能有些过头了。
https://stackoverflow.com/questions/33956385
复制相似问题