Web Whammy
This example shows:
- How to whammy/pitch shift the guitar notes.
- How to pass messages among MIDI Guitar 3 and the web browser. This allows you to code apps using any web framework and display/record notes in the browser.
Run this example
- Copy the Lua code below to a file named
MyWhammy.lua. - Copy the Html code below to a file named
MyWhammy.html. - Drag the Lua file into a chain in MIDI Guitar 3.
Lua audio/MIDI
local mute = false
local whammy = 0
local outputNotes = {}
function Initialize()
end
function Message(key, value)
if key == "param1" then
mute = value < 50
elseif key == "param2" then
whammy = 24 * value/100 - 12
end
end
function Process(time, beat, inputNotes)
if mute then
return nil
end
outputNotes = inputNotes
for k, v in pairs(outputNotes) do
outputNotes[k].pitch = outputNotes[k].pitch + whammy
end
return outputNotes
end
HTML/JavaScript visuals
<!doctype html>
<html>
<head>
<title>JAM API, JavaScript example app</title>
<script>
let client;
append = function (text) {
let html = text.replace(/\n/g, "<br />");
document.getElementById("midi_guitar_events").innerHTML = html;
};
window.onload = function () {
client = new WebSocket("ws://127.0.0.1:8080");
client.onmessage = function (event) {
append(event.data);
};
client.onopen = function () {
append("Connected to WebSocket.");
};
client.onclose = function () {
append("Connection closed. Refresh to reload.");
};
client.onerror = function () {
append("WebSocket error.");
};
};
function sendMessage(event) {
console.log(event);
client.send(document.getElementById("message").value);
}
function changeParameter(parameter, value) {
client.send("param"+parameter+"="+value);
}
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
</head>
<body>
<main class="container">
<h1>MIDI Guitar 3 Web App Example</h1>
<h3>Say something to MIDI Guitar 3</h3>
<div class="grid">
<input value="Hello from the web!" type="text" id="message" />
<input type="button" value="Say something to MIDI Guitar" onclick="sendMessage(event)"/>
</div>
<h3>Control MIDI Guitar 3</h3>
<div class="grid">
<div><p>Your App can control <b>MIDI Guitar 3</b>'s sound processing.</p></div>
<div>
<div>
<label>Mute</label>
<input id="param1" type="range" oninput="changeParameter(1, this.value)"/>
</div>
<div>
<label>Whammy</label>
<input id="param2" type="range" oninput="changeParameter(2, this.value)"/>
</div>
<div>
<label>CC3</label>
<input id="param3" type="range" oninput="changeParameter(3, this.value)"/>
</div>
<div>
<label>CC4</label>
<input id="param4" type="range" oninput="changeParameter(4, this.value)"/>
</div>
</div>
</div>
<h3>Notes streaming from MIDI Guitar 3</h3>
<div class="grid">
<div>
<p>Your App recieves the note data in the format:
<code>time, beat, beat-fraction \n</code>
<code>number-of-input-notes \n</code> and for every input note:
<code>note-id, age, string, pitch, bend, pressure, brightness \n</code>
<code>number-of-output-notes \n</code> and for every output note:
<code>note-id, age, string, pitch, bend, pressure, brightness \n</code>
</p>
<p><small>where <code>time</code> and <code>age</code> are in units of frames: 128/44100*1000 or 128/48000*1000 milliseconds each. <code>beat</code> is the PPQ (pulse pr quater) value, used in DAWs, depending on the BPM-tempo. Notes are streamed at >30fps (every tenth frame).</small></p>
</div>
<div><code><ul id="midi_guitar_events"></ul></code></div>
</div>
</main>
</body>
</html>