Raspberry, signs of life (MIDI)

offrhodes

Member
Hi,

I managed to get USB MIDI to work for Axe FX II XL+ on a Raspberry pi. This as a quick write-up of the steps so far... might be interesting for custom controllers. The PI doesn't excel at anything, but it's "adequate" for a great many things... Me, I'm after physical buttons for tone controls...

"fxload" for USB firmware upload can be installed with sudo apt-get install fxload.
The hex file is here.
I haven't done a "regular" hotplug setup yet but ran it from the command line as
sudo fxload -v -t fx2lp -I axefx2load.hex -D /dev/bus/usb/001/011
where the number "11" changes with every replug cycle, get it with dmesg
[ 368.463374] usb 1-1.1.3: new high-speed USB device number 11 using dwc_otg
[ 368.594151] usb 1-1.1.3: New USB device found, idVendor=2466, idProduct=8003
[ 368.594168] usb 1-1.1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0

If this step causes trouble, a temporary solution is to plug the USB cable first into a Windows machine with drivers, then unplug and connect to the RPI without power cycling. The MIDI interface should appear as /dev/snd/midiC1D0.

Then, I did a crude implementation of the sysex protocol. The program doesn't do anything useful, but I hope it helps as a simple starting point, below.
Note, you may need to edit the "model number" byte, see [1] link in the code.
Then compile with gcc main.c (might require some apt-get gcc or similar) and run with ./a.out. Everything going according to plan, you should see a single message"got firmware info".

I hope this is useful to somebody. Happy hacking :)
Code:
#include <stdio.h>
#include <assert.h>
// [1] https://wiki.fractalaudio.com/axefx2/index.php?title=MIDI_SysEx#MIDI_SysEx:_Axe-Fx_II
#define MODELNO (0x07) // [1] "MIDI SysEx: SysEx Model number per device"
#define MIDIDEV ("/dev/snd/midiC1D0")
void handleMsg(char* buf, int len){
  if (len < 6) return;
  if (buf[0] != 0xF0) return;
  if (buf[1] != 0x00) return;
  if (buf[2] != 0x01) return;
  if (buf[3] != 0x74) return;
  if (buf[4] != MODELNO) return;
  switch (buf[5]){
  case 0x08: fprintf(stdout, "got firmware info\n"); break;
  case 0x10: fprintf(stdout, "got tempo beat\n"); break;
  case 0x21: fprintf(stdout, "got front panel change\n"); break;
  default:
    for (int ix = 0; ix < len; ++ix){
      fprintf(stdout, "%02x ", (int)(buf[ix]));
    }
    fprintf(stdout, "\n"); fflush(stdout);
  }
}

typedef struct {
  char buf[256];
  int ptr;
} msg_t;

void msg_init(msg_t* self){
  self->ptr = 0;
  self->buf[self->ptr++] = 0xf0; // sysex start
  self->buf[self->ptr++] = 0x00; // man ID byte 1
  self->buf[self->ptr++] = 0x01; // man ID byte 2
  self->buf[self->ptr++] = 0x74; // man ID byte 3
  self->buf[self->ptr++] = MODELNO; // model specific. See above
}

void msg_add(msg_t* self, char val){
  self->buf[self->ptr++] = val;
}

void msg_closeSendInit(msg_t* self, FILE* h){
  char chksum = 0;
  for (int ix = 0; ix < self->ptr; ++ix)
    chksum ^= self->buf[ix];
  self->buf[self->ptr++] = chksum & 0x7F;
  self->buf[self->ptr++] = 0xF7;
  int n = fwrite((void*)self->buf, 1, self->ptr, h); assert(n == self->ptr);
  fflush(h);
  msg_init(self);
}

int main(void){
  FILE* hIn = fopen(MIDIDEV, "r"); assert(hIn);
  FILE* hOut = fopen(MIDIDEV, "wb"); assert(hOut);

  msg_t _m; msg_t* m = &_m;
  msg_init(m);
 
  msg_add(m, 0x08);
  msg_closeSendInit(m, hOut);

  int p;
  char buf[256];
 restartMidiLoop:
  p = 0;
  while (1){
    char c;
    int n = fread((void*)&c, 1, 1, hIn); assert(n == 1);
    if (c == 0xF0)
      p = 0;
    buf[p++] = c;
    if (p == sizeof(buf)) goto restartMidiLoop;
    if (c == 0xF7){
      handleMsg(buf, p);
      goto restartMidiLoop;
    }
  }
}
 
Last edited:
Awesome stuff! Thanks for sharing :)

What exactly is your goal with this piece of code? Do you want to extend it to something like an editor like Axe-Edit or something?

Just if you don't already know it, have you heard about afx2tool? I've been exclusively using this script for firmware updates and system backups. It's super handy if you like to use the command line!
 
Hi,

my long term ambition is to hook up a bunch of motorized potis that track the main tone controls when changing presets.
It would be a pretty basic implementation project - get some cheap RC servos, add a wire for position feedback through an ADC like MCP3008. But let's not talk about "plans" - common sense is screaming I better stop tinkering and practice more :)

More realistic, what I'll probably do for my own immediate use is tone control up-down buttons and overdrive, chorus bypass toggles using a plain computer keyboard plugged into the PI... not pretty but functional.

-------------------------------------------------------------
Quick update on the technical stuff regarding fxload and hotplugging:
afx2usb-linux works on my PI without any modification (after apt-get fxload). Meaning, I can plug the AxeFx into USB and it appears immediately as /dev/snd/MIDIC0D0. Great work, especially given that the last change there was made 2 years ago.
 
Yeah this script should work on all linuxes and all processor architectures, since it's a bash script. You seem to use Raspbian, I'm on Archlinux (both Laptop and Raspberry), which is completely different to Debian but still it works perfectly. Its age doesn't really matter, since the AxeII+XLs didn't change in that regard (SysEx messages, checksum codes etc). It's quite well tested, at least by me ;) No firmware update ever failed, it's rock stable!

I'd be very interested in hearing (reading) more about how you realize those ideas!

One thing: I kinda think that an Arduino would do a better job for you here. I'm currently coding a foot controller for my Ultra and I see that the possibilities are almost endless. I could even implement a whole Axe-Edit (ok, totally over my head right now, I'm not really a coder, but I'm sure it's possible) into this controller. It's amazing! But since a Raspberry is capable of much more than an Arduino you'll certainly be able to achieve anything with it!
 
OK, I've spun the idea a little further. The code can be found here on github.

Compiled successfully (make, requires fltk-dev) , it will show a window with some sliders and one large button on the right.
The sliders are the major tonecontrols for AMP1, the button bypasses DRV1. They should track front panel controls (preset change and manual editing). It's intended for use with the touchscreen, but haven't bought one yet.

Please consider this as a possible starting point for own development, not a finished product. It's possible to put any combination of controls on the screen across all blocks, but it requires editing app.cxx with a text editor and recompiling.
Also note that for other units than Axe Fx II XL+ the model number needs to be changed in main.cxx (look up here).

Now I ran into some unexpected MIDI groundloop problems thanks to my El-Cheapo USB-MIDI interface (was planning to keep USB on the PC for audio playback), will continue testing when I've found a better one.
 
Hi,

my long term ambition is to hook up a bunch of motorized potis that track the main tone controls when changing presets.
It would be a pretty basic implementation project - get some cheap RC servos, add a wire for position feedback through an ADC like MCP3008. But let's not talk about "plans" - common sense is screaming I better stop tinkering and practice more :)

Better solution would be to use a MIDI controller with LED rings around the infinite rotary pots. I used to own a Yamaha DG80 combo that had motorized knobs that changed when presets changed and that was great but also the number one thing that eventually failed on those amps. Infinite rotaries are much better solution for this.

If you are interested, I have a work-in-progress project called Axe-Fx Virtual Pedalboard that lets you map any MIDI controller CC to control any knob/switch on the Axe-Fx via Sysex and shows their values in a user interface. It can run in a web browser that supports WebMIDI or as its own app but I have yet to make any standalone app versions of it and support for blocks is incomplete.

My goal with the app was to make Axe-Fx easier to tweak and it has achieved that but I was also thinking that you could export the configuration from it as JSON and load it in an Arduino or Raspberry PI and just have a "headless" solution with no UI that handles the translation of values between MIDI controller and Axe-Fx.

See https://github.com/laxu/AxeFx2VirtualPedalboard
 
Last edited:
Thanks :) Had I known about your project, I wouldn't have started my own but simply rigged up my old Doepfer 16-button MIDI CC box...

Physical controls would be nice but I think I'll go for a touchscreen first. It's the least hassle, and my local supplier even has one in stock.
On 7'' size I should still be able to control that with my knuckles when wearing fingerpicks.
A screenshot, if anybody is interested, same as just checked in here on github.
upload_2018-5-24_11-32-23.png
 
Back
Top Bottom