Last active
January 6, 2018 22:47
-
-
Save Joeltbond/f64ff68f9c69b756fadc602eb30a31c1 to your computer and use it in GitHub Desktop.
Redux Module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { eventChannel } from "redux-saga"; | |
import { takeEvery, take, call, put } from "redux-saga/effects"; | |
const APP_MOUNTED = "midi/APP_MOUNTED"; | |
const MIDI_UNSUPPORTED = "midi/MIDI_UNSUPPORTED"; | |
const MIDI_NOTE_ON = "midi/MIDI_NOTE_ON"; | |
const MIDI_NOTE_OFF = "midi/MIDI_NOTE_OFF"; | |
const initialState = { | |
errors: [], | |
notes: {} | |
}; | |
export default (state = initialState, action = {}) => { | |
switch (action.type) { | |
case MIDI_UNSUPPORTED: | |
return { | |
...state, | |
errors: state.errors.concat( | |
"Midi input is not supported in your browser" | |
) | |
}; | |
case MIDI_NOTE_ON: { | |
return { | |
...state, | |
notes: { | |
...state.notes, | |
[action.payload.note]: action.payload.velocity | |
} | |
}; | |
} | |
case MIDI_NOTE_OFF: { | |
const newNotes = { ...state.notes }; | |
delete newNotes[action.payload.note]; | |
return { | |
...state, | |
notes: newNotes | |
}; | |
} | |
default: | |
return state; | |
} | |
}; | |
export const appMounted = () => ({ | |
type: APP_MOUNTED | |
}); | |
function* onMidiMessage({ data }) { | |
const [type, note, velocity] = data; | |
switch (type) { | |
case 144: | |
yield put({ type: MIDI_NOTE_ON, payload: { note, velocity } }); | |
break; | |
case 128: | |
yield put({ type: MIDI_NOTE_OFF, payload: { note } }); | |
break; | |
default: | |
} | |
} | |
function createMidiEventChannel(midiAccess) { | |
return eventChannel(emitter => { | |
const inputs = midiAccess.inputs.values(); | |
for ( | |
var input = inputs.next(); | |
input && !input.done; | |
input = inputs.next() | |
) { | |
// each time there is a midi message call the onMIDIMessage function | |
input.value.onmidimessage = emitter; | |
} | |
return () => { | |
//; | |
}; | |
}); | |
} | |
function* onMidiSuccess(midiAccess) { | |
const channel = yield call(createMidiEventChannel, midiAccess); | |
while (true) { | |
const message = yield take(channel); | |
yield call(onMidiMessage, message); | |
} | |
} | |
function* appMountedSaga() { | |
if (window.navigator.requestMIDIAccess) { | |
try { | |
const midiAccess = yield call( | |
[window.navigator, window.navigator.requestMIDIAccess], | |
{ | |
sysex: false | |
} | |
); | |
yield call(onMidiSuccess, midiAccess); | |
} catch (error) { | |
yield put({ type: MIDI_UNSUPPORTED }); | |
console.error(error); | |
} | |
} | |
} | |
export const appSagas = [takeEvery(APP_MOUNTED, appMountedSaga)]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment