Skip to content

Support NRPN? #154

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yaxu opened this issue Dec 3, 2019 · 12 comments
Closed

Support NRPN? #154

yaxu opened this issue Dec 3, 2019 · 12 comments

Comments

@yaxu
Copy link
Collaborator

yaxu commented Dec 3, 2019

NRPN is a way to send high resolution data over MIDI CC messages
https://www.elektronauts.com/t/nrpn-tutorial-how-to/46669

For example to change the x parameter on this alesis micron You send first send a two-byte controller identifier for it using CCs 99 and 98 99:0 98:44 (these being cc number, cc value pairs). You then send a two-byte value over CCs 44 (msb) and 38 (lsb), e.g. `44:6 38:4 = 128 * 6 + 4 = a value of 772.

The id and value is always sent over those four cc numbers. You might send the id once followed by a series of values in quick succession.

Here's an example of someone sending a value using supercollider:
https://sccode.org/1-57O

I tried this in tidal:
once $ cc "[99:0,98:44,6:0,38:9]" # s "midi"

Unfortunately the list comes through in a random order, so the sequence isn't set properly. This works:
once $ cc "[99:0 98:44 6:7 38:0] ~@10000" # s "midi"

But it would be great if it could be sent as a name:value pair with supercollider doing the work to break it into bytes for sending as CC:s. e.g.:

once $ nrpn "44*16" # val sine # s "midi"`
@yaxu
Copy link
Collaborator Author

yaxu commented Dec 4, 2019

I've had a go, but just can't fathom supercollider out at all. Despite a lot of moving things around, I just get lots of ERROR: Message 'asInteger' not understood.

@telephon
Copy link
Contributor

telephon commented Dec 5, 2019

Maybe some of the variables are nil? The MIDIOut tries to interpret the nils as integers, and fails (probably the thrower is posted further below in the error message).

@telephon
Copy link
Contributor

telephon commented Dec 5, 2019

Are you sure your midicmd is really nil? The whole initialisation of the variabls happens only if this is the case (line 44).

@yaxu
Copy link
Collaborator Author

yaxu commented Dec 5, 2019

Yes midicmd is nil. I think maybe the ~ variables are global and so aren't held in the function closure?

yaxu added a commit that referenced this issue Dec 5, 2019
@yaxu
Copy link
Collaborator Author

yaxu commented Dec 5, 2019

Yes that was it. Will test next time I'm with the synth

@yaxu
Copy link
Collaborator Author

yaxu commented Dec 11, 2019

I redid my changes, seems to work well now.

telephon added a commit that referenced this issue Dec 12, 2019
@yaxu
Copy link
Collaborator Author

yaxu commented Dec 19, 2019

This isn't working with negative values.

@yaxu yaxu reopened this Dec 19, 2019
@yaxu
Copy link
Collaborator Author

yaxu commented Dec 19, 2019

Any ideas what this should be, to support sending negative numbers?

					var nrpnMSB, nrpnLSB, valMSB, valLSB;
					~val = ~val ? 0;
					nrpnLSB = ~nrpn % 128;
					nrpnMSB = (~nrpn - nrpnLSB) / 128;
					valLSB  = ~val % 128;
					valMSB  = (~val - valLSB) / 128;
					schedmidi.value({
						midiout.control(chan, 99, nrpnMSB);
						midiout.control(chan, 98, nrpnLSB);
						midiout.control(chan, 6,  valMSB);
						midiout.control(chan, 38, valLSB)
					});

@yaxu
Copy link
Collaborator Author

yaxu commented Dec 19, 2019

The standard doesn't seem to permit negative numbers. http://www.somascape.org/midi/tech/spec.html#rpns

My synth demands them though. Hmm!

@bgold-cosmos
Copy link
Contributor

bgold-cosmos commented Dec 19, 2019

I think it's up to the MIDI device to interpret the 14 bits, usually they use 2's complement. So I think something along these lines will work for both positive and negative values:

var x = -129;
var lsb = (x % 128);
var msb = ((x-lsb) /128) % 128;

i.e. you don't need to change your LSB, and just take % 128 of the MSB

@yaxu
Copy link
Collaborator Author

yaxu commented Dec 19, 2019

That worked, thanks a lot @bgold-cosmos !

@johanwk
Copy link

johanwk commented Apr 19, 2022

Seems Tidal won't send value 0 for CC 38. The midi monitor shows that the following resends the last occurrence of CC 6 instead of CC 38 with value 0.

once $ ccn 38 # ccv 0 # s "midi"

This means that NRPN codes that require CC 38 = 0 won't work. I came across this trying to control the Elektron A4.

For example, this goes wrong, with nrpnv value 4096: once $ nrpnn 128 # nrpnv 4096 # s "midi" # midichan 8, returning

Channel	Value
9	99	1
9	98	0
9	6	32
9	6	32

while values that don't imply value 0 for CC 38 are fine; once $ nrpnn 128 # nrpnv 4097 # s "midi" # midichan 8 returns

Channel	Value
9	99	1
9	98	0
9	6	32
9	6	32
9	38	1

(but note that CC 6 is sent twice).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants