diff --git a/src/devices/Midi.ts b/src/devices/Midi.ts index 1d5811b..e5302e6 100644 --- a/src/devices/Midi.ts +++ b/src/devices/Midi.ts @@ -110,7 +110,8 @@ export class MidiControl { } // ugly typing here, but library overloads are a little annoying to work around. worst case scenario nothing happens - this.device.output?.send(type as any, { ...data, ...this.filter } as any); +const outData = {...this.filter, ...data } + this.device.output?.send(type as any, outData as any); } public getPage(): number { return this.page }; @@ -136,7 +137,6 @@ export class MidiControl { if (typeof pages === 'number') pages = [pages]; const newValue = { ...this.defaultData(), ...this.filter, ...data }; - for (const page of pages) { if (!noStore) this.values[page] = newValue; diff --git a/src/mappings/beunsize-ma3.ts b/src/mappings/beunsize-ma3.ts index bd79c8a..e47f1cc 100644 --- a/src/mappings/beunsize-ma3.ts +++ b/src/mappings/beunsize-ma3.ts @@ -161,7 +161,7 @@ export default async function mapping() { const [xtouch, xtouch_loop] = await retry(() => { return [ new MidiDevice('X-TOUCH COMPACT', true), - new MidiDevice('XTouch-loop', true, true) + new MidiDevice('xtouch-ma', true) ] }, 1000, 'xtouch') @@ -182,39 +182,36 @@ export default async function mapping() { tryXTouch(); //tryKeyboard(); - //tryApcMini(); + tryApcMini(); } async function xtouchMapping(xtouch: MidiDevice, xtouch_loop: MidiDevice, ma3: OSCDevice) { - const noteButtonFeedback = (note: number, address: string) => { - const button = xtouch.addControl(MessageType.NoteOnOff, { note }); - ma3.addListener(address, data => { - const value = data[0] - if (typeof value !== 'number') return; + xtouch.input.on('cc', m => console.dir(m)); + xtouch.input.on('noteon', m => console.dir(m)); + xtouch.input.on('noteoff', m => console.dir(m)); - button.handleFeedback(0, { value: value === 1 ? true : false }) - }) - - button.addOutput(0, data => ma3.sendInt(address, data.value ? 1 : 0)) - - return button; - } // MAPPINGS // passthroughs for encoders plugin - numberRange(21, 26).forEach(encoder => { + numberRange(18, 22).forEach(encoder => { xtouch.addControl(MessageType.CC, { controller: encoder }).addOutput(0, message => { xtouch_loop.output?.send(MessageType.CC, message) }) }) +numberRange(8, 12).forEach(encoder => { + xtouch.addControl(MessageType.NoteOn, { note: encoder }).addOutput(0, message => { + xtouch_loop.output?.send(MessageType.NoteOn, message) + }) + }) + // Executor Faders - const faders = numberRange(0, 8).map(f => xtouch.addControl(MessageType.CC, { controller: f })) + const faders = numberRange(1, 9).map(f => xtouch.addControl(MessageType.CC, { controller: f })) faders.forEach((fader, index) => { const firstExec = 201; @@ -227,7 +224,7 @@ async function xtouchMapping(xtouch: MidiDevice, xtouch_loop: MidiDevice, ma3: O ma3.addListener(address, value => { if (typeof value[0] === 'number') { - const mappedValue = mapNumber(value[0], 0, 1, 0, 127); + const mappedValue = mapNumber(value[0], 0, 100, 0, 127); fader.handleFeedback(0, { value: mappedValue }) } }) @@ -241,17 +238,30 @@ async function xtouchMapping(xtouch: MidiDevice, xtouch_loop: MidiDevice, ma3: O numberRange(32, 39), numberRange(40, 48) ].map((row, rowIndex) => row.map((note, noteIndex) => { + const totalIndex = rowIndex * 8 + noteIndex; const rowLookup = [401, 301, 201, 101]; - const address = `/Page/Key${rowLookup[rowIndex] ?? 101 + noteIndex}` + const address = `/Page/Key${(rowLookup[rowIndex] ?? 101) + noteIndex}` - return noteButtonFeedback(note, address); + const button = xtouch.addControl(MessageType.NoteOnOff, { note }); + + ma3.addListener(address, data => { + const value = data[0] + + if (typeof value !== 'number') return; + + button.handleFeedback(0, { value: true, note: totalIndex, velocity: value + 1 }) + }) + + button.addOutput(0, data => ma3.sendInt(address, data.value ? 1 : 0)) + + return button; })) // Misc Buttons const [rwd, fwd, loop, rec, stop, play] = [ - { note: 49, key: 'PAGE_UP' }, - { note: 50, key: 'PAGE_DOWN' }, + { note: 49, key: 'PAGE_DOWN' }, + { note: 50, key: 'PAGE_UP' }, { note: 51, key: '' }, { note: 52, key: '' }, { note: 53, key: 'DEF_GOBACK' }, @@ -268,20 +278,24 @@ async function xtouchMapping(xtouch: MidiDevice, xtouch_loop: MidiDevice, ma3: O // Exec Encoders - const encoders = [11, 12, 13, 14, 15, 16, 17, 18].map((cc, index) => { + const encoders = [26,27,28,29,30,31,32,33].map((cc, index) => { const encoder = xtouch.addControl(MessageType.CC, { controller: cc }) const firstExec = 401; const address = `/Page/Encoder${firstExec + index}`; const feedbackAddress = `/Page/Fader${firstExec + index}`; + + encoder.addOutput(0, message => { - ma3.sendInt(address, mapNumber(message.value, 0, 1, -1, 1)) +let value = message.value; +if(message.value > 50) value = message.value - 128; +console.log(value); + ma3.sendFloat(address, value) }) ma3.addListener(feedbackAddress, data => { if (typeof data[0] !== 'number') return; - - encoder.handleFeedback(0, { value: mapNumber(data[0], 0, 1, 0, 127) }) + encoder.handleFeedback(0, { value: mapNumber(data[0], 0, 100, 0, 13) }) }) }) } @@ -333,7 +347,7 @@ async function keyboardMapping(keyboard: MidiDevice, ma3: OSCDevice) { } async function apcminiMapping(apcmini: MidiDevice, ma3: OSCDevice) { - const APC_FIRST_EXEC = 201; + const APC_FIRST_EXEC = 231; apcmini.input.on('cc', m => console.dir(m)); apcmini.input.on('noteon', m => console.dir(m)); @@ -347,7 +361,8 @@ async function apcminiMapping(apcmini: MidiDevice, ma3: OSCDevice) { const address = `/Page/Fader${exec}`; fader.addOutput(0, (message) => { - ma3.sendFloat(address, mapNumber(message.value, 2, 125, MA3_FADER_MIN, MA3_FADER_MAX)); +console.log(address) + ma3.sendFloat(address, mapNumber(message.value, 0, 127, MA3_FADER_MIN, MA3_FADER_MAX)); }); }); @@ -381,9 +396,9 @@ async function apcminiMapping(apcmini: MidiDevice, ma3: OSCDevice) { ]; [ - numberRange(101, 108), - numberRange(301, 308), - numberRange(401, 408), + numberRange(331, 338), + numberRange(431, 438), + numberRange(131, 138), null, null, null,