Matrix velocities

Hi everyone!

I currently have a matrix with three buttons (A, B, C) sending different notes but with the same velocity.

So I was wondering, how I could make sure that each buttons can have the entire velocity range going from 1 to 127 so in the end whenever I would tap at the bottom a button it would play a low velocity and as I'm sliding up it would play higher velocity.

Any ideas/solution to this?

Looking forward to your answers!

Swayrian

Buttons dont have a ranged velocity, you can't do what you describe this way, but it's possible to hack it using faders : fader_buttons.json (2.7 KB)

Thank you @jean-emmanuel !

I didn't understand what is the function of the touch state you wrote on props.script.
Could you please explain it in simple words or a little session showing how is it working practically speaking?
Is it supposed to do the following?

send('midi:whatever', '/address', channel #, note #, velocity #)

Because I couldn't send any address with what you wrote what I did instead was the following
(widgetType of the matrix being faders this time):

JS{{

var props = {}
var labels = 'ABCD'

props.snap = true
props.html = labels[$]
props.target = "midi:whatever"

props.range = {min:0, max:127}
props.address = "/note"
props.preArgs = [1, $+36]

return props
}}

With this one, the velocity part is working perfectly and I can send the address.

However, now I don't know how can I get a note off once a note is triggered.
I would like the mode to be similar to a button which would be set to tap.
I was thinking of adding props.off = 0 to make that happen but I suppose it's not working with faders?

On the side of that, I've set traversing to true so how can I hack the CSS of the faders to behave as if I would use props.mode = "push" ?
Since the widgets are now faders this is not working but maybe there is a way to hack that directly into the props?

Swayrian

In the example I uploaded, you only need to remove the "//" before "send()" and replace "whatever" with the actual midi devices you defined in your config to make it work.

The touch state is documented here. The script executes only when the fader is touched or released, which is what we want to turn a fader into a button. snap is set to true so that the fader jumps to the touched value directly. The send() call is wrapped in a setTimeout() function to delay it just a tiny bit to ensure we get the fader's new value and not the previous one (the touch state event occurs before the value changes).

My bad, sometimes things are easier than what I'm thinking.
Now I understand how it works - Thanks a lot @jean-emmanuel, you're super helpful !

Now the real fun begins :partying_face:

Swayrian

Hi @jean-emmanuel my brain just hit another wall... :grimacing:

I created a new matrix from the session you sent featuring a simple major scale as:
C-D-E-F-G-A-B-C

The issue I encounter now is when I'm using #{$}+60 on send() the notes are going chromatically as:
C-C#-D-D#-E-F-F#-G

I found #{$}+60+1 but that's simply shifting to the next note.
So how to turn the note value of let's say C# directly into D which should be #{$}+62 ?

Loving matrix these days, so many possibilities with it!

Swayrian

hi

an array to store the gap between the present note and the next ?
for a major scale
2 2 1 2 2 2 1

You don't need to write #{$}, $ is enough since you're already in a JS{} block.

var scale = [0, 2, 4, 5, 7, 9, 11]
var note = 60 + scale[$ % scale.length] 
// 8 % 8 = 0, 9 % 8 = 1 -> loop over scale
var octave = 12 * Math.floor($ / scale.length)
note = note + octave
// now use note instead of $
1 Like

It's strange because I'm getting some errors:

Am I doing anything wrong or something is missing?

JS{
var props = {}
var labels = 'CDEFGAB'

var scale = [0, 2, 4, 5, 7, 9, 11]
var note = 60 + scale[$ % scale.length]

var octave = 12 * Math.floor($ / scale.length)
note = note + octave

props.snap = true
props.range = {min:0, max:127}
props.html = labels[$]

props.script = if (touch !== undefined) { setTimeout(()=>{ var v = touch == 1 ? get('this') : 0 console.log(v) send('midi:whatever', '/note', 1, $, v) }) }

return props
}

Swayrian

Really sorry to bother you about this @jean-emmanuel but I think something is not working anymore.

I went back to your initial props to try it again and followed what you said:
I removed // before send() also changed whatever to my config but I'm getting errors:

Here is the initial props you wrote which should normally be working but it is not functioning on my side:

JS{
var props = {}
var labels = 'ABCDEFG'

props.snap = true
props.range = {min:0, max:127}
props.html = labels[$]

props.script = if (touch !== undefined) { setTimeout(()=>{ var v = touch == 1 ? get('this') : 0 console.log(v) send('midi:whatever', '/control', 1, $, v) }) }

return props
}

However when I'm replacing

$

to

#{$}+'note value'

It is working.
But you said I don't need to write this way as I'm already in a JS{} block
So what is wrong?

Because of that, I can't go on to work on the additional var you wrote:

var scale = [0, 2, 4, 5, 7, 9, 11]
var note = 60 + scale[$ % scale.length] 
// 8 % 8 = 0, 9 % 8 = 1 -> loop over scale
var octave = 12 * Math.floor($ / scale.length)
note = note + octave
// now use note instead of $

Here is the session with everything included if you could please have a look at it:
fader_buttons_test_2.json (2.8 KB)

@Greenman Thanks for your suggestion but the array also didn't work for me.

Sorry for my huge incompetence :grimacing:

Swayrian

Here is the correct code (explanation below):


JS{
var props = {}
var labels = 'CDEFGAB'
var scale = [0, 2, 4, 5, 7, 9, 11]
var note = 60 + scale[$ % scale.length] 
var octave = 12 * Math.floor($ / scale.length)

note = note + octave

props.snap = true
props.range = {min:0, max:127}
props.html = labels[$]

props.script = `
if (touch !== undefined) {
  setTimeout(()=>{
    var v = touch == 1 ? get('this') : 0
    send('midi:whatever', '/note', 1,` + note + `, v)
  })
}
`

return props
}

With the syntax coloration you can see how props.script is a just string and not an actual script (until the fader is created and uses it). $ didn't work because the code in props.script is not executed in the same context as the one in JS{}. Writing #{$} worked in the JS{} block because it was replaced with its value before the JS{} block was executed (a bit tricky, yes).

1 Like

Thanks a lot @jean-emmanuel :pray:

That wasn't an easy guess, I almost got it right by replacing $ by note but the quotation I made was totally out of my mind :sweat_smile:

Hi @jean-emmanuel !

I'm getting back to the matrix, and wondered how I could turn the "tricked-CSS-buttons" into traversing ?

  • Swayrian

I don't understand your question, can you reformulate ?

Sorry I should have explained further what I had in mind.

In the session you sent:

The faders are turned as if they were buttons thanks to what is written on the CSS property, that's great.

Now if you click and hold the buttons for instance going from A to D the problem is that you don't see visually the boxes going from A to D, you only see the "fader_button" A being pushed.

So to fix that, I thought something has to be added in the CSS field ?

Normally, if the widgetType of the matrix were normal buttons you would simply set the traversing property to true.

Hope that makes more sense ?

Swayrian