Skip to content

Commit

Permalink
Merge pull request #21 from oscarrc/dev
Browse files Browse the repository at this point in the history
[ADD] Midi passthrough
  • Loading branch information
oscarrc authored Mar 16, 2021
2 parents 494ae4e + f59acee commit 83357d3
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 21 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ This is still a work in progress, so expect some bugs and issues.

#### TODOs

- [ ] Implement midi passthrough (in progress, but [I need a controller for testing](https://ko-fi.com/oscarrc))
- [x] Get names of user oscilators and effects.
- [x] Implement midi passthrough (done, but [I need a controller for testing](https://ko-fi.com/oscarrc))
- [x] Get names of user oscilators and effects
- [ ] Compile standalone apps

If you miss any feature, please, request it.

Expand All @@ -35,6 +36,7 @@ If you miss any feature, please, request it.
* Play with the on screen keyboard
* Change the starting octave
* Send pitch bend
* Use any USB Midi controller to play the NTS-1
* Sequence melodies with the built-in sequencer
* Control the tempo of the sequencer
* Play notes any octave
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "nts-web",
"description": "NTS-1 web based editor and controller",
"version": "2.0.0",
"version": "2.0.3",
"author": "Oscar R.C.",
"private": true,
"dependencies": {
"@ant-design/icons": "^4.3.0",
Expand Down Expand Up @@ -37,12 +38,13 @@
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"postbuild": "npx cap copy android && npx cap copy @capacitor-community/electron",
"postbuild": "npx cap sync android && npx cap sync @capacitor-community/electron",
"test": "react-scripts test",
"eject": "react-scripts eject",
"predeploy": "npm run build && cp build/index.html build/200.html",
"deploy": "surge build nts-web.oscarrc.me",
"postdeploy": "electron-packager electron/ nts-web --platform=win32 --arch=arm64 --arch=ia32 --arch=x64 --overwrite --out=dist"
"package": "electron-packager electron/ nts-web --platform=win32 --platform=linux --arch=arm64 --arch=ia32 --arch=x64 --overwrite --out=dist",
"postpackage": "electron-installer-windows --src dist/nts-web-win32-x64 --dest dist/installers/nts-web-win-32-x64 && electron-installer-windows --src dist/nts-web-win32-ia32 --dest dist/installers/nts-web-win-32-ia32 && electron-installer-windows --src dist/nts-web-win32-arm64 --dest dist/installers/nts-web-win-32-arm64"
},
"eslintConfig": {
"extends": [
Expand Down
6 changes: 3 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function App(){
});
}

// const initPassthrough = (midi) => midiListenPassthrough(midi.passthorughDevice, midi.pasthroughChannel, midi.outputDevice, midi.outputChannel);
const initPassthrough = (midi) => midiListenPassthrough(midi.passthroughDevice, midi.pasthroughChannel, midi.outputDevice, midi.outputChannel);
const initControlChange = (midi) => midiListenControlChange(midi.inputDevice, midi.inputChannel, (e) => {
dispatch({ type: "synth/setControl", payload: {
cc: e.data[1],
Expand All @@ -61,10 +61,10 @@ function App(){
}, [])

useEffect( () => {
// initPassthrough(midiState);
initPassthrough(midiState);
initControlChange(midiState);
return () => {
// initPassthrough(midiState);
initPassthrough(midiState);
initControlChange(midiState);
}
// eslint-disable-next-line
Expand Down
10 changes: 5 additions & 5 deletions src/components/layout/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function Settings(props) {
opt.forEach( (option) => {
options.push(<Option key={ obj ? option.id : option } value={ obj ? option.id : option }>{ obj ? option.name : option }</Option>)
})

return options;
}

Expand All @@ -45,8 +45,8 @@ export function Settings(props) {
inputChannel: props.settings.inputChannel,
outputDevice: props.settings.outputDevice,
outputChannel: props.settings.outputChannel,
// passthroughDevice: props.settings.passthroughDevice,
// passthroughChannel: props.settings.passthroughChannel
passthroughDevice: props.settings.passthroughDevice,
passthroughChannel: props.settings.passthroughChannel
}} >
<Divider className="text-light">Input</Divider>
<Item label="Device" name="inputDevice">
Expand All @@ -70,7 +70,7 @@ export function Settings(props) {
{ renderOptions(props.channels) }
</Select>
</Item>
{/* <Divider className="text-light">Passthrough</Divider>
<Divider className="text-light">Passthrough</Divider>
<Item label="Device" name="passthroughDevice">
<Select className="control-select text-lcd">
{ renderOptions(props.settings.passthroughDevices, true) }
Expand All @@ -80,7 +80,7 @@ export function Settings(props) {
<Select className="control-select text-lcd">
{ renderOptions(props.channels) }
</Select>
</Item> */}
</Item>
</Form>
</Modal>
);
Expand Down
21 changes: 13 additions & 8 deletions src/utils/midi.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,33 @@ const midiStart = () => {
return new Promise((resolve, reject) => {
webmidi.enable( (err) => {
if (err) reject(err);

const devices = {
inputDevices: webmidi.inputs.filter(d => d.name.includes("NTS")).map( d => { return {id: d.id, name: d.name } }),
outputDevices: webmidi.outputs.filter(d => d.name.includes("NTS")).map( d => { return {id: d.id, name: d.name } }),
passthroughDevices: webmidi.outputs.filter(d => !d.name.includes("NTS")).map( d => { return {id: d.id, name: d.name } }),
passthroughDevices: webmidi.inputs.filter(d => !d.name.includes("NTS")).map( d => { return {id: d.id, name: d.name } }),
}

resolve({
...devices,
inputDevice: devices.inputDevices?.length > 0 ? devices.inputDevices[0].id : "",
outputDevice: devices.outputDevices?.length > 0 ? devices.outputDevices[0].id : "",
passthorughDevice: devices.passthorughDevices?.length > 0 ? devices.outputDevices[0].id : ""
passthroughDevice: devices.passthroughDevices?.length > 0 ? devices.passthroughDevices[0].id : ""
})
}, true);
})
}

const midiListenPassthrough = (passDevice, passChannel, outputDevice, outputChannel) => {
const midiDeviceDetection = (cb) => {
if(!webmidi.enabled) return;
const passthrough = webmidi.getInputById(passDevice);
webmidi.addListener('connected', cb);
webmidi.addListener('disconnected', cb);
}

const sendNote = (e) => midiPlayNote(e.value, outputDevice, outputChannel, e.type === "noteon" ? true : false, e.velocity);
const midiListenPassthrough = (passDevice, passChannel, outputDevice, outputChannel) => {
if(!webmidi.enabled) return;
const passthrough = webmidi.getInputById(passDevice);

const sendNote = (e) => midiPlayNote(e.note.number, outputDevice, outputChannel, e.type === "noteon" ? true : false, e.velocity);
const sendPitchBend = (e) => midiSendPitchBend(e.value, outputDevice, outputChannel);

if(passthrough){
Expand Down Expand Up @@ -121,4 +126,4 @@ const midiGetUserPrograms = (inputId, outputId, inputChannel, vendor, device, ch
})
}

export { midiStart, midiListenPassthrough, midiListenControlChange, midiSendPitchBend, midiGetUserPrograms, midiControlChange, midiPlayNote }
export { midiStart, midiDeviceDetection, midiListenPassthrough, midiListenControlChange, midiSendPitchBend, midiGetUserPrograms, midiControlChange, midiPlayNote }

0 comments on commit 83357d3

Please sign in to comment.