JSFiddle - React, Tailwind, and code Playground
by Arto Chydenius
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.7/rx.all.min.js"></script>
<div class="chilicorn"></div>
CSS
.chilicorn {
background: url('http://spiceprogram.org/assets/img/logo/chilicorn_no_text-512.png') center center no-repeat;
width: 512px;
height: 512px;
}
JavaScript
'use strict';
// Convert the promise to Observable, select the first input device and get stream of messages
const inputStream = Rx.Observable.fromPromise(navigator.requestMIDIAccess())
.map(midi => midi.inputs.values().next().value)
.flatMap(input => midimessageAsObservable(input))
.map(message => parseEvent(message));
const noteOnEvent = 144;
const firstPadNote = 36;
const controlEvent = 176;
const firstKnobIndex = 1;
const padStream = inputStream
.filter(x => x.status === noteOnEvent)
.filter(x => x.data[0] === firstPadNote);
const controlStream = inputStream
.filter(x => x.status === controlEvent)
.filter(x => x.data[0] === firstKnobIndex);
const tapTempoStream = padStream
.timeInterval()
.skip(1)
.map(x => msToBpm(x.interval))
.filter(x => x > 40);
const knobTempoStream = controlStream
.map(x => x.data[1])
.map(x => Math.round(x / 127 * 200));
const tempoStream = tapTempoStream.merge(knobTempoStream);
tempoStream.subscribe(bpm => {
console.log(bpm);
// chilicornEffect.setBpm(bpm);
});
function parseEvent(event) {
return {
status: event.data[0] & 0xf0,
data: [
event.data[1],
event.data[2]
]
};
}
// Convert millisecond time to beats per minute
function msToBpm(ms) {
console.log('ms: ' + ms);
return Math.round(60000 / ms);
}
/* chilicornEffect */
const chilicornEffect = (function() {
const fps = 100;
let phase = 0;
let bpm = 0;
setInterval(() => {
const scale = Math.sin(Math.PI * 2 / fps * phase * bpm / 60) * 0.25 + 0.75;
const size = scale * 512;
document.querySelector('.chilicorn').style.backgroundSize = `${size}px`;
phase++;
}, 1000 / fps);
return {
setBpm: function(x) {
bpm = x;
}
};
})();
chilicornEffect.setBpm(60);
/* rxjs-web-midi */
function midimessageAsObservable(input) {
return createObservable(input, 'onmidimessage');
}
function statechangeAsObservable(midi) {
return createObservable(midi, 'onstatechange');
}
function...