Hi!
here is a small script i made for AKAI Advance 25 with simple assignments.
as the knobs are 360 degree infinite rotation I would like it to update directly according to the selected track like the motorized fader
so i need help as i am not an experiamenter developer and the api is not really documented yet because it is still young
//-----------------------------------------------------------------------------
// 1. DRIVER SETUP - create driver object, midi ports and detection information
//-----------------------------------------------------------------------------
// get the api's entry point
var midiremote_api = require('midiremote_api_v1')
// create the device driver main object
var deviceDriver = midiremote_api.makeDeviceDriver('Akai', 'Advance 25', 'Gnox')
// create objects representing the hardware's MIDI ports
var midiInput = deviceDriver.mPorts.makeMidiInput()
var midiOutput = deviceDriver.mPorts.makeMidiOutput()
// define all possible namings the devices MIDI ports could have
// NOTE: Windows and MacOS handle port naming differently
deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput)
.expectInputNameEquals('ADVANCE25 USB PORT 1')
.expectOutputNameEquals('ADVANCE25 USB PORT 1')
//deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput)
// .expectInputNameEquals('SimpleDevice (MIDI IN)')
// .expectOutputNameEquals('SimpleDevice (MIDI OUT)')
var surface = deviceDriver.mSurface
//---------- channelNumber and controlChangeNumber -----------//
// KnobcNr = knobIndex
const KnobccNr = 7
// switcheccNr = switcheIndex
const switcheccNr = 65
const padcNr = 15
const padInitPitch = 36
const transportcNr = 0
const transportccNrs = [118, 119, 117, 114]
//-----------------------------------------------------------------------------
// 2. SURFACE LAYOUT - create control elements and midi bindings
//-----------------------------------------------------------------------------
// Encoders
function makeKnobStrip(knobIndex, x, y) {
var knobStrip = {}
knobStrip.knob = surface.makeKnob(x * knobIndex + 16.5, y, 2.5, 2.5)
knobStrip.knob.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(knobIndex, KnobccNr)
return knobStrip
}
// Switches
function makeSwitcheStrip(switcheIndex, x, y) {
var switcheStrip = {}
switcheStrip.button = surface.makeButton(x * switcheIndex + 17, y, 1.5, 0.8)
switcheStrip.button.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(switcheIndex, switcheccNr)
return switcheStrip
}
// Pads
function makePadStrip(padIndex, x, y) {
var padStrip = {}
padStrip.pad = surface.makeTriggerPad(x * padIndex + 16.5, y, 2.5, 2.5)
padStrip.pad.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToNote(padcNr, padInitPitch + padIndex)
return padStrip
}
// Transport Control Buttons
function makeTransport(transportIndex, x, y, ccNr) {
var trasnport= {}
trasnport.button = surface.makeButton(x * transportIndex + 29, y, 1.5, 1)
trasnport.button.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(transportcNr, ccNr)
return trasnport
}
function makeSurfaceElements() {
var surfaceElements = {}
surfaceElements.numStrips = 8
surfaceElements.numTransport = 4
// Encoders
var x = 2.5
var y = 0
surfaceElements.knobStrips = {}
for(var i = 0; i < surfaceElements.numStrips; ++i) {
surfaceElements.knobStrips[i] = makeKnobStrip(i, x, y)
}
// Switches
x = 2.5
y = 2.8
surfaceElements.switcheStrip = {}
for(var i = 0; i < surfaceElements.numStrips; ++i) {
surfaceElements.switcheStrip[i] = makeSwitcheStrip(i, x, y)
}
// Pads
x = 2.5
y = 4
surfaceElements.triggerPads = {}
for(var i = 0; i < surfaceElements.numStrips; ++i) {
surfaceElements.triggerPads[i] = makePadStrip(i, x, y)
}
// Transport Control Buttons
x = 1.9
y = 7
surfaceElements.trasnport = {}
for(var i = 0; i < surfaceElements.numTransport; ++i) {
var ccNr = transportccNrs[i]
surfaceElements.trasnport[i] = makeTransport(i, x, y, ccNr)
}
// Pitch-Bend Wheel
var pitchBend = surface.makePitchBend(1.5, 10, 1.5, 6)
pitchBend.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToPitchBend(0)
// Modulation Wheel
var modWheel = surface.makeModWheel(5, 10, 1.5, 6)
modWheel.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(0, 1)
//----------------unassignable buttons---------------//
x = 1.9
y = 5.7
var w = 1.5
var h = 0.8
var xOffset = 2.9
// Page Left/Right
for (var i = 0; i < 2; i++) {
surface.makeBlindPanel(x * i + xOffset, 5.7, w, h)
}
// Shift and Mode Buttons
y = 7.2
xOffset = 0
for (var i = 0; i < 7; i++) {
if (i >= 5) {
xOffset = 3.2
}
surface.makeBlindPanel(i * x + xOffset, y, w, h)
}
// Octave Down/Up, Arp / Config, Latch, Tap Tempo, Note Repeat and Full Level
y = 7
h = 1
xOffset = 16.5
for (var i = 0; i < 5; i++) {
surface.makeBlindPanel(i * x + xOffset, y, w, h)
}
surface.makeBlindPanel(0.5, 0, 8, 5).setShapeRectangle() // Display
surface.makeBlindPanel(10.1, 0, 2.6, 2.6).setShapeCircle() // Data Dial
// Cursors
surface.makeBlindPanel(9.65, 2.8, 1.15, 2.2)
surface.makeBlindPanel(10.65, 2.8, 1.5, 1.15)
surface.makeBlindPanel(10.65, 3.85, 1.5, 1.15)
surface.makeBlindPanel(12, 2.8, 1.15, 2.2)
surface.makeBlindPanel(14.6, 2.8, 1.5, 0.8) // Time Div
surface.makeBlindPanel(14.6, 5.7, 1.5, 0.8) // Pad Bank
surface.makePianoKeys(7.5, 8.5, 29, 10, 0, 24) // Keyboard
return surfaceElements
}
var surfaceElements = makeSurfaceElements()
//-----------------------------------------------------------------------------
// 3. HOST MAPPING - create mapping pages and host bindings
//-----------------------------------------------------------------------------
var switches = surfaceElements.switcheStrip
var trasnports = surfaceElements.trasnport
var pads = surfaceElements.triggerPads
var knobs = surfaceElements.knobStrips
function makePage(name) {
var page = deviceDriver.mMapping.makePage(name)
page.makeActionBinding(switches[6].button.mSurfaceValue, page.mHostAccess.mTrackSelection.mAction.mPrevTrack)
page.makeActionBinding(switches[7].button.mSurfaceValue, page.mHostAccess.mTrackSelection.mAction.mNextTrack)
page.makeValueBinding(trasnports[0].button.mSurfaceValue, page.mHostAccess.mTransport.mValue.mStart)
page.makeValueBinding(trasnports[1].button.mSurfaceValue, page.mHostAccess.mTransport.mValue.mRecord)
page.makeValueBinding(trasnports[2].button.mSurfaceValue, page.mHostAccess.mTransport.mValue.mStop)
page.makeValueBinding(trasnports[3].button.mSurfaceValue, page.mHostAccess.mTransport.mValue.mCycleActive)
return page
}
function makePageSelectedTrack() {
var page = makePage('Selected Track')
var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel
for (var i = 0; i < 8; i++) {
page.makeValueBinding(knobs[i].knob.mSurfaceValue, selectedTrackChannel.mQuickControls.getByIndex(i)).setValueTakeOverModeScaled()
}
page.makeValueBinding(switches[0].button.mSurfaceValue, selectedTrackChannel.mValue.mMute).setTypeToggle()
page.makeValueBinding(switches[1].button.mSurfaceValue, selectedTrackChannel.mValue.mSolo).setTypeToggle()
page.makeValueBinding(switches[2].button.mSurfaceValue, selectedTrackChannel.mValue.mMonitorEnable).setTypeToggle()
page.makeValueBinding(switches[3].button.mSurfaceValue, selectedTrackChannel.mValue.mEditorOpen).setTypeToggle()
page.makeValueBinding(switches[4].button.mSurfaceValue, selectedTrackChannel.mValue.mInstrumentOpen).setTypeToggle()
return page
}
function makePageSelectedMixerChannel() {
var page = makePage('Mixer')
var selectedMixerChannel = page.mHostAccess.mTrackSelection.mMixerChannel
page.makeValueBinding(knobs[0].knob.mSurfaceValue, selectedMixerChannel.mValue.mVolume).setValueTakeOverModeScaled()
page.makeValueBinding(knobs[1].knob.mSurfaceValue, selectedMixerChannel.mValue.mPan).setValueTakeOverModeScaled()
page.makeValueBinding(knobs[2].knob.mSurfaceValue, selectedMixerChannel.mSends.getByIndex(0).mLevel).setValueTakeOverModeScaled()
page.makeValueBinding(knobs[3].knob.mSurfaceValue, selectedMixerChannel.mSends.getByIndex(1).mLevel).setValueTakeOverModeScaled()
page.makeValueBinding(knobs[4].knob.mSurfaceValue, selectedMixerChannel.mSends.getByIndex(2).mLevel).setValueTakeOverModeScaled()
page.makeValueBinding(switches[0].button.mSurfaceValue, selectedMixerChannel.mValue.mMute).setTypeToggle()
page.makeValueBinding(switches[1].button.mSurfaceValue, selectedMixerChannel.mValue.mSolo).setTypeToggle()
page.makeValueBinding(switches[2].button.mSurfaceValue, selectedMixerChannel.mSends.getByIndex(0).mOn).setTypeToggle()
page.makeValueBinding(switches[3].button.mSurfaceValue, selectedMixerChannel.mSends.getByIndex(1).mOn).setTypeToggle()
page.makeValueBinding(switches[4].button.mSurfaceValue, selectedMixerChannel.mSends.getByIndex(2).mOn).setTypeToggle()
return page
}
var selectedTrack = makePageSelectedTrack()
var selectedMixerChannel = makePageSelectedMixerChannel()
selectedTrack.makeActionBinding(switches[5].button.mSurfaceValue, selectedMixerChannel.mAction.mActivate)
selectedMixerChannel.makeActionBinding(switches[5].button.mSurfaceValue, selectedTrack.mAction.mActivate)
selectedTrack.mOnActivate = function (context) {
console.log('from script: AKAI Advance 25 "Selected Track" activated')
}
selectedMixerChannel.mOnActivate = function (context) {
console.log('from script: AKAI Advance 25 "selected Mixer Channel" activated')
}
Advance 25.zip (2.5 KB)