APH

14 bit Midi Messages

8 posts in this topic

HI, i posted about this topic over a year ago, but have only just got around to trying to implement what was discussed. I've built a standard midibox setup with only a 32 pot AIN board connected at present. We have some faders connected which currently send 7bit values to our software. I have read the article regarding the construction of the 7 bit data from the 10bit sample taken by the pic; as stated in the midi specification: http://www.midibox.org/dokuwiki/doku.php?id=midi_specification

We are looking to try and implement 14 bit midi messages so that we can attain a higher reolution on our faders. I understand that the Pic controller only samples to 10bit which is more than adequate and that we will have to interpolate the remaining bits from that.

My question is does anyone know of an application running on MIOS which has already implemented 14 bit midi messages?

I am currently trying to edit the application : ain64_din128_dout128 V2.1

specifically the section to do with sending the midi message when updating pot values.

MIOS_MIDI_BeginStream();

MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1

MIOS_MIDI_TxBufferPut(pin); // pin number corresponds to CC number

MIOS_MIDI_TxBufferPut(MIOS_AIN_Pin7bitGet(pin)); // don't send 10bit pin_value, but 7bit value

MIOS_MIDI_EndStream();

Could anyone give me guidance on how to alter this to transmit in 14 bit. I understand i need to shift the bits on my 10bit sample to obtain a MSB and LSB value but im unsure on how to construct the dual CC midi control message so that a piece of software like Traktor understands it correctly.

The specification states that to send 2 control messages it should be formatted like:

CC 12, Effect Ctrl 1 (MSB = Most Significant Byte)

CC 44, Effect Ctrl 1 (LSB = Least Significant Byte)

If anyone has any guidance on this it would be greatly apreciated.

Share this post


Link to post
Share on other sites


u16 value = MIOS_AIN_PinGet(pin);
u8 lsb = (value & 0x7f);
u8 msb = (value >> 7);

MIOS_MIDI_BeginStream();

MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1
MIOS_MIDI_TxBufferPut(12); // CC 12
MIOS_MIDI_TxBufferPut(lsb); // send lsb

MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1
MIOS_MIDI_TxBufferPut(44); // CC 44
MIOS_MIDI_TxBufferPut(lsb); // send msb

MIOS_MIDI_EndStream();[/code] That will send out the 10bits as 2 7bit messages. If you want to scale the value to the full 14bits you could change the first few lines to
[code]
u16 value = MIOS_AIN_PinGet(pin);
u8 lsb = (value << 4) & 0x7f;
u8 msb = (value >> 3);

Share this post


Link to post
Share on other sites

Excellent, Thats a spot on answer; i thankyou for the quick reply and usefull info. It would seem to work ok; i had to make this adjustment for it to compile, maybe different compiler? -


unsigned ADCvalue = MIOS_AIN_PinGet(pin);

 unsigned char lsb = ((ADCvalue << 4) & 0x7f);

 unsigned char msb = (ADCvalue >> 3);

However upon testing it would seem that the message doesnt perform as i intended. On a 7bit message the format is:

//  MIOS_MIDI_BeginStream();

//  MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1

//  MIOS_MIDI_TxBufferPut(pin);  // pin number corresponds to CC number

//  MIOS_MIDI_TxBufferPut(MIOS_AIN_Pin7bitGet(pin)); // don't send 10bit pin_value, but 7bit value

//  MIOS_MIDI_EndStream();

ie - start stream, [CC@ch1] - [Pin Number] - [ADCvalue] - close stream It would seem that in the example provided there is no pin number/CC number and therefore the software can't differentiate between any one of the inputs on the midibox. Is this a limitation of the midi protocol where we cant specify CC numbers in a 2x7bit control message or a lack of my understanding of how these messages should be constructed. If anyone has a example layout/spec for the midi comms that would be great. Maybe Would it be possible to put the cc number as the first 2 bits of the adc data to differentiate CCnumbers? Or is that not standard? Regards

u16 value = MIOS_AIN_PinGet(pin);

u8 lsb = (value & 0x7f);

u8 msb = (value >> 7);


MIOS_MIDI_BeginStream();


MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1

MIOS_MIDI_TxBufferPut(12);   // CC 12

MIOS_MIDI_TxBufferPut(lsb);  // send lsb


MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1

MIOS_MIDI_TxBufferPut(44);   // CC 44

MIOS_MIDI_TxBufferPut(lsb);  // send msb


MIOS_MIDI_EndStream();
That will send out the 10bits as 2 7bit messages. If you want to scale the value to the full 14bits you could change the first few lines to

u16 value = MIOS_AIN_PinGet(pin);

u8 lsb = (value << 4) & 0x7f;

u8 msb = (value >> 3);

Share this post


Link to post
Share on other sites

If you have a Host that expects FX Ctrl1, your only choice is to send the different pins on different channels.

MIOS_MIDI_TxBufferPut(0xb0); // CC at channel corresponging to AIN pin

Or use 3 messages, or use the remaining 4 bits in the 2 messages to put in upto 4 bits (max. 16 possibilities). That'll mean unpacking the messages at the host side though.

Share this post


Link to post
Share on other sites

OK, so the code is up and running, and from the looks of it for every movement two midi messages are generated. Im not entirely sure the scaling part accurately adjusts the value correctly but at the moment thats not my primary concern. In the mios studio software i can see the two messages being generated which look something like:

b0 12 LSB

b0 44 MSB

( both messages are generated for each movement of the POT/Fader)

However DJ mixing software such as mixx or Traktor, do not see the messages as a 2 part 14 bit message. Both seem to take the first message as coming from CC12 and not understanding that its a 2 part message. Therefore only interpreting the data as 7bit. The latest version of Traktor PRO supposidly has support for 14 bit midi devices so im left pondering. Is the data being correctly sent as a 14bit message? or do these programs not strictly adhere to the midi protocol, and therefore don understand that CC12 followed by CC44 is a 14 bit payload?

For those that maybe reading this thread, you may find this website of help:

http://www.midi.org/techspecs/midimessages.php

Its the Technical specification for what values represent in a midi data packet.

You'll see in table 2 "b0" refers to "Chan 1 Control/Mode Change " (you can choose any channel that you want)

Then refer to table 3: this byte represents the function of the control change. in our example "12" is "Effect Control 1" and "44" is "LSB for Control 12 (Effect control 1) "

If anyones worked with any of these programs and has some input i would greatly apreciate it.

Thanks. Ash

Share this post


Link to post
Share on other sites

Hey, you were the one who suggested using those two message ;)

Keyword: NRPN

Share this post


Link to post
Share on other sites

Hey, you were the one who suggested using those two message ;)

Keyword: NRPN

So from my understanding of NRPN; Would this implementation be correct?

MIOS_MIDI_BeginStream();

MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1

MIOS_MIDI_TxBufferPut(98); //

MIOS_MIDI_TxBufferPut(lsb); // send lsb

MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1

MIOS_MIDI_TxBufferPut(99); //

MIOS_MIDI_TxBufferPut(msb); // send msb

MIOS_MIDI_EndStream();

From testing this it would seem that all of my mixing software still just sees this as two individual 7 bit messages and doesnt combine them into one 14 bit one. Could anyone confirm that the above implementation is correct for NRPN, and thus this would lead me to believe that my mixing software doesnt support 14bit midi/compliant midi rules. Any guidance is duely apreciated.

Share this post


Link to post
Share on other sites

CC#98/99 selects the NRPN parameter, CC#26/6 sets the NRPN parameter.

You mixed this - In your code a NRPN parameter is selected based on msb/lsb value - which has to be send with CC#26 and CC#6

In other words (for the case that the MIDI spec is too difficult to understand): MIDI supports up to 16384 NRPN parameters with a value range of 0..16383. It requires 4 CCs to select and set the parameter.

Optimization measure #1: once a parameter has been set, you can change the value multiple times before another parameter is selected.

Optimization measure #2: you can leave out the status byte for the second, third and fourth CC thanks to the "running status" feature.

Detailed description: read MIDI spec again.

But if your DAW isn't already able to interpret CC#98/99 correctly, it seems that it doesn't support NRPN at all.

Did you already consider to contact the user support of the programs you are using?

This should not only give you a definitive answer, but should also awake a certain awareness that users are asking for this (very simple to implement) feature!

Best Regards, Thorsten.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now