MIDI.js 音符持续时间不会改变
Posted
技术标签:
【中文标题】MIDI.js 音符持续时间不会改变【英文标题】:MIDI.js note duration does not change 【发布时间】:2014-01-22 23:40:01 【问题描述】:由于 mudcube MIDI.js 的文档在这方面似乎缺乏,我希望有人能够为我指明正确的方向。说白了,使用midi.js,如何调整midi音符的时长和结尾?
对于某些背景,我创建了一个带有可拖放音符 (jQuery-ui) 的乐谱小部件,可以添加或删除该小部件,以形成可以调用来播放 MIDI 的序列。到目前为止,一切正常,但是,当我试图用更复杂的时间扩展这个小部件的功能时,我遇到了一些问题。
似乎我只能在设定的时长内弹奏音符,而且,尽管我付出了所有努力,但仍无法实现可以改变该时长的更改,例如二分音符、四分音符、八分音符等。此外,这可能是原因之一,MIDI.noteOff 对输出没有明显的影响。人们会认为给定的音符会无限期地播放,直到调用 MIDI.noteOff 为止,但是,无论是否调用 noteOff,所述音符都会播放然后逐渐消失。
让我在这里说一下,我已经对 SO 和整个网络进行了广泛的研究,以弄清这一点。我找到了有类似问题的人并应用了他们的修复程序,但他们的答案对我不起作用。见how do I play arbitrary notes in Midi with javascript和MIDI.noteOff does not seem to work reliably
我有一个名为 noteSequence 的音符序列,其中每个音符都是一个具有 noteValue(即“C4”)和 noteDuration 属性的对象,这些属性在函数 convertToMidiSequence 中转换为 midiSequence。一切都适用于旋律序列和和弦,我只想添加持续时间功能。我还应该说,调整“延迟”变量或 noteDuration 属性只会增加播放序列之前的时间。然后在初始延迟之后,序列以与之前相同的时间播放。
感谢您抽出一些时间来查看此内容并希望能提供帮助。将不胜感激。
这是运行我的 MIDI 的适用代码:
$(document).ready(function()
MIDI.loadPlugin(
soundfontUrl: GLOBALS.SOUNDFONT_URL,
instrument: 'acoustic_grand_piano',
callback: function()
var channel = 0,
instrument = 0,
velocity = 127,
delay = 1;
MIDI.programChange(0, instrument);
);
);
function playCurrentSequence()
playSequence(noteSequence);
function playSequence(sequence)
var midiSequence = convertToMidiSequence(sequence);
for (var i = 0; i < midiSequence.length; i++)
if (!(midiSequence[i] instanceof Array))
playNote(midiSequence[i], i);
else
playChord(midiSequence[i], i);
function playNote(midiNote, notePositionInMeasure)
var channel = 0,
velocity = 127,
delay = 1;
MIDI.noteOn(channel, midiNote, velocity, delay + notePositionInMeasure + 1);
MIDI.noteOff(channel, midiNote,
delay + midiNote.noteDuration + notePositionInMeasure + 1);
MIDI.Player.stop();
function playChord(midiChord, notePositionInMeasure)
var channel = 0,
velocity = 127,
delay = 1;
for (var i = 0; i < midiChord.length; i++)
MIDI.noteOn(channel, midiChord[i], velocity, delay + notePositionInMeasure + 1);
MIDI.noteOff(channel, midiChord[i],
delay + midiChord[i].noteDuration + notePositionInMeasure + 1);
MIDI.Player.stop();
【问题讨论】:
你如何衡量noteDuration
?为什么+1
?
@CL。我已将 noteDuration
设置为 4 以表示整个音符(我尝试了许多其他值),但这可能会根据时间的正确实现而改变。 +1
是早期修复程序的保留(notePositionInMeasure
是给定音符在零索引数组中的位置,这是为了确保始终添加至少 1),但它目前似乎没有改变它是否有没有。感谢您指出这一点,我会删除它。
noteOff
的implementation 被注释掉。我还没有找到任何关于 delay
实际含义的文档。
@CL。非常有趣...我拥有的 Plugin.js 似乎包含我发布的链接中建议的修复。 MIDI.noteOff does not seem to work reliably 也许他们还没有更新他们的网站以反映这一变化?
【参考方案1】:
有必要指出 MIDI NoteOff 的实际含义——通常是之前收到 NoteOn 的音符进入其ADSR envelope 的释放状态,并最终消失。它直到一段时间后才会释放频道。
现在,对于大多数打击乐声音而言,本身并没有 NoteOff 的概念 - 它们只是在延音阶段的初始攻击之后衰减到零(有点用词不当)。钢琴上的 Note-off 应用了制音器,但此时声音可能已经消失得无影无踪了。
其他声音可能是没有 NoteOff 概念的直接样本触发器。
因此行为并不一致,很大程度上取决于您选择的声音。您是否验证过 NoteOffs 确实对它有意义?
【讨论】:
感谢您澄清这一点,我不知道。我正在调查noteOff
现在是否真的适用。但是,我是否应该发现它没有,是否有可以将钢琴声音延长或静音预定长度的解决方法?
是的。制音器(又名延音)踏板应该起到延长音符的作用 - 尽管不是无限期地 - 音符。将通道音量设置为零可能会起到阻止音符消失的作用。
这是一个很好的观点,然而,据我所知,MIDI.js 似乎没有阻尼或延音选项来增强音符。不过我可能弄错了。
阻尼踏板 - 又名。维持 - 是 CC64。我猜有什么方法可以在 MIDI.js 中发送控制器消息?这是list of controllers以上是关于MIDI.js 音符持续时间不会改变的主要内容,如果未能解决你的问题,请参考以下文章