User Tools

Site Tools


prime2

This is an old revision of the document!


dnttalo.cluster029.hosting.ovh.net_pictures_p2toakf.jpg

I think the best / easier usage with force is to use prime2 or primeGo. Below i will explain / provide a template for Prime2.

Prime use QML from QT to do assignments and map functions. You can write your own javascript / qml code to suit your needs. I'm not a QT expert, i'm still learning :p

Import section to get all the QT/QML prime objects

import airAssignments 1.0
import ControlSurfaceModules 0.1
import InputAssignment 0.1
import OutputAssignment 0.1
import Planck 1.0
import QtQuick 2.12

Then Assignments begin

MidiAssignment {
	objectName: 'PRIME 2 Controller Assignment'

	Utility {
		id: util
	}

	GlobalAssignmentConfig {
		id: globalConfig
		midiChannel: 0
	}

	GlobalAction {
		id: globalAction
	}

	Back {
		note: 67
		ledType: LedType.Simple
	}

	Forward {
		//note: 115
		shiftAction: Action.Quantize
		ledType: LedType.Simple
	}

Back& Forward are mapped like this : dnttalo.cluster029.hosting.ovh.net_pictures_backforward.jpg

	BrowseEncoder {
		pushNote: 111
		turnCC: 100
		ledType: LedType.Simple
	}

	View {
		note: 0
		holdAction: Action.ToggleControlCenter
		shiftAction: Action.SwitchMainViewLayout
		ledType: LedType.Simple
	}

	Shift {
		note: 49
		ledType: LedType.Simple
	}

	Media {
		mediaButtonsModel: ListModel {
			ListElement {
				name: 'Eject'
				shiftName: 'Source'
				note: 20
				hasLed: true
			}
		}
	}

	Mixer {
		cueMixCC: 12
		cueGainCC: 13
		crossfaderCC: 32
	}

	MicSettings {}

	Mics {
		mic1Note: 36
		mic2Note: 37
		mic1ShiftAction: Action.ToggleMicTalkover
	}

Then we create one repeater bloc for deck1 and further, another for deck2

DeckMidiChannel is 9 on the force when you press the sensitive pads in the middle.

dnttalo.cluster029.hosting.ovh.net_pictures_akaifpadchannel.jpg

that's why i use deckMidiChannel: 9 , which will be assigned to my whole repeater bloc section

	Repeater {
		model: ListModel {
			ListElement {
				deckName: 'Left'
				deckMidiChannel: 9
				loadNote: 123
			}
		}

		Item {
			DeckAssignmentConfig {
				id: deckConfig
				name: model.deckName
				midiChannel: model.deckMidiChannel
			}

			DeckAction {
				id: deckAction
			}

			Bank {}

			Load {
				note: model.loadNote
				ledType: LedType.Simple
			}


			PerformanceModes {
				ledType: LedType.RGB
				modesModel: ListModel {
					ListElement {
						note: 78
						view: 'CUES'
					}
					ListElement {

						note: 79
						view: 'LOOPS'
						altView: 'AUTO'
					}
					ListElement {
						note: 80
						view: 'ROLL'
					}
					ListElement {				
					note: 81
					view: "SLICER"
					altView: "FIXED"
				}
									
				}
			}

Here In PerformanceModes section , we define where we want the function pad assignment. I've done it on note 78,79,80,81 for deck 1

By using LedType.RGB option, I suspect Engine send a sendcolor function through the Device Assignement file . However this property is not assignable to each functions.

dnttalo.cluster029.hosting.ovh.net_pictures_akf_funcktionpaddeck1.jpg

The we defined ActionPads , they are for the pads when you will press one of the pad upper :

  1. Press 78 you'll have CUES mode
  2. Press 79 you'll have LOOPS mode
  3. Press 80 you'll have AUTOLOOPS mode
  4. Press 81 you'll have SLICER mode
			ActionPads {
				firstPadNote: 70
				ledType: LedType.RGB
			}

As prime 2 has 8 pads, when putting 70, it will assign pads from 70 to 77 ( 70, 70+1 , 70+2 ,70+3, etc… to 70+7) (0 to 7 = 8 pads )

dnttalo.cluster029.hosting.ovh.net_pictures_akf_functionpads2_deck1.jpg

As an exemple, when you'll press the pad for the cue ( pad number 78 ) . it will send a Sysex message to the pad via sendcolor function, defined in the Device Assignment File. And then you'll have all the cue for this track

dnttalo.cluster029.hosting.ovh.net_pictures_akf_deck1_cuemapping.jpg

You can trigger you cue, by pushing the colored pad , create new on the no colored one or remove them by press shift of the AKF + your colored pad. Shift button has been mapped upper with Shift keyword ( see upper ) to note 49, which is the midi note that shift button send on AKF.

It will work the same for loops (press key 79 ) , quick auto loops (key 80) , and slicer (key 81 ) Below some pics of these functions.

Cues dnttalo.cluster029.hosting.ovh.net_pictures_akf_cues.jpg Loops dnttalo.cluster029.hosting.ovh.net_pictures_akf_loops.jpg

** Slicer dnttalo.cluster029.hosting.ovh.net_pictures_akf_slice1.jpg dnttalo.cluster029.hosting.ovh.net_pictures_akf_slice2.jpg

			Sync {
				syncNote: 83
				syncHoldAction: Action.KeySync
			}

			PlayCue {
				cueNote: 37
				cueShiftAction: Action.SetCuePoint
				playNote: 82
	
			}

			PitchBend {
				minusNote: 29
				plusNote: 30
			}

			JogWheel {
				touchNote: 33
				ccUpper: 0x37
				ccLower: 0x4D
				jogSensitivity: 1638.7 * 10.08
				hasTrackSearch: true
			}

			Vinyl {
				note: 35
				holdAction: Action.GridCueEdit
			}

			AutoLoop {
				pushNote: 116
				turnCC: 16
				loopInactiveShiftTurnAction: Action.BeatJump
				ledType: LedType.Simple
			}

			SpeedSlider {
				ccUpper: 0x1F
				ccLower: 0x4B
				invert: true
			}
			
		
		}
	}

Same thing for deck Right

 


Repeater {
		model: ListModel {
			ListElement {
				deckName: 'Right'
				deckMidiChannel: 9
				loadNote: 124
			}
		}

		Item {
			DeckAssignmentConfig {
				id: deckConfig
				name: model.deckName
				midiChannel: model.deckMidiChannel
			}

			DeckAction {
				id: deckAction
			}

			Bank {}

			Load {
				note: model.loadNote
				ledType: LedType.Simple
			}

			PerformanceModes {
				ledType: LedType.RGB
				modesModel: ListModel {
					ListElement {
						note: 110
						view: 'CUES'
					}
					ListElement {
						note: 111
						view: 'LOOPS'
						altView: 'AUTO'
					}
					ListElement {
						note: 112
						view: 'ROLL'
					}
					ListElement {					
					note: 113
					view: "SLICER"
					altView: "FIXED"
				}
				}
			}

			ActionPads {
				firstPadNote: 102
				ledType: LedType.RGB
			}

			Sync {
				syncNote: 115
				syncHoldAction: Action.KeySync
			}

			PlayCue {
				cueNote: 9
				cueShiftAction: Action.SetCuePoint
				playNote: 114
			}

			PitchBend {
				minusNote: 29
				plusNote: 30
			}

			JogWheel {
				touchNote: 33
				ccUpper: 0x37
				ccLower: 0x4D
				jogSensitivity: 1638.7 * 10.08
				hasTrackSearch: true
			}

			Vinyl {
				note: 35
				holdAction: Action.GridCueEdit
			}

			AutoLoop {
				pushNote: 56
				turnCC: 23
				loopInactiveShiftTurnAction: Action.BeatJump
				ledType: LedType.Simple
			}

			SpeedSlider {
				ccUpper: 0x1F
				ccLower: 0x4B
				invert: true
			}
		}
	}

Next I configure Filter Sweep button for the 2 decks like below, and parameters button used to change note repeat speed in slice mode.

dnttalo.cluster029.hosting.ovh.net_pictures_filtersweep.jpg

Repeater {
		model: ListModel {
			ListElement {
				deckName: "Left"
				deckMidiChannel: 0
			}
			
			ListElement {
				deckName: "Right"
				deckMidiChannel: 0
			}
			
			
		}

		Item {
			id: deckmixer
			
// Internal properties for Deck 1 


			readonly property QObjProperty padsView1: Planck.getProperty("/Engine/Deck%1/Pads/View".arg(1))
			
			property string padsMode1: padsView1.translator.string
			
			readonly property bool padsModeIsAutoLoop1: padsMode1 === "AUTO"
			readonly property bool padsModeIsLoop1: padsMode1 === "LOOPS"
			readonly property bool padsModeIsLoopRoll1: padsMode1 === "ROLL"
			readonly property bool padsModeIsSlicerContinuous1: padsMode1 === "SLICER"
			readonly property bool padsModeIsSlicer1: padsModeIsSlicerContinuous1 || padsMode1 === "FIXED"
			
			readonly property bool loopEnabled1: Planck.getProperty("/Engine/Deck%1/Track/LoopEnableState".arg(1)).translator.state
			readonly property bool loopEditable1: Planck.getProperty("/Engine/Deck%1/Track/LoopEnableState".arg(1)).translator.editable
			

// Internal properties for Deck 2			
			
			
			readonly property QObjProperty padsView2: Planck.getProperty("/Engine/Deck%1/Pads/View".arg(2))
			
			property string padsMode2: padsView2.translator.string
			
			readonly property bool padsModeIsAutoLoop2: padsMode2 === "AUTO"
			readonly property bool padsModeIsLoop2: padsMode2 === "LOOPS"
			readonly property bool padsModeIsLoopRoll2: padsMode2 === "ROLL"
			readonly property bool padsModeIsSlicerContinuous2: padsMode2 === "SLICER"
			readonly property bool padsModeIsSlicer2: padsModeIsSlicerContinuous2 || padsMode2 === "FIXED"
			
			readonly property bool loopEnabled2: Planck.getProperty("/Engine/Deck%1/Track/LoopEnableState".arg(2)).translator.state
			readonly property bool loopEditable2: Planck.getProperty("/Engine/Deck%1/Track/LoopEnableState".arg(2)).translator.editable


			
// Sweep Filter for Deck 1 

ValueCCAssignment {
				objectName: "Dual Filter Cutoff Deck%1".arg(1)
				cc: 16
				channel: deckMidiChannel
				
						output: JogOutput {
							jogAcceleration: 1.5;
							jogSensitivity: 0.5;
							type: 0
							target: PropertyTarget { path: "/Engine/Mixer/Channel%1/SweepFx/Value".arg(1) }					
						}
				
			}



// Sweep Filter for deck 2 

ValueCCAssignment {
				objectName: "Dual Filter Cutoff Deck%1".arg(2)
				cc: 23
				channel: deckMidiChannel
								

						output: JogOutput {
							jogAcceleration: 1.5;
							jogSensitivity: 0.5;
							type: 0
							target: PropertyTarget { path: "/Engine/Mixer/Channel%1/SweepFx/Value".arg(2) }
						
							
						}
		
			}

Then we will map FX section / Buttons.








     ///////////////////////////////////////////////////////////////////////////
	// Effect Controls
	 Repeater {
		model: ListModel {
			ListElement {
				deckName: "Left"
				deckMidiChannel: 0
			}

			ListElement {
				deckName: "Right"
				deckMidiChannel: 1
			}
		}

		Item {
			id: deckFx
			
			ValueNoteAssignment {
				objectName: "FX%1 Active Button".arg(1)
				note: 93
				channel: deckMidiChannel
				enabled: !device.shift
				output: ActionOutput {
					target: PropertyTarget {
						path: "/Engine/Mixer/Channel%1/DJFx/Active".arg(1)
					}
				}
			}
			
			ValueNoteAssignment {
				objectName: "FX%1 Active Button".arg(2)
				note: 05
				channel: deckMidiChannel
				enabled: !device.shift
				output: ActionOutput {
					target: PropertyTarget {
						path: "/Engine/Mixer/Channel%1/DJFx/Active".arg(2)
					}
				}
			}
			

			
			
				ValueCCAssignment {
				objectName: "FX%1 Selection".arg(1)
				cc: 17
				channel: deckMidiChannel

				enabled: Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/Selecting".arg(1)).translator.state
				output: QtObject {
					readonly property QObjProperty pSelectionIndex: Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/PreselectIndex".arg(1))
					function setValue(channel, value, assignmentEnabled) {
						if(assignmentEnabled) {
							if(value > 0.5) { // turn counter clockwise, value normalized
								pSelectionIndex.translator.unnormalized = pSelectionIndex.translator.unnormalized - 1
							}
							else {
								pSelectionIndex.translator.unnormalized = pSelectionIndex.translator.unnormalized + 1
							}
						}
					}
				}
			}
				
						
			ValueCCAssignment {
				objectName: "FX%1 Selecting".arg(1)
				cc: 17
				channel: deckMidiChannel
				enabled: !Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/Selecting".arg(1)).translator.state
				output: ActionOutput {
					behaviour: force.action
					target: PropertyTarget {
						path: "/Engine/Mixer/Channel%1/DJFx/Selecting".arg(1)
					}
				}
			}
			
			ValueCCAssignment {
				objectName: "FX%1 Selection".arg(2)
				cc: 20
				channel: deckMidiChannel

				enabled: Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/Selecting".arg(2)).translator.state
				output: QtObject {
					readonly property QObjProperty pSelectionIndex: Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/PreselectIndex".arg(2))
					function setValue(channel, value, assignmentEnabled) {
						if(assignmentEnabled) {
							if(value > 0.5) { // turn counter clockwise, value normalized
								pSelectionIndex.translator.unnormalized = pSelectionIndex.translator.unnormalized - 1
							}
							else {
								pSelectionIndex.translator.unnormalized = pSelectionIndex.translator.unnormalized + 1
							}
						}
					}
				}
			}
				
						
			ValueCCAssignment {
				objectName: "FX%1 Selecting".arg(2)
				cc: 20
				channel: deckMidiChannel
				enabled: !Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/Selecting".arg(2)).translator.state
				output: ActionOutput {
					behaviour: force.action
					target: PropertyTarget {
						path: "/Engine/Mixer/Channel%1/DJFx/Selecting".arg(2)
					}
				}
			}
			
			
	


//			ValueCCAssignment {
//				objectName: "FX%1 Rate".arg(1)
//				cc: 100
//				channel: deckMidiChannel
//				enabled: Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/Knob2Target".arg(1)).translator.string === "Rate"
//				output: QtObject {
//					readonly property QObjProperty pTarget: Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/Rate".arg(1))
//					function setValue(channel, value, assignmentEnabled) {
//						if(assignmentEnabled) {
//							var counterClock = value > 0.5
//							var changeIndex = counterClock ? -1 : 1
//							pTarget.translator.index = pTarget.translator.index + changeIndex
//						}
//					}
//				}
//			}

			ValueCCAssignment {
				objectName: "FX%1 Amount".arg(1)
				cc: 18
				channel: deckMidiChannel
				enabled: Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/Knob2Target".arg(1)).translator.string === "Amount"
				output: EndlessKnobOutput {
					smallestIncrement: 0.01
					biggestIncrement: 0.1
					target: PropertyTarget { path: "/Engine/Mixer/Channel%1/DJFx/Amount".arg(1) }
				}
			}	
				
			ValueCCAssignment {
				objectName: "FX%1 Amount".arg(2)
				cc: 21
				channel: deckMidiChannel
				enabled: Planck.getProperty("/Engine/Mixer/Channel%1/DJFx/Knob2Target".arg(2)).translator.string === "Amount"
				output: EndlessKnobOutput {
					smallestIncrement: 0.01
					biggestIncrement: 0.1
					target: PropertyTarget { path: "/Engine/Mixer/Channel%1/DJFx/Amount".arg(2) }
				}
			}		
				
				
			ValueCCAssignment {
				objectName: "FX%1 Mix".arg(1)
				cc: 19
				channel: deckMidiChannel
				output: ValueOutput {
					target: PropertyTarget {
						path: "/Engine/Mixer/Channel%1/DJFx/Mix".arg(1)
					}
				}
			}


			ValueCCAssignment {
				objectName: "FX%1 Mix".arg(2)
				cc: 22
				channel: deckMidiChannel
				output: ValueOutput {
					target: PropertyTarget {
						path: "/Engine/Mixer/Channel%1/DJFx/Mix".arg(2)
					}
				}
			}	
							

		}
	}	




/*
	FxAssignmentConfig {
		id: fxConfig
		midiChannel: 0
		channelNames: ['1', '2']
	}

	DJFxSelect {
		pushNote: 53
		touchNote: 91
		turnCC: 17
	}

	DJFxTime {
		pushNote: 8
		turnCC: 18
	}

	DJFxWetDry {
		cc: 19
	}

	DJFxActivate {
		fxActivateType: FxActivateType.Button
		activateControlsModel: ListModel {
			ListElement {
				midiChannel: 0
				note: 93
				
			}
			ListElement {
				midiChannel: 0
				note: 92
			}
			
			
			
		}
	}


	

	DJFxAssign {
	
		notes: [94, 95]
	}
		
*/
}
prime2.1701031778.txt.gz · Last modified: 2023/11/26 21:49 by ounsatn

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki