View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0008117 | ardour | bugs | public | 2020-05-15 20:22 | 2020-05-15 20:50 |
Reporter | gwyndaf | Assigned To | |||
Priority | normal | Severity | minor | Reproducibility | always |
Status | new | Resolution | open | ||
Platform | Linux Mint Debian Edition 4 | OS | Debian | OS Version | 10/Buster |
Product Version | 5.12 | ||||
Summary | 0008117: Unexpected response to Midi Machine Control (MMC) from control surface: track arm/mute/solo | ||||
Description | 1. Pressing controller button for Arm (record ready) on each of tracks 1-9 activates Record control on corresponding Ardour track, as expected. Pressing button on track 10 arms track 11 in Ardour, skipping track 10. Same behaviour with tracks 18 and 26, i.e. skipping every 8th track. 2. Pressing Mute button for any track has no effect in Ardour 3. Pressing Solo buttons for any track has no effect in Ardour (possible feature request, as I think this isn't supported, and may be non-standard MMC) 4. No MMC output from Ardour in response to any of the above track controls being pressed. For 1-3, MIDI Tracer (on MMC in) reports "MMC command 41" for all controls across all tracks; for 3 also "[WARNING]: MIDI::MachineControl: masked write to 66 not implemented" in error messages. 4 produces no MIDI Tracer output (on MMC out) | ||||
Steps To Reproduce | I've tried 3 ways (all with JACK and ALSA-MIDI bridge running). Have at least 12 audio tracks in Ardour (I used 32 to suit my controller) A. Hardware controller (Tascam US428 or US224) Connect and make sure us428control is running (manually if not started automatically). Connect us428control midi out to Ardour MMC in Press Record, Mute, Solo for each track in turn, using bank shift to access higher tracks. B. Virtual controller (QmidiCtl on Android device, connecting to QmidiNet on Linux) Connect QmidiNet MIDI out to Ardour MMC in Press Record, Mute, Solo for each track in turn, using bank shift to access higher tracks. C. Translate keyboard notes into MMC codes Run the attached mididings script: 'python midi_notes-mmc.py' to create MMC-Translate device (which translates) Connect MMC-Translate input to keyboard and output to Ardour MMC in Note 24-35 (octave up from C) send Record Ready on for tracks 1-12; notes 36-47 send Record Ready off for tracks 1-12 (masked write 4f) Note 48-59 (octave up from C) send Mute on for tracks 1-12; notes 60-71 send Mute off for tracks 1-12 (masked write 62) Note 72-83 (octave up from C) send Solo on for tracks 1-12; notes 84-95 send Record Ready off for tracks 1-12 (masked write 66) | ||||
Additional Information | I think the cause of 1. might lie in libs/midi++2/mmc.cc (lines 555-559). These seem to calculate track numbers for arming from a base track that's a multiple of 8 when translating the MIDI bitmap. I think MIDI uses only 7 data bits in each byte, so the 8th bit is ignored. The attached ods gives my calculations of converting the MMC code into visible bits, and it seems the 'track skip' is built into how the bits are used. I'm not a great C++ coder, but wonder if a possible fix might be to replace all of lines 555-559 with: base_track = (msg[0] * 7) - 5 (so the 8th bit of each byte doesn't get taken to signify a track number). I don't think I'm up to testing this out and compiling something on the scale of Ardour, but happy to help with testing. | ||||
Tags | control, Midi | ||||
|
midi_notes-mmc.py (5,122 bytes)
from mididings import * config( client_name='MMC-Translate', in_ports=[('MIDI-note-CC-in')], out_ports=[('MMC-out')], ) run( ####### MPK Midi to MMC ######## ( Filter(CTRL) >> CtrlSplit({ # Play 4: SysEx('\xf0\x7f\x7f\x06\x02\xf7'), # Stop 3: SysEx('\xf0\x7f\x7f\x06\x01\xf7'), # Rew 1: SysEx('\xf0\x7f\x7f\x06\x05\xf7'), # Fwd 2: SysEx('\xf0\x7f\x7f\x06\x04\xf7') }) ) // ( Filter(NOTE) >> KeySplit ({ # 24-35 octave sends MMC RecArm (0x4f) ON 24: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x00\x20\x20\xf7'), 25: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x00\x40\x40\xf7'), 26: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x01\x01\xf7'), 27: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x02\x02\xf7'), 28: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x04\x04\xf7'), 29: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x08\x08\xf7'), 30: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x10\x10\xf7'), 31: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x20\x20\xf7'), 32: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x40\x40\xf7'), 33: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x02\x01\x01\xf7'), 34: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x02\x02\x02\xf7'), 35: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x02\x04\x04\xf7'), # 24-35 octave sends MMC RecArm (0x4f) OFF 36: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x00\x20\x00\xf7'), 37: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x00\x40\x00\xf7'), 38: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x01\x00\xf7'), 39: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x02\x00\xf7'), 40: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x04\x00\xf7'), 41: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x08\x00\xf7'), 42: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x10\x00\xf7'), 43: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x20\x00\xf7'), 44: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x01\x40\x00\xf7'), 45: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x02\x01\x00\xf7'), 46: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x02\x02\x00\xf7'), 47: SysEx('\xf0\x7f\x7f\x06\x41\x04\x4f\x02\x04\x00\xf7'), # 48-59 keys send MMC Mute (0x62) ON 48: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x00\x20\x20\xf7'), 49: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x00\x40\x40\xf7'), 50: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x01\x01\xf7'), 51: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x02\x02\xf7'), 52: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x04\x04\xf7'), 53: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x08\x08\xf7'), 54: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x10\x10\xf7'), 55: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x20\x20\xf7'), 56: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x40\x40\xf7'), 57: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x02\x01\x01\xf7'), 58: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x02\x02\x02\xf7'), 59: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x02\x04\x04\xf7'), # 60-71 keys send MMC Mute (0x62) OFF 60: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x00\x20\x00\xf7'), 61: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x00\x40\x00\xf7'), 62: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x01\x00\xf7'), 63: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x02\x00\xf7'), 64: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x04\x00\xf7'), 65: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x08\x00\xf7'), 66: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x10\x00\xf7'), 67: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x20\x00\xf7'), 68: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x01\x40\x00\xf7'), 69: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x02\x01\x00\xf7'), 70: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x02\x02\x00\xf7'), 71: SysEx('\xf0\x7f\x7f\x06\x41\x04\x62\x02\x04\x00\xf7'), # 72-83 octave sends MMC Solo (0x66) ON 72: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x00\x20\x20\xf7'), 73: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x00\x40\x40\xf7'), 74: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x01\x01\xf7'), 75: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x02\x02\xf7'), 76: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x04\x04\xf7'), 77: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x08\x08\xf7'), 78: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x10\x10\xf7'), 79: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x20\x20\xf7'), 80: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x40\x40\xf7'), 81: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x02\x01\x01\xf7'), 82: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x02\x02\x02\xf7'), 83: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x02\x04\x04\xf7'), # 84-95 octave sends MMC Solo (0x66) ON 84: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x00\x20\x00\xf7'), 85: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x00\x40\x00\xf7'), 86: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x01\x00\xf7'), 87: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x02\x00\xf7'), 88: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x04\x00\xf7'), 89: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x08\x00\xf7'), 90: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x10\x00\xf7'), 91: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x20\x00\xf7'), 92: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x01\x40\x00\xf7'), 93: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x02\x01\x00\xf7'), 94: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x02\x02\x00\xf7'), 95: SysEx('\xf0\x7f\x7f\x06\x41\x04\x66\x02\x04\x00\xf7') }) ) >> Port('MMC-out') ) |
|
Note: my main reference as to 'correct' MMC functionality has been only Qtractor, as I don't have access to any other DAW that I know supports MMC track controls, as another point of reference. I found it's useful to have that connected in parallel with Ardour, to verify the relevant controller is working ok. However, I'm also aware that Qtractor, along with us428control and QmidiCtl/Net are all developed by the same person, so may be that they're more geared to working well with each other. However, I've tried to check them (i.e. that MIDI message that go in/out of them) against the MMC spec and they seem sound, with the exception of the Solo function, which I know he's added as a non-standard MMC implementation, albeit consistently (and quite handy). |
Date Modified | Username | Field | Change |
---|---|---|---|
2020-05-15 20:22 | gwyndaf | New Issue | |
2020-05-15 20:22 | gwyndaf | Tag Attached: control | |
2020-05-15 20:22 | gwyndaf | Tag Attached: Midi | |
2020-05-15 20:22 | gwyndaf | File Added: midi_notes-mmc.py | |
2020-05-15 20:22 | gwyndaf | File Added: MIDI MMC Masked Write calcs.ods | |
2020-05-15 20:50 | gwyndaf | Note Added: 0024158 |