Skip to content

Instantly share code, notes, and snippets.

@colinbdclark
Last active August 10, 2019 14:48
Show Gist options
  • Save colinbdclark/c719dbd8b07b550a7968e20cf80dda42 to your computer and use it in GitHub Desktop.
Save colinbdclark/c719dbd8b07b550a7968e20cf80dda42 to your computer and use it in GitHub Desktop.
Infused MPE MIDI Example
<html>
<head>
<script src="node_modules/flocking/dist/flocking-all.js"></script>
<script src="seaboard-block-instrument.js"></script>
<script src="mpe-voice.js"></script>
<script src="mpe-synth.js"></script>
<style>
body {
padding: 0;
margin: 0;
}
#meter {
box-sizing: border-box;
position: fixed;
bottom: 0;
left: 0;
border: 3px solid grey;
border-radius: 15px;
width: 100vw;
height: 75px;
}
</style>
</head>
<body>
<input type="checkbox" id="starter" name="starter">
<label for="starter">Start Audio</label>
<canvas id="meter"></canvas>
<script>
var environment = flock.init();
document.getElementById('starter').onclick = function(){
if (this.checked){
environment.play();
} else{
environment.stop();
}
};
var seaboardBlock = adam.seaboardBlock();
</script>
</body>
</html>
fluid.defaults("adam.mpeSynth", {
gradeNames: "flock.synth",
synthDef: {
ugen: "flock.ugen.scope",
source: {
id: "distortion",
ugen: "flock.ugen.distortion.tarrabiaDeJong",
mul: {
id: "env",
ugen: "flock.ugen.asr",
attack: 0.1,
release: 1,
gate: 0,
mul: 0.35
},
amount: 2,
source: {
id: "osc",
ugen: "flock.ugen.saw"
}
},
options: {
canvas: "#meter",
styles: {
strokeColor: "#777777",
strokeWidth: 2
}
}
}
});
fluid.defaults("adam.mpeVoice", {
gradeNames: "flock.midi.receiver",
channel: 1,
components: {
synth: {
type: "adam.mpeSynth"
}
},
listeners: {
"noteOn.updateSynth": {
funcName: "adam.mpeVoice.noteOn",
args: ["{arguments}.0", "{that}"]
},
"noteOff.updateSynth": "{synth}.noteOff()",
"control.updateSynth": {
funcName: "adam.mpeVoice.control",
args: ["{arguments}.0", "{that}"]
}
}
});
adam.mpeVoice.noteOn = function (midiMsg, that) {
that.synth.noteOn({
"osc.freq": flock.midiFreq(midiMsg.note)
});
};
adam.mpeVoice.control = function (midiMsg, that) {
that.synth.set("distortion.amount", midiMsg.value / 64);
};
{
"dependencies": {
"flocking": "2.0.1"
}
}
fluid.defaults("adam.seaboardBlock", {
gradeNames: "fluid.component",
channels: "@expand:fluid.iota(15, 1)", // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
components: {
midiConnection: {
type: "flock.midi.connection",
options: {
openImmediately: true,
ports: {
input: {
name: "Seaboard BLOCK"
}
}
}
}
},
dynamicComponents: {
voices: {
type: "adam.mpeVoice",
sources: "{that}.options.channels",
options: {
channel: "{source}"
}
}
},
listeners: {
"{midiConnection}.events.message": {
funcName: "adam.seaboardBlock.fireToChannel",
args: ["{seaboardBlock}", "{arguments}.0", "{arguments}.1"]
}
});
adam.seaboardBlock.fireToChannel = function (seaboardBlock, midiMsg, rawMidiEvent) {
var midiChannelKey = fluid.computeDynamicComponentKey("voices", midiMsg.channel);
var midiChannelFilter = seaboardBlock[midiChannelKey];
if (midiChannelFilter) {
// TODO: This ends up doubly-parsing raw incoming MIDI messages
// because Flocking doesn't allow us to call the event-delegation logic
// buried within flock.midi.connection.fireEvent().
flock.midi.connection.fireEvent(rawMidiEvent, midiChannelFilter.events);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment