We have published the Qu MIDI Protocol specs on the product page.
‘Qu transmits MIDI messages when its controls are operated. It also responds to parameter changes it receives via MIDI, for example from a computer, Qu-Pad or an external MIDI controller.’
First, thank you for posting this. I was able to figure out how to midi control my QU-SB because this document exists.
So, please don’t take it personally when I say - could you have at least gone to the trouble of converting the hex values? This is one of the most unfriendly midi spec sheets I’ve come across in ages!
The MIDI protocol specs are essential and effectively was the deciding factor on picking up a QU-SB mixer for me. I was originally on the fence as it seems risky to me to invest in a system that can only be controlled via iPad. You never know how long a company will continue app support and development, especially with pro audio gear as the amount of support largely depends on adoption rates. However, I am also a software developer and open sourcing control protocols means I can always develop my own control software should the app be abandoned.
With all that said I have basically been able to get everything working via the provided MIDI protocols. However, I have run into difficulty with the Sysex protocol. So my question is does the QU-SB send meter data over USB MIDI or only with network (TCP) MIDI? Because I’ve tried polling for the meter data and running the Sysex All Call over USB MIDI and I receive no reply from the console. All the other controls and buttons return MIDI messages as expected.
I have a Qu-SB with 1.94 firmware that I’ve been able to successfully connect to via TCP. Once connected, I receive a stream of active sense 0xFE bytes from the mixer, as expected. I’ve also sent the sysex all-call message to receive a stream of NRPNs, which I am also receiving.
However, the TCP connection is always dropped by the mixer after 12 seconds. According to the v1.9 PDF documentation (which by the way is missing info about the Qu-SB):
Qu also responds to Active Sense If it receives an Active Sense byte it will expect to receive
regular MIDI data from that point onwards (either valid control data, or more Active Sense bytes
during any period of inactivity). If it does not receive any data for 12 seconds, it will close the
Ethernet connection
So it appears that all I have to do is send something back - an activeSense command, anything. So I send an activeSense, and the connection is closed after 12 seconds anyway. So I send one activeSense per second, and the connection is closed after 12 seconds. No matter how I respond, the connection is closed after 12 seconds.
I’ve had a play with this myself and found that if you set the iPad flag to 00 rather than 01, this stops the requirement for an Active Sense Byte response.
If you would like to keep the active sensing, you will need to send an Active Sense Byte every 300ms.
Thanks so much for the response. I’m curious about the iPad flag byte: you wrote “00 rather than 01”, but the PDF shows 10 instead of 01:
REQUEST: Sysex Header (All Call), 10 , F7
So that line can be read a couple different ways:
10 is the iPad flag, make it 00 to disable it
10 is the byte precedeing the iPad flag (though there’s no comma)
10 OR’d with the iPad flag makes it 11 if you want the iPad flag enabled
So I’ve tried sending ‘sysex-header, 10, F7’ and I get the NRPN messages (which I desire, btw), and that’s when the connection is dropped after 12 seconds. I’ve tried sending ‘sysex-header, 00, F7’, which I think is what you’re suggesting, but I no longer get the NRPN messages (that I want). So unfortunately, I think I must have the iPad flag enabled, otherwise I’ll never get the NRPN responses.
What a difference one little byte makes. I added 0x00 between the 0x10 and 0xF7 and viola - I got all the NRPN data and the comm link stayed up. Lifesaver!
So I’m parsing the bulk SysEx and NRPN data coming back, and I’ve run into an obstacle that I’d like some confirmation. Here is a snippet of the data stream that comes back after the sysex all-call request (newlines added by me for clarity):
As the NRPN and sysex packets started streaming in, I also started receiving interleaved NRPN and sysex messages, no big deal. But the big deal is the sysex packet would often arrive in the middle of an incomplete NRPN packet, then the remainder of the NRPN packet would arrive (and sometimes with activesense in there too, as shown).
I can learn how to deal with this, but I wanted to confirm that this is normal behavior and not some “hey, upgrade to the latest fw to fix it” kind of thing. Being lazy, updating firmware is easier than compensating for separated packets :-).
Thanks for the help. It will be a while before I get any answers - a power outage blew my UPS, motherboard, and boot disk, which contained the source code. Fortunately, 99% of the source code is in git in the cloud, but that last 1% was hard-fought work.
Apologies for the lengthy delay on your firmware update request. A power outage took out most of my dev computer’s RAM, and unfortunately, the system drive which also had my code on it (most is committed to bitbucket). But unfortunately, the last bit of code not committed was the code that was parsing the sysex/nrpn data. So after a big delay and expense to recover my code, I’m back up and running. Update…
I checked and verified that I was running v1.94.4557, so I updated to v1.95.4561, which on the website is the latest version. I don’t think the update made much of a difference. I dug deeper into the sysex/nrpn data coming back, and found a fairly consistent anomaly - in the middle of the nrpn dump, I would get this chunk of data, which of course is throwing off my parsing algorithms:
0xd 0xa 0x20 0x65 0x74 0x73 0x20 0x4a 0x61 0x6e 0x20 0x20 0x38 0x20 0x32 0x30 0x31 0x33 0x2c 0x72 0x73 0x74 0x20 0x63 0x61 0x75 0x73 0x65 0x3a 0x31 0x2c 0x20
CR LF e t s J a n 8 2 0 1 , r s t c a u s e : 1 ,
0x62 0x6f 0x6f 0x74 0x20 0x6d 0x6f 0x64 0x65 0x3a 0x28 0x33 0x2c 0x37 0x29
b o o t m o d e : ( 3 , 7 )
0xd 0xa 0xd 0xa 0x6c 0x6f 0x61 0x64 0x20
CR LF CR LF l o a d
0x30 0x78 0x34 0x30 0x31 0x30 0x30 0x30 0x30 0x30 0x2c 0x20 0x6c 0x65 0x6e 0x20 0x31 0x33 0x39 0x36
0 x 4 0 1 0 0 0 0 0 , l e n 1 3 9 6
I’m receiving only the hex values, but here I’m showing their ascii equivalents. Does this data make any sense to you? Ever had this happen before?
Full disclosure, I’m coding this TCP driver on an Espruino WiFi microcontroller (Espruino WiFi), and of course I could be causing data loss/corruption on my end, but it’s just not obvious to me where the problem lies yet. Any thoughts on this are greatly appreciated. Thanks!
I can do that, but first I’ve found some issues with my buffer handling that I need to address first. I’d like to convince myself that I have no bugs on my end before I lodge an issue.