One day later and I got the data mapping between the basic MIDI and grid tuples worked out and libraries that can handle the I/O.

Here’s the toolkit I’m working with

  • python 2.7
  • python-midi
  • python-osc
  • ALSA sequencer for hardware MIDI communication

The concurrent realtime I/O is more difficult than I imagined. I would like to have a drop in replacement for serialoscd. I pushed my commits thus far and I’ll continue working on it. If anyone else has this hardware and is interested, lemme know.

It’s Linux only because that’s what I know. I imagine a macOS hardware interface would be useful as well.

1 Like

I’m curious about what project(s) you’re planning with your grid on linux once you got the serialoscd emulation layer cooking!

Nothing specific yet. I’m using this as a chance to do software development work with controller protocols I’ve been curious about for a long time in an environment that isn’t PD.

It’s a really difficult thing to approach! I was making good progress using common lisp & the same ‘concurrency channel’ abstraction that’s part of go (go the programming language). It’s basically like a ‘unix pipe’ that can be read/written to from different threads, either blocking or non-blocking. Maybe there’s a library you could hook into for this kind of inter-thread communication? nanomsg could be helpful if you can find some bindings ready to rock?

I’ve already got 2 unfinished midi performance sequencer projects (an initial ugly one & an aborted rewrite) written in common lisp… They both used this kind of concurrency. But I was getting more stuck on sequencer design - my plumbing on the second attempt worked well…

So I do think that, overall, an approach to concurrent i/o using nanomsg or similar is to be recommended!

Turns out the python-midi library was designed primarily for reading and writing midi files, not realtime communication with hardware. I found the rtmidi python bindings, which provides a user defined callback function on MIDI input. Gonna test that out today.

There’s also a python-osc library that looks like there is an OSC address => callback function matching feature.

I wonder if I’ll need a third thing to glue together these two event loops and callbacks?

1 Like

Have you looked at pymonome? Not sure if you’ll be able to use it directly, but it can at the very least give you some ideas :slight_smile: it uses asyncio

1 Like

totally different tack, but you may like to know that the monome serial protocol is pretty straightforward. so yeah i’d go for the hardware route, why not

a programmable adapter that took hardware midi and emitted monome serial would be easy to make and widely useful. (i probably have some arduino emulator code bits lying around that could be posted). i don’t know if its ever been tested but i think you can just tell serialosc your serial device has M buttons and N encoders and &c.

(actually guess i don’t know if apc40 even has hardware midi out… so maybe nevermind)


but for software, yeah emulating all of serialoscd sounds like a lot. i’m thinking of all the multiple device and configuration managment stuff it does.) for a single device it seems not too bad: one thread to read midi / send osc, one other thread to read osc / send midi. i don’t even see why they’d need much synchronization

in C i guess i’d use liblo; gives you an OSC server thread with a callback and lets you dispatch OSC client messages asynchronously from any thread. (i guess pyosc is similar.) and i guess portmidi if you don’t want to deal with sysfs or alsa directly. (dunno about realtime midi in python. sounds fishy)


[ed: omg, lol]
http://www.akaipro.com/support/kb/articles/akai-apc-series-frequently-asked-questions#q13

Will the secret handshake prevent us from turning a Monome + BCR into an APC?
Yes.

2 Likes

I used to emulate monome in various ways when serialosc was strictly zeroconf-based. Without too much effort you could make any program pretend to be a grid or an arc (even mobile devices/apps connected to the same LAN).

Now it seems you have to emulate serialosc for the discovery mechanism to work, so pymonome would not be of much help here, unfortunately.

I did it!

Implemented the /grid/led/set, /grid/led/all and /grid/key namespaces.

I know some of the secret sysex handshakes…

3 Likes

@zebra what is BCR? The APC MIDI implementation is documented in my repo with a PDF from Akai. I got the Sysex to enable “Ableton mode” without Ableton.

A Behringer rotary controller (I presume!)

huh, there is one encoder on the APC40 and it outputs a CC with deltas as 127 when turned counter clockwise and 1 as clockwise when rotated with slow constant movement. If I spin it as fast as I can with my finger it’ll output up to 33 so I guess that’s the step over clock tick.

I’m a little unsure about the /grid/led/map address. From the protocol document

Set a quad (8×8, 64 buttons) in a single message. Each number in the list is a bitmask of the buttons in a row, one number in the list for each row. The message will fail if the list doesn’t have 8 entries plus offsets.

If my grid is 8x8 is this address equivalent to /grid/led/all

no, /grid/led/all takes a single binary argument and sets all the leds on the device to full on or full off.

So the /grid/led/map address can turn 64 buttons on or off, based on a bitmasks?

yes. /led/map is 1 byte per column, 1 bit per led.

/led/level, /led/level/map, led/level/all are analogous but for variable brightness using1B per led

I just thought it was funny that akai saw fit to dissuade people from using monome in their official faq

aren’t those encoders all over the right side of the thing?

1 Like

The knobs on the right are pots, 0-127

In other news, I got it all working and the PD grid studies loaded. I had to hack [serialosc] for manual connections to the server. I have to implement a few more things in the row, col and map callbacks but check it out!

Gonna take a little break from this for a few days.

6 Likes

Nice project! I have been trying to reclaim my Ableton Push 1 to be used with some PureData patches. Right now I have a very rough interface between PD and the Push via Python - but in lieu of not being able to get rtmidi working I opted for Jack Client.

I’m keen to comb through your work and see if I can learn and adopt some of your methods.

Speaking of APC40 hax, has anyone successfully removed the big side wings? There are some instructions on the Ableton forum but the pics were all hosted on photobucket and are now dead. I’m about to pick one up super cheap and would like to slim it down.