你如何转置midi文件?
Posted
技术标签:
【中文标题】你如何转置midi文件?【英文标题】:How do you transpose a midi file? 【发布时间】:2014-02-26 19:16:10 【问题描述】:我正在使用这个 MIDI.js 库:https://github.com/mudcube/MIDI.js
要加载插件并播放midi文件,我这样做:
window.onload = function ()
MIDI.loadPlugin(
soundfontUrl: "./soundfont/",
instruments: [ "acoustic_grand_piano" ],
callback: function()
MIDI.programChange(0, 0);
_player = MIDI.Player;
);
;
function playSong()
_player.timeWarp = 1; // speed the song is played back
_player.loadFile(song[songid], _player.start);
_player.addListener(function(data)
var now = data.now; // where we are now
var end = data.end; // time when song ends
var channel = data.channel; // channel note is playing on
var message = data.message; // 128 is noteOff, 144 is noteOn
var note = data.note; // the note
var velocity = data.velocity; // the velocity of the note
);
var songid = 0;
var song = ['data:audio/mid;base64,TVRoZAAAAA...
我的问题是,在播放之前是否可以转置这个 MIDI 文件?基本上我想解析一个midi文件(.mid文件或base64格式),将所有音符更改+1,然后将其发送给播放器。有什么方法可以在 javascript 中做到这一点?
【问题讨论】:
【参考方案1】:这不是一个完整的答案,但如果您仍然遇到困难,它可能会为您指明正确的方向。它基于花费几分钟查看 MIDI.js 的源代码以及它所构建的几个包。我假设您想在读入文件时应用转置并且对保存转置文件不是特别感兴趣。
-
addListener 方法不太可能有用。它看起来像是在音符发送到合成器后立即发生的回调,即改变音高为时已晚。
您需要找到将传入文件字符转换为 javascript 数组元素的函数。那可能在 jasmid 库中。
如果您真的很幸运,开发人员将提供一个挂钩,您可以使用该挂钩设置回调以在函数将事件属性写入数组之前更改它们。否则,您需要相应地修改函数。如果你能让它运行良好,请尝试说服开发人员将其修补到源代码中 - 否则你将无法维护自己的库分支。
希望这会有所帮助。
编辑:我认为您想要的文件是 https://github.com/gasman/jasmid/blob/master/midifile.js 。您可以在处理从第 155 行开始的 note-on 事件的情况下应用移调
case 0x09:
event.noteNumber = param1;
event.velocity = stream.readInt8();
if (event.velocity == 0)
event.subtype = 'noteOff';
else
event.subtype = 'noteOn';
return event;
或者,当返回的事件被推送到从第 227 行开始的轨道数组之前时
while (!trackStream.eof())
var event = readEvent(trackStream);
tracks[i].push(event);
【讨论】:
【参考方案2】:你可以添加一个监听器到播放器
addListener(
data =>
data.note += 1;
);
我相信它是在笔记本身之前调用的。
如果您使用我的 ES6 分支的 mudcube MIDI.js,称为 midicube [https://github.com/mscuthbert/midicube],它全部在 ES6 模块中,因此您可以更轻松地继承 Player 并在播放前操作数据。
【讨论】:
以上是关于你如何转置midi文件?的主要内容,如果未能解决你的问题,请参考以下文章