Knobber - USB MIDI single knob/button controller by Echolevel

(UPDATED - see below!)



image



Well, here it is: the Echolevel Knobber! A tiny, class-compliant, USB MIDI controller with precisely ONE knob and ONE button. I always wanted something like this and could never find one on the market; fortunately, once the Teensy USB Development Board came of age, making my own became very straightforward. The Teensy is an Arduino-like dev board with two major advantages (for me) over Arduino: it’s extremely small while still having a USB (micro) connector, plus it natively acts as a class-compliant USB MIDI device allowing plug’n’play use on modern versions of OS X, Windows, iOS and - to a certain extent - Linux. Why? Well sometimes you’re working in a coffee shop or playing live on a very tiny amount of table space, and you don’t *need* the 8+ knobs that your favourite controller offers. In something like Ableton Live, where the Remote feature ‘captures’ your controller per track or device, being able to map one single knob to a parameter for the purposes of a carefully-controlled automation edit or a live performance tweak is handy. It is to me, anyway, and I primarly built this to cater for my own need :) The button is just there because a) there was enough space for it in the box and b) it’s handy for toggling that device (or another device) on/off; great for automation stutter edits with a glitchy effect, for example.



See it in use controlling an Ableton Live Auto Filter cutoff in the video above, while the push-button toggles the device on/off, and check out the pics, schematic and code to see how you can build your own. 



Dev Process - Short Version 



The first problems I ran into were in stabilising the value from the potentiometer (knob). For MIDI CC automation, you want the value to stay still and for the device to stop sending MIDI data when the knob isn’t being turned. Fortunately, my old friend and chipmusic compatriot Philip Cunningham (aka Firebrand Boy, aka unsymbol) had made a slightly more complex MIDI controller a few years ago so I was able to use some of his code (availalbe on his Github) to take a running average of the input values and smooth them out. That wasn’t quite enough, though, and a bit more digging led me to the concept of power decoupling and the fact that a small capacitor would - for reasons I don’t quite understand because I’m an electronics noob - smooth everything out nicely. Phil’s code also clued me in on the Bounce stuff, which makes it much easier to get useful data from button presses. Cheers Phil! 



I prototyped the whole thing on a breadboard (see below), testing the input with MIDI Monitor for OS X (MIDI-OX is best on Windows), and then packed it all into the smallest Hammond project box I could find in Maplin. The pot is a 100K linear (you can logarithmise the values in your code if you want to), the switch is the smallest I could find in Maplin (though Farnell/RS/etc probably have better ones; this one isn’t great, to be honest) and I used a Dremel to carve out the micro-USB slot and the knob/button holes. The £16 Teensy board sits on the case cover so that the screws are face-down when the device is in use, and I glued that down with a hot glue gun - bracing it at the back with a Dremelled-down piece of veroboard (also glued) so it can withstand having the USB cable jammed into it without moving. Hopefully the glue will keep it nicely in place, though a more hardwearing option might be to break out the micro-USB to a B-type connector mounted to the chassis. Easily done in a bigger case, but there is almost NO free space in this one once the components and wires are packed in. Finally I soldered everything in, tested it and was met with success! 



If you make one of these yourself, bear in mind that loading an update of your code onto the Teensy (which you might need to do if you want to change CC mappings, for instance) requires you to press the reset button on the Teensy itself. I can do this quite easily by unscrewing the bottom of the box, opening it slightly, then poking a finger in to hit the button. Not ideal, but then you shouldn’t have to make changes very frequently. If you did, you could break out the rest switch to another physical switch mounted on the case. In the long term, I want to implement some SysEx control whereby you can send new mapping values direct from SysEx Librarian or something, or maybe a Max/MSP patch, which are stored in the Teensy’s tiny amount of non-volatile EPROM. Just a thought. 



I’ll add other details as I think of them.



UPDATE

I’ve now got a SysEx configuration system in place, described in the code below. Basically, while some commercial controllers supply graphical config programs so you can choose which channel/CC number/button type each control should have, I’m offering a far more ghetto solution: hack the default .syx file in a hex editor (very easy) and then transmit it to the device using software like Sysex Librarian (OS X), MIDI-OX (Windows) or various DAWs. Few people will feel the need to do this, but I’ve included it in case you have a really awkward clash with some other controller in your setup. You should only need to make a change once, as the Knobber has non-volatile storage built in that should hold those values for, ooh, eternity or thereabouts.



image

image

image

image

image

image

image

image

image



Note - you’ll need to install Arduino and the Teensy stuff for it (which is all part of Teensy setup, explained on its website), and before you send any MIDI-related code to the board you should go to Tools -> USB Type and select ‘MIDI’. Once the board is running in MIDI mode, you won’t be able to see any useful output in Arduino’s built-in serial monitor, but that’s no problem - just use MIDI Monitor or MIDI-OX instead. You can also change the self-declared USB MIDI device name in a header somewhere, but I can’t remember right now…I’ll add it when I do.



CODE:

/*
'Knobber' - one knob/one button USB MIDI controller by Echolevel - 
http://echolevel.tumblr.com/post/49737964614/knobber-usb-midi-controller-by-echolevel
Feedback: http://twitter.com/echolevel

Special thanks to Philip Cunningham (aka unsymbol, aka 
Firebrand Boy - http://philipcunningham.org )

SysEx Config Message Structure:
0xF0 # SysEx message start byte
0x14 # Manufacturer ID; 0x14 is actually Fairlight, but I don't forsee too many conflicts here... 
0x01 # Knobber knob channel number
0x01 # Knobber button channel number
0x0E # Knobber knob CC number
0x0F # Knobber button CC number
0x01 # Knobber button behaviour (0 = momentary, 1 = toggle)
0xF7 # SysEx message end byte

On first run, your Teensy's EEPROM might contain values left over from a previous sketch so you 
should use Sysex Librarian, MIDI-OX or similar to transmit the default .syx file (available from
wherever you got this code). Thereafter, you can copy that default .syx and use a hex editor to 
adjust the values according to the structure above.
*/

#include <Bounce.h>
#include <EEPROM.h>

// Default settings - will be overwritten if EEPROM values are present.
int knobChan = 1; int buttonChan = 1; int knobCC = 14; int buttonCC = 15; 
int kPin = 0; int bPin = 0; int behaviour = 1;
int inputAnalog, ccValue, iAlag;
boolean toggled = false;
Bounce button0 = Bounce(0,5);

void setup() {
  //MIDI rate
  Serial.begin(31250);
  pinMode(bPin, INPUT_PULLUP);
  delay(5);
  knobChan =  EEPROM.read(1); 
  usbMIDI.sendControlChange(44, knobChan, 2);
  delay(5);
  buttonChan = EEPROM.read(2); 
  delay(5);
  knobCC = EEPROM.read(3);    
  delay(5);
  buttonCC = EEPROM.read(4);
  delay(5);
  behaviour = EEPROM.read(5);
}

void loop() {
  // Check for SysEx config message
  if(usbMIDI.read() && usbMIDI.getType() == 7) {                
     if (usbMIDI.getData1() > 1 && usbMIDI.getData1() < 9) {
        // unpack SysEx
        byte * sysbytes = usbMIDI.getSysExArray();
        if (sysbytes[0] == 0xf0 && sysbytes[7] == 0xf7) { // Good length; legit sysex.
          if(sysbytes[1] == 0x14) {  // It's either Knobber or a Fairlight CMI...
              // 2, 3, 4, 5 and 6 can now be written to EEPROM and to global vars
              EEPROM.write(1, sysbytes[2]);
              knobChan = sysbytes[2];
              EEPROM.write(2, sysbytes[3]);
              buttonChan = sysbytes[3];
              EEPROM.write(3, sysbytes[4]);
              knobCC = sysbytes[4];
              EEPROM.write(4, sysbytes[5]);
              buttonCC = sysbytes[5];
              EEPROM.write(5, sysbytes[6]);
              behaviour = sysbytes[6];

          }          
        }
     } 
  }
  
  
  if(behaviour > 0) {
      // Pushbutton - MOMENTARY behaviour
      button0.update();
      if (button0.fallingEdge()) {
          usbMIDI.sendControlChange(buttonCC, 127, buttonChan);
      }
      if (button0.risingEdge()) {
          usbMIDI.sendControlChange(buttonCC, 0, buttonChan);
      } 
  } else {      
      // Pushbutton - TOGGLE behaviour
      button0.update();
      if(button0.fallingEdge()) {
         if (toggled) {
             usbMIDI.sendControlChange(buttonCC, 0, buttonChan);
             toggled = false;
         } else {
             usbMIDI.sendControlChange(buttonCC, 127, buttonChan);
            toggled = true;
         } 
      }
  }
    
  inputAnalog = analogRead(kPin);  
  if(abs(inputAnalog - iAlag) > 7) {  
    // calc the CC value based on the raw value
    ccValue = inputAnalog/8;                                
    // Invert the pot value (because I soldered it backwards...)
    int inverted = map(ccValue, 127, 0, 0, 127);            
    // send the MIDI
    usbMIDI.sendControlChange(knobCC, inverted, knobChan);                                  
    iAlag = inputAnalog;
  }

  delay(5); // limits message frequency
}

Swamplr

Swamplr

Studio wear: personal isolation chamber

Studio wear: personal isolation chamber

Genuinely bought for composing, not dicking around, but this is fun. Scrolltext soon!

Genuinely bought for composing, not dicking around, but this is fun. Scrolltext soon!

&#8220;Yo, hit the lights - I bet it looks crispy in the dark&#8221;

“Yo, hit the lights - I bet it looks crispy in the dark”

Right-click convert to wav - MIDI sample dump (and MPC2000, Amiga, FastTracker, etc.)!

Trying to outdo myself in the Finding Really Convenient Solutions To Excruciatingly Obscure Problems stakes. This time, it’s an extremely quick way of converting MIDI sample dumps to wav. The MIDI Sample Dump Standard is a means of transmitting audio data at a sub-snail - actually, sub-glacial - pace over DIN5 MIDI serial connections. One in the eye for all those who love to condescendingly remind newbies that “MIDI doesn’t carry audio, YOU FOOL!”; the standard was actually introduced in the early 80s and was still built into sampling hardware into this century. MIDI is just a serial protocol, so you can send any sort of data along it. As long as you’re prepared…to wait…ages… My SU10 can export sample dumps (but sadly not receive them), and its own nuanced shitness at sampling means it’s nice to be able to retrieve stuff from it before wiping its banks and sampling new stuff.

I was hoping I wouldn’t have to spend (waste) a day researching the SYSEX data structure and coding something that would parse the headers and stitch the data back into WAV, so I was relieved to discover that libsndfile does just that. It’s easily installed on OS X (I used the horrible but occasionally useful MacPorts), and it offers a few commandline programs that do conversions of all sorts of esoteric formats (including FastTracker 2 XI instruments - wehey!). So, wrapping that up in an AppleScript/Automator service was pretty straightforward and, with the service in my ~/Library/Services directory, I now have ‘mdsd to wav’ as a right-click context menu action in Finder. Select the file, right-click, ‘mdsd to wav’ and it’s done - the wav is created in the same directory as the sds file. The sds file, by the way, can be anything: if you’ve done what I do to get the sample dump, which is to record it in Sysex Librarian and save it from there, it might have a .syx extension. Doesn’t really matter; libsndfile will just do what it does or inform you via the Terminal window if you ran it on a bogus file.

As for your service, in Automator you should set ‘Service receives selected’ to ‘files or folders’ and in ‘Finder’, add a Get Selected Finder Items, then Run AppleScript and paste the following:

on run {input, parameters}

if input is not {} then
set posix_file to POSIX path of item 1 of input
set posix_target to text 1 thru ((offset of "." in posix_file) - 1) of posix_file
if input is not {} then
tell application "Terminal"
activate
set windowcount to count window
if windowcount is 0 then
do script "clear"
end if
set thescript to "sndfile-convert -pcm16 \"" & posix_file & "\" \"" & posix_target & ".wav\" "
do script thescript in window 1
end tell
end if
end if
return input
end run

BY THE WAY…because this doesn’t check input file extensions, it’ll work on all the formats that libsndfile understands (see the link above) including Apple AIFF, Amiga IFF/SVX8/SVX16, FLAC, Akai MPC 2000, FastTracker 2 Extended Instrument and RAW PCM audio. Isn’t that cool? It converts them to 16bit PCM but as you can see from the script, it’s easy to change that to one of libsndfile’s other output encodings. Run sndfile-convert with no arguments to see a list of possibilities.

Chipdisco on Raspberry Pi - Amiga MOD playback in Java (by bdse)

Long story short: PortaMod is my Amiga MOD (and PC FastTracker XM and ScreamTracker S3M) replayer library for Processing. Chipdisco is a dual-deck DJ app built with PortaMod. Processing is Java made simple and fun (if you can believe that Java could be made fun) and it’s great for interactive digital art. Its focus is very much on visuals, however, and there’s no way of getting it to run without wasting a lot of CPU cycles on graphics - even if you don’t want graphics. 

I just got a Raspberry Pi. Woohoo, etc. Cute little thing, and I’d love to be able to use it as a headless Chipdisco DJ box that can be run without a monitor, and just with a MIDI controller for controlling Chipdisco’s myriad interactive functions (crossfader, tempo, pitch, sync, channel-faders, channel-mutes, etc.)

Problem is, asking a wee 700Mhz machine to run a Java virtual machine at any decent lick is a bit much. openJDK, the default open source JVM implementation, is really slow - much slower than Oracle’s embedded VMs (apparently) and it doesn’t use RasPi’s floating point hardware, instead doing it in software. That’s quite a big deal, but it seems like people are interested in getting Java up to some kind of usable speed on RasPi - not least because, although everyone claims to hate Java (me included), there’s a lot to be said for having code that’ll run on x86 Windows, OSX and Linux *and* ARM platforms without it needing to be tweaked.

So. This video shows a proof of concept: a command-line mod player in Java using a version of PortaMod that I made last night - basically removed all the Processing so it’s pure Java and doesn’t require that inefficient graphics loop to be run. Anyway, for reasons that are probably quite good, Processing just *will not* run headless and there are no plans to change that. This PortaMod version is still quite inefficient as it does a load of note-processing stuff on each row of playback (great for interactive stuff like syncing visual effects to individual drum hits, or whatever) so I’ll try commenting out those bits to see how smooth I can get this on RasPi.

Chipdisco for Raspberry Pi? tl;dr alert

Well. I’ve got a Raspberry Pi on order and although I expect the Java runtime implementations to range from crap to awful, I’d love it if Chipdisco could run on it. 700/800Mhz is tight, but my latest version of ChipdiscoDJ slashes the CPU load to about a quarter of the previous version by cutting back on a load of wasteful GUI stuff. Sure, I should abandon browser-applet functionality (a further nail in that particular coffin being Processing 2.0’s recent ditching of applet support), give up on Java entirely and do the whole thing in SDL, but learning SDL (and C++, at which I’m hopeless) is not a small task and frankly, Processing/Java still makes it really easy for me to do what I want quickly and in a cross-platform way.

Anyway, one of ChipdiscoDJ’s ‘big’ (to me and the three other people in the world I know to have ever used it) features has been the Cue Mix thing: select a secondary audio interface, plug headphones into it, then switch either deck between the default and the secondary interface so you can beatmatch/pitch-match a track against the one that’s playing out to FOH before toggling it back to the default interface and blasting it out to the punters. Y’know, all those punters who’ve come to hear you DJ your Amiga modules.

Well, the Cue Mix thing never worked that well. Firstly, it was prone to those utterly mysterious Java exceptions that sometimes just appear for NO GOOD REASON and occasionally crash your app. Secondly, because I had to flush the buffer on changing devices and then fill the new one, if you’d beatmatched your tune while cueing, the timing would be thrown right out when you brought it back in. Defeating pretty much the entire point of this feature. Finally, Apple’s contempt for Java (which I can absolutely understand, as a Java programmer) has led to the cripplement - accidental or otherwise - of SourceDataLines for installed audio devices that definitely exist, though Java says they don’t. I’m Mac-only now, so when I realised this, I decided to ditch Cue Mix completely. Life’s too short. Oh, Apple have also ruined Java MIDI too - but that’s another story.

Ghetto solution! In my experience, clubs are badly laid out and usually have weird configurations of speakers (unless you’re playing through a Funktion One rig, in which case you’re probably not using Chipdisco) which render most stereo-spectrum subtleties redundant - if not actually detrimental to the sound, which is why most dance producers mix with this in mind. Nothing important is panned too wide, or else half the people in the club might never hear it. 4-channel Amiga MODs are, usually, best played in mono. Don’t listen to anyone who says you have to recreate the 100% hard-panned Left/Right/Right/Left sound of an Amiga that’s been plugged directly into a hifi - while Chipdisco can do this, I force it not to. It’s awful; a deficiency of the hardware that Commodore tried to cover up by claiming it meant the Amiga had ‘stereo’ sound. It didn’t - not until software drivers like AHI were able to mix stereo properly and shove it out through Paula. Don’t buy the authenticity argument, either: like most claims of ‘authenticity’, it’s bogus. Any of us who cared about music back in the oldschool Amiga days (particularly demosceners) set up mono or near-mono listening environments so we could get the proper effect of a 2-channel pattern delay effect, or similar, without it ping-ponging back and forth across the room.

Long and the short of these two considerations is that if Chipdisco’s output is going to be completely mono, which I think it might as well/should be, I can shove one deck out fully to the left, the other deck fully to the right and… you’ve guessed it, cue mixing! Sorta! You’ll only get half of your headphones to listen through, but that’s how most DJs cue mixes anyway, and because there’s no device switching, any beatmatching you do should be dead on time! I’m going to convert the cue mix buttons so that they flip the panning, so using it should be roughly the same. And hey, it frees up a channel on the mixing desk! Stick your iPhone in the other one, with some kind of dub siren fartbox. That’s what I’m gonna do at Sundown in September, if I get this finished in time.

Finally, it’s a shame (to me) that nobody’s really heard of Chipdisco - even amongst the few people who understand what it is without having to be subjected to one of my tedious history lessons. But that’s my fault. Now’s the time to decide whether I can be arsed to push it as a thing that oldschool chipmusic/demoscene people might want to use in live situations, and if not, maybe I’ll start doing a few proper gigs with it just for the craic. Also plugging in some OSC output messages to hook up with some visuals, which are being worked on by evilpaul of AteBit…might give that an outing at Sundown. Anyway, there it is.

At least it&#8217;s got pretty colours #chipdisco

At least it’s got pretty colours #chipdisco