webMIDIで制御するのは良いけど、マッピング出来たら楽だなぁと思ったので作ってみました。
SelectIndex(0で音量,1で再生速度)を選択して、Add miniでMIDIデータ上位2バイトを配列に保存して設定完了です。
JSON形式にしてローカルファイルに保存、参照できたら良いけど面倒なのでパス。
html
<!DOCTYPE HTML>
<html lang="jp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input id="Afile" type="file">
<audio id="Aplayer"></audio>
<input type="checkbox" id="play_pause">PLAY/PAUSE
<input type="checkbox" id="loop">LOOP
<input type="range" id="volume" value="1" min="0" max="1" step="0.05">GAIN
<input type="range" id="pitchAdj" value="1.00" min="0.84" max="1.16" step="0.01">PITCH
<select id="midiMapping" size="2">
<option value="gain">GAIN</option>
<option value="pitch">PITCH</option>
</select>
<input type="button" value="add midi" id="add">
<script>
</script>
</body>
</html>
javascript
var inputs = [];
var highNibble;
var lowNibble;
var highDatabyte;
var lowDatabyte;
var mapping;
var midiData = [];
var gain;
window.onload = function() {
//ファイルの読み込み
var Actx = new(window.AudioContext || window.webkitAudioContext)();
gain = Actx.createGain();
var source = Actx.createMediaElementSource(Aplayer);
Afile.onchange = function() {
Aplayer.src = URL.createObjectURL(this.files[0]);
Aplayer.currentTime = 0;
play_pause.checked = false;
};
//再生、一時停止
play_pause.onchange = function() {
(play_pause.checked) ? Aplayer.play(): Aplayer.pause();
};
//ループ
loop.onchange = function() {
(loop.checked) ? Aplayer.loop = true: Aplayer.loop = false;
};
//音量
document.getElementById('volume').addEventListener('input', function() {
gain.gain.value = this.valueAsNumber;
});
//再生速度の変更
document.getElementById('pitchAdj').addEventListener('input', function() {
Aplayer.playbackRate = this.valueAsNumber;
});
//再生終了時チェックを外す
Aplayer.onended = function() {
play_pause.checked = false;
Aplayer.currentTime = 0;
};
//ルーティング
source.connect(gain).connect(Actx.destination);
//MIDIマッピング
document.getElementById("add").onclick = function() {
mapping = document.getElementById("midiMapping").selectedIndex;
midiData[mapping] = [highNibble, lowNibble, highDatabyte];
};
};
//MIDIデバイスへ接続
navigator.requestMIDIAccess().then(function(midiAccess) {
var inputIterator = midiAccess.inputs.values();
for (var i = inputIterator.next(); !i.done; i = inputIterator.next()) {
inputs.push(i.value);
}
inputs[0].onmidimessage = function(e) {
highNibble = (e.data[0] & 240) >> 4;
lowNibble = e.data[0] & 15;
highDatabyte = e.data[1];
lowDatabyte = e.data[2];
//MIDIコントロール
if (midiData[0].toString() == [highNibble, lowNibble, highDatabyte]) {
gain.gain.value = lowDatabyte / 127;
}
if (midiData[1].toString() == [highNibble, lowNibble, highDatabyte]) {
Aplayer.playbackRate = lowDatabyte / 127 * 0.16 + 0.92;
}
};
});