Renesas RZ – a good next step after PIC, Teensy and Arduino

P1100098

DIY hardware developers today are spoilt by the ease with which they can create processor-intensive hardware with very little prior knowledge. A Teensy 3.2, for instance, runs at 96MHz and can easily process and output CD-quality audio (through its Audio Adapter Board), and the relatively small amount of coding you need to do is well documented and easy.

If you need something a bit more powerful (and with quite a bit more RAM than the Teensy 3.2’s 64KB), there’s PIC – their top MCUs (PIC32MZ) run at 200MHz, with 512KB RAM. Not quite as easy to use as Teensy / Arduino, but still manageable, and with a large user community who can help you out. (The top PIC32MZ does have many known errata, for which users are anxiously awaiting an updated version.)

But where to if you need even more power than that? That’s the question that I came up against a few months ago, and nowhere on the Internet had a definitive answer. For an advanced piece of music hardware I’m developing, I needed something with as much processing power and RAM as possible.

The option I went with, and spent several difficult months learning how to use, is the Renesas RZ. It runs at 400MHz (and has 3 times the DMIPS of the top PIC32MZ), and has between 3MB and 10MB of onboard RAM, depending on the model, and allows you to connect up to 128MB of external SDRAM. Its specs are an enormous upgrade from Teensy and PIC.

My own synthesizer engine, which crunches 32-bit integers, runs 4.2x faster on the Renesas RZ than Teensy 3.2 / 3.1. (That’s with virtually the exact same codebase – I’d bypassed the Teensy audio library and am writing generated audio data straight to a DMA-read output buffer in both cases. The same GCC optimisation settings were used.)

However, if you’re used to the friendly documentation and active online user communities around Teensy, Arduino and PIC development, you’re not going to find Renesas easy: all there is is a 2,500 page datasheet, a few example projects, and the RZ forum only gets about 3 posts per week. And yet, it’s still the best option. Nowhere could I find any hint of an MCU more powerful than the PIC32MZ with a more active user community than the Renesas RZ’s very small one.

The purpose of this post is not to provide a step-by-step guide to using Renesas RZ microcontrollers. They are extremely complicated things to use, and developers will need to know (or learn) how to do things like design their own PCBs (see below), read and understand MCU datasheets, tweak linker scripts, and unless your luck is significantly better than mine, probably troubleshoot seemingly unexplainable problems for days at a time.

This post is intended simply as a DIY-friendly introduction to the Renesas RZ so that you can assess its suitability for your project, and have some pointers should you decide to begin developing with it.

Further advantages

  • The Renesas RZ has multiple SPI ports, which Teensy 3.2 doesn’t have (but PIC does).
  • A possible advantage over PIC is that Renesas RZ development standardly uses the free GCC compiler, which includes the option to significantly optimise your compiled program. My understanding is a little limited here, but it appears that with PIC, you have to use Microchip’s XC compiler, whose free version does not include any optimisation (and the paid versions cost $495 USD and $995 USD). I could have this wrong though – maybe there is a way to use GCC with PIC.
  • The Renesas RZ includes an SD host interface – for talking to SD cards using a faster method than SPI. This sounds great, but what I didn’t initially realise is that in order to obtain the code library for this, or even the corresponding chapter of the datasheet, you need to sign a non-disclosure agreement with Renesas. This will be related to the fact that SD cards are proprietary technology, and companies have to pay a $2000 USD per year licensing fee to Secure Digital if their products interface with SD cards using the non-SPI interface. I contacted Renesas, hoping to go through the process of signing the NDA so that I could use the SD host interface in my own personal, non-commercial projects, but I think they cottoned on that I’m just a DIY enthusiast and not a large company. You can still access SD cards using SPI though – I’ve done this successfully, using the free FatFS library for handling the FAT filesystem.

How to get a Renesas RZ

If you’re used to working with Teensy, Arduino, and possibly PIC, you’ll be used to buying your microcontrollers as existing PCBs, all set to be wired up to LEDs and switches, with a USB connector for programming them. And it’s cheap. Whereas, Renesas’s development board for the RZ (the Renesas Starter Kit+, or RSK+) costs…….. $1,100 USD.

A couple of other companies have created and are selling Renesas RZ development boards significantly cheaper:

  • The Vekatech VK-RZ/A1H – 49.99 EUR. Purchase here.
  • The Computex CEV-RZ/A1L – I can no longer find the purchase link, but I think it was around $100 USD

The option I prefer, however, and the one I’m going to provide info on, is the creation of a custom PCB. If you’re working on a project advanced enough to require something as powerful as the Renesas RZ, chances are you’ll be planning to do this anyway, so it may be logical to jump straight to this step rather than first experimenting with the pre-built boards. The Reneas RZ chips cost between $18.11 US and $35.96 US on Digi-Key, depending on RAM size.

If there’s any interest, I may eventually share the design for, and possibly even sell pre-made, my own basic evaluation board for the Renesas RZ.

Hardware

A significant difference between the Renesas RZ and any of the more common DIY-friendly MCUs is that the RZ does not store its program (the code you write) on on-chip flash memory. The program has to be stored on an external flash memory chip, connected via SPI. It’s ok – these chips cost just a couple of dollars for a few megabytes. The user will probably want to set up a bootloader program to copy the main program from flash to RAM before it is executed. Renesas provides a working one – see below.

Unfortunately, programming the Renesas RZ (i.e. programming its external flash chip) isn’t as simple as just plugging in a USB cable as you might be used to. There are a couple of different ways you can do it. The ideal way, recommended by Renesas, is to use a device called a J-Link, made by a company called Segger. Digi-Key stocks them. The J-Link is a “JTAG emulator”. It provides a connection between your computer’s USB port and the Renesas RZ’s “JTAG” port (you’ll build a connector into your PCB), allowing it to do a couple of things:

  • Program your external flash memory chip – but only if you have an expensive version of the J-Link – see below
  • Load your program directly into the Renesas RZ’s RAM for immediate testing and even live debugging (pretty cool)

For a DIY developer, getting all of this working is prohibitively expensive. There is a cheap version of the J-Link – the “EDU” model – which is only $60 USD and licensed for educational purposes only. It can load your program to RAM and do debugging, but it doesn’t come with the software J-Flash for programming your external flash memory chip. The cheapest J-Link to come with this software is the $598 USD version. Or you can buy the J-Flash software separately for $384 USD, but the Segger website suggests that it doesn’t work with the J-Link EDU anyway. There is also a “lite” version of J-Flash, which is free and works with the J-Link EDU, but it doesn’t appear to support the Renesas RZ. (Please note that I have not personally verified that the J-Flash software can program the Renesas RZ at all – I don’t have it, and only have some fairly hazy information to go by, so research this yourself before spending lots of money.)

The solution if you’re on a budget is to instead (or preferably in addition) use something like a FlashCatUSB ($30 USD) to program your flash memory. The FlashCatUSB connects directly to your flash chip via SPI (you’ll need to build a physical connector for this into your PCB), and comes with free software for programming it. There are some complications to this method though – it’s really a bit of a “hack” compared to the elegant but expensive J-Link:

  • You need to keep your Renesas RZ in “reset” mode (you’ll normally build in a hardware button for this) while programming your flash chip, otherwise the RZ will try to access the chip at the same time as the FlashCatUSB and it won’t work. In fact, you’ll want to make your PCB’s reset button a toggle switch rather than a momentary button so that you can leave it in reset mode hands-free.
  • If you’re going to leave the FlashCatUSB connected to your flash chip while you run your program, you’ll need to disconnect the FlashCatUSB from your computer’s USB port first, otherwise again, both things will be trying to access the flash chip at once.
  • After writing your program to the flash chip, you need to switch the power off and on again to the RZ to flush a potentially cached version of what was on the flash chip before.

So a sensible and economical solution (provided it’s just for “educational” purposes, which it probably will be, because you’ll have a lot to learn) would be to use the $60 USD J-Link EDU for debugging and running your program directly from RAM, and the $30 USD FlashCatUSB for programming your flash memory so your creation can function away from your computer.

Designing a PCB

The best resource on what your Renesas RZ schematic should look like is Renesas’s own schematic for the RSK+. By copying the parts of this that I needed, and referring to the datasheet a lot, I was able to create a functioning board. The Computex CEV-RZ/A1L also has its schematic publicly available – it’s a bit simpler as it has less add-ons included.

Some important notes on your PCB design:

  • I would recommend starting with the 10MB RAM version of the RZ – the RZ/A1H, because some of the example projects’ linker scripts are configured to use the full 10MB, and need modifying in order to run on an RZ with less RAM (this is the case with the USB example project). That can be done though, if you prefer. The RSK+ uses the 208-pin version of the chip, so perhaps you’ll find that easiest if you’re copying the schematic, and it might mean the example projects will be happier to run without modification. But I used the 176-pin version and got it working.
  • Unlike custom PCBs based on Teensy or PIC, you need a “reset supervisor”. Switching power on to the Renesas RZ chip sometimes doesn’t cause it to start up correctly. It needs to be kept in “reset” mode momentarily first, which is what a reset supervisor does. This is very easy and only needs one component – I use a APX803-31SRG-7. Making this setup compatible with the JTAG connection needs to be done right. The RSK+ schematic’s way is quite complicated. I do it an equivalent and easier way – here’s the schematic. You can see the reset button, reset supervisor, and JTAG connector.
    jtag schematic
  • If you’re going to use one external SDRAM chip, but not two, it should be connected to CS3 (that is, the pin called CS3, which will also “attach” it to the “CS3 address space” as it’s referred to in the datasheet). Both the datasheet and some comments in a Renesas example project state this requirement, although I’m not sure exactly what would happen if you connected your lone SDRAM chip to CS2 instead.
  • The SDRAM chips that you’re able to use with the RZ are generally the 54-pin ones which operate off a 3.3V supply, and may be up to 64MB each. The RSK+ uses the K4S561632D (32MB) which can be had for only a dollar or two on sites like AliExpress. From the more mainstream suppliers, Digi-Key has the 32MB AS4C16M16S-6TCN for $2.84 USD (that one I haven’t personally tried yet), or the 64MB MT48LC32M16A2TG-75:C for $11.95 USD. Conveniently, these chips all share the same pinout.
  • As you will see, the RZ requires a 1.2V supply as well as 3.3V. You should use a switching regulator like this one, rather than a linear regulator, to supply the 1.2V, because the RZ will draw almost 400mA from it, which is huge, and a linear regulator would be terribly inefficient.
  • While there might be a technically better way to do it, the board I created was just 2-layer. In order to achieve all the routing between the RZ and my SDRAM chip, I “piggy-backed” the two of them on opposite sides of the board. This meant that the SDRAM chip was kind of disrupting my ground plane, but it still worked fine.
  • You need to be careful with your placement of crystals (you’ll at least need one ~13.333MHz one). The PJRC (Teensy) website has some good guidelines for this, on this page.
  • There are some pins which you need to tie to either 3.3v or 0v to select a few options, including whether you want to boot from your external SPI flash memory (you very likely do). They are called MD_ BOOT0, MD_ BOOT1, MD_ CLK, and MD_ CLKS – look them up in the datasheet.
  • The BSCANP pin should be tied to 0V to enable JTAG programming / debugging with the J-Link.

Coding

Just like Arduino, Teensy and PIC, programming is done in C or C++. For an IDE, Renesas makes their own modified version of Eclipse called e2 Studio, which is what I’ve used. It uses a GCC toolchain. The other option Renesas provides is a program called ARM DS-5, but I haven’t used it.

Download the installer for the RSK+. Make sure you get the version that includes e2 Studio rather than DS-5, unless you want to give that a try. The download will install e2 Studio and give you 10 or so example projects. It will also give you a very basic PDF “manual” for the setup, which will explain how to import the demo projects.

After importing the demo projects into e2 Studio, you should be able to run them on your RZ chip / board by connecting it to your computer via your J-Link, and clicking e2 Studio’s “debug” button. Hopefully, the code should compile, the debug perspective should open, and you should be able to step through the code as it runs on the RZ – just like any debugger.

It’s worth mentioning that all kinds of things can go wrong in e2 Studio. I’ve been using it for a couple of months and I still think it sometimes gets confused despite me selecting the correct options. For instance, most of the example projects have multiple run / debug configurations, called “HardwareDebug” and “Release”. I seem to have ended up in a situation a few times where (I think) the project is being “built” for one of the configurations, but then the debugger uses the other configuration, and consequently I can’t see the source code while debugging. And sometimes, no matter how much I fiddle with the options, I just can’t get a project out of this state. There are plenty of options relating to these configurations and to the debugger, so you’re going to have to use trial and error. If it’s not working, look at every option in the project’s properties, or maybe try another one of the example projects.

Most of the example projects relate to particular peripherals (e.g. a USB connection) which you may or may not have implemented in your PCB, so not all of them will be relevant. In any case though, if you can get the code to compile, and you can see it start to execute in the debugger, then you know that it’s working, so you can start changing the example code to do what you want for your own projects.

Using the example projects as a base to build my own programs on top of is the best way I’ve found to code for the RZ. e2 Studio does have an option to begin a “new” C or C++ project, and this does create you a project stub with a tiny bit of existing code, which you can successfully run using “debug”. Most of the example projects, though, contain some additional code (in the “compiler_specific” folder, much of it in assembly language) which sets a number of options for the RZ which make it run faster, allow interrupts, and more – all important stuff. I haven’t figured out exactly how to copy all of this functionality into a “new” project (it’s not straightforward), so I just build on top of the example projects. I also haven’t found a way to rename the example projects without getting build errors, so my own projects all have the names of the original example projects for the time being.

Another note: while the “debug” option in e2 Studio works, the “run” option gives me an error. The only way I can get my code to run on the RZ via my J-Link is with the “debug” option, which seems to be slower than ideal. Renesas’s tech support department gave me a cryptic answer to my question about this and didn’t seem to dispute that the feature wasn’t working as one would expect.

The example projects include code to perform most of the RZ’s core functions – UART, SPI, using individual pins for switches or LEDs, USB. This code is not presented in the same kind of user-friendly library form that you might be used to with Arduino or Teensy, though, so you can expect to have to poke around and modify things a lot.

There is also an SSI (Renesas’s name for I2s – audio output) example – not included in the RSK+ download, but in the sample code section of Renesas’s website. That one took some serious tweaking to get running though. I use a CS4344 DAC. You’ll need a dedicated audio crystal, too.

And, if you want to use SD cards, I recommend the FatFS library for handling the FAT filesystem. You’ll need to tie it to the RZ’s existing SPI “library” – for this connection, I modified FatFS’s example PIC24 implementation.

Hopefully (and if there’s enough interest) I’ll eventually find time to tidy up and release some of the “libraries” I’ve created myself from all of this example code.

Additional development quirks

  • If you use C++, you’re going to notice a frustrating problem: globally declared object variables don’t get their constructors called. See this thread for a long description of the problem by me, and a confirmation from someone more experienced that Renesas’s C++ implementation isn’t as it should be here. I found a work-around though: manually call the constructors of all your globally declared object variables once your program is running, e.g.:  new (&alreadyExistingObject) ClassName;
  • The example projects’ linker scripts aren’t properly set up for dynamic memory allocation (that is, calling malloc() or new), but it can be fixed. The explanation is a bit long – leave a comment if you want to know how to fix this, and I’ll add it here. And speaking of linker scripts, any time you change yours, you have to tell e2 Studio to “clean” your project before you build it, otherwise your changes won’t take effect.
  • Unbelievably, there seems to be no way to make a program “print” text out to the console in e2 Studio via the J-Link. Even Renesas’s tech support, when I asked them, said I’d need to use a USB serial connection. Currently, I’m obtaining a printout by having my RZ output text via a UART (non-USB serial) connection to an Arduino, which then relays the text back to my computer – clunky but it allows me to work.
  • Among other build options for GCC that e2 Studio gives you access to, there is link-time optimisation. Unfortunately, selecting this option doesn’t work. I found a way to manually achieve it though – leave a comment if you’d like me to write up how to do it. It has only a surprisingly small effect on performance, though it does make my program 20% smaller.

Running your program from flash memory

Above, I outlined how to write to your external flash memory using either a J-Link or a FlashCatUSB. The actual file you want to put onto the flash memory is the .bin file that’s generated by building, and will be sitting in either your project’s HardwareDebug or Release folder, depending on what configuration you’re using.

Hold on though – simply writing that file to flash memory won’t make it run correctly when the RZ powers up. Most of the example projects have linker scripts which assume the program is being run from RAM. The linker script would need to be changed significantly if the program was to be run directly from SPI flash. The RZ_A1H_Tutorial_RSK project includes an alternate linker script which can be used for this.

However, you don’t really want your program to run from SPI flash, because this would be slow, so don’t in fact change your linker script. What you instead want is a bootloader which runs from SPI flash, then loads your actual program from SPI flash into RAM and then runs it from RAM. The example project called RZ_A1H_QSPI_LOADER does just this. You need to build it and write the generated .bin file onto your flash chip at address 0x000000. Then write your actual program’s .bin file at address 0x080000, which is where the bootloader will look for it.

There’s another step! The RZ_A1H_QSPI_LOADER likely needs to be modified slightly before you can use it with a board that’s not the RSK+. This bootloader assumes, among other things, that there are two SPI flash chips connected, which is likely not the case on your board. The most fool-proof way of making it work (probably at the expense of some speed) is to go into the file src/spibsc_init2.c and comment out lines 225 to 229 – the ones under the comment “==== Sets the SPIBSC ====”. I’m still trying to determine whether there’s a better way than this, but it should at least get it up and running.

Another reason to build on top of the example projects rather than creating “new” projects is that the example projects are configured (via assembly language located in compiler_specific/asm/start.S) to present certain information (such as the program’s size) to the RZ_A1H_QSPI_LOADER. The RZ_A1H_QSPI_LOADER in fact won’t load any program which doesn’t have this.

And if you’re wanting to create a product which allows your users to update their firmware at a later date, you could modify the RZ_A1H_QSPI_LOADER to include the ability replace the actual program (which, remember, begins at 0x080000) on your flash chip. For instance, I’ve created a variant which loads a new firmware version from a file on an SD card and overwrites the old version on the flash chip. Modifying RZ_A1H_QSPI_LOADER is quite tricky though, since the configuration of its linker script and the way it operates is quite complicated, so be prepared to troubleshoot.

Let us know how you get on. It would be great to see some more people developing innovative hardware using this very powerful microcontroller.

Advertisements

Simple C code for resonant LPF / HPF filters, and high / low-shelving EQs

Lately, as part of a very ambitious project based on a Teensy / Arduino, I’ve had to code LPF and HPF filters – the resonant kind found in subtractive synthesizers – and also high- and low-shelving EQs.

I was surprised that an exhaustive search of the web didn’t turn up a simple, stock-standard way of doing this, and even many hours spent attempting to utilise what I did find yielded effectively nothing. Most documentation concerned using mathematical objects called Infinite Impulse Responses (IIRs) or Finite Impulse Responses (FIRs), but despite tearing my hair out playing with library implementations of these, I wasn’t able to make any usable sense of them whatsoever, and no amount of Googling seemed to help.

There’s actually a very easy way, though, as I was eventually forced to discover for myself.

The code snippets in this post are to be fed one audio sample at a time, and are in C code which will work on an Arduino / Teensy. I’ve used floats in the code, but these can be replaced with large integers for dramatically improved efficiency (this is probably mandatory for such code to run in realtime on an Arduino or Teensy prior to Teensy 3.0).

Non-resonant LPF

This is the simplest filter. All it needs to do is roll off the treble on an incoming stream of audio. The function achieves this by giving its output a “reluctance” to jump around fast. High-pitched sounds, with their quick oscillation, will be attenuated or nearly obscured, while slow-changing bass sounds will be all but unaffected. For each audio sample passing through the function, the function implements this reluctance by calculating how “far” its output will need to “move” (compared to what it outputted last time) in order to match its input – but instead of moving this whole “distance”, it just moves a certain fraction of the way. What this fraction is determines the cutoff frequency.

float lastOutput;

float doLPF(float input) {
    float distanceToGo = input - lastOutput;
    return lastOutput += distanceToGo * 0.125; // Lower / higher number here will lower / raise the cutoff frequency
}

Resonant LPF

This is what a subtractive synthesizer uses to get that congested, present sound, which with added modulation can create those classic “zappy” effects. What we want is to have the input signal’s treble chopped off, but to also accentuate / resonate a bit of the frequencies that reside just a little lower. To do this, our function is given a concept of “momentum”. Rather than simply place a dampener on the speed with which the output may move, as in the non-resonant LPF above, we instead give the output a sense of “inertia” – it will be resistant to moving, but once it gets moving, it will keep moving until it eventually gets pulled back in the other direction: it will resonate. This resonance can be lessened, though, if we wish, by allowing the output to retain some of the tendency, from the previous example, to move part-way towards the input at each sample, regardless of momentum.

float lastOutput;
float momentum;

float doResonantLPF(float input) {
    float distanceToGo = input - lastOutput;
    momentum += distanceToGo * 0.125; // Lower / higher number here will lower / raise the cutoff frequency
    return lastOutput += momentum + distanceToGo * 0.125; // Higher number here (max 1) lessens resonance
}

I was amazed when this simple code actually sounded like a classic synth-style resonant LPF! Sure, it’s not going to quite give you the analog warmth of some vintage unit, but at three lines of code, it’s more than acceptable.

Resonant HPF

Coding an HPF is slightly less intuitive. Basically, you make an LPF, and then subtract the output of that from the input signal, leaving only the higher frequencies. The momentum, required to make the filter resonant, has to be dealt with a bit differently. Here, I make the momentum dissipate over time (think friction). The rest… to be honest I’ve forgotten exactly why the code below is as it is – I arrived at it after much simplification of what earlier resembled far more explainable concepts. It still works great though, give it a shot!

float lastInput;
float lastOutput;
float momentum;

float doResonantHPF(float input) {
    lastOutput += momentum - lastInput + input;
    lastInput = input;
    momentum = momentum * 0.125 - lastOutput * 0.125; // First number controls resonance; second controls cutoff frequency
    return lastOutput;
}

High / low-shelving EQ

AKA the classic bass and treble controls. This is easy – we chop the treble off with an LPF, chop the bass off with an HPF (which again is a “backwards” LPF), and then mix back in however much of these we wish.

float withoutTreble;
float bassOnly;

float doShelvingEQ(float input) {

    // Treble calculations
    float distanceToGo = input - withoutTreble;
    withoutTreble += distanceToGo * 0.125; // Number controls treble frequency
    float trebleOnly = input - withoutTreble;

    // Bass calculations
    distanceToGo = withoutTreble - bassOnly;
    bassOnly += distanceToGo * 0.125; // Number controls bass frequency

    return withoutTreble + trebleOnly * 1 + bassOnly * 0;
    // The "1" controls treble. 0 = none; 1 = untouched; 2 = +6db
    // The "0" controls bass. -1 = none; 0 = untouched; 1 = +6db
}

Happy synthesizing!

Sensing hit-velocity and quick subsequent hits of a piezo with an Arduino / Teensy

Using a piezo and an Arduino / Teensy to create an electronic drum pad is not an unusual task. I wanted my pad to be velocity-sensitive however, and a quick search of the Web didn’t provide any code for doing this. Some pages suggested using a capacitor in the circuit to “hold” the piezo’s signal value for a longer time. But the method I eventually developed does not require any additional non-standard piezo circuitry – except I had to add an additional resistor to dampen the piezo’s signal, whose voltage got too high for my Teensy when hit hard. If your piezo’s signal is reaching your Arduino / Teensy’s maximum analogRead() level (usually 1023), you’ll need to do this too.

The stock-standard way to get Arduino code to register “hit” information from a piezo is to get it to listen to the analog input from it, and register a hit whenever the piezo’s signal rises above a certain threshold.

Determining velocity from the piezo’s signal, however, is a different story. At the point in time at which the piezo’s signal first rises above a given threshold, there’s no way for the code to predict whether the signal will continue to rise quite high, meaning a high-velocity hit, or whether it’s already almost arrived at its peak, which would mean a low-velocity hit.

I tried a few different methods, and the most accurate by far was: when the signal breaches the threshold, have the code spend the next couple of milliseconds or so looking out for the highest reading of the piezo’s signal. At some point during these first couple of milliseconds, the piezo’s signal will reach its peak, and the value of this peak is an accurate indicator of the hit’s velocity.

A note here – piezos have a polarity. Which way around you wire it will change what the signal looks like – and from my experience, it’s not necessarily clear-cut which way is better. I suggest you try both. On the pad / piezo that I worked with, when wired one way the signal rose to its peak in only about 0.5ms (good) but this peak was a poor indicator of velocity; the other way around the peak usually took around 2ms to reach (not as good but still fine) but was a much better indicator of velocity, but the piezo received much more “cross-talk” from hits to other pads on the same object.

Great, so now we have a velocity-sensitive drum pad. One problem though is that once our code has registered the hit, we have to tell it to stop “listening” to the piezo for a little while – say, 200ms – because the piezo’s signal will remain above the hit-threshold for a portion of this time, and we don’t want this to cause the incorrectly registering of any additional hits. This unfortunately means, however, that the user can’t perform hits too close together, or else the code will miss subsequent ones entirely. How can we get around this?

After a given hit, the piezo’s signal will fall gradually, and we can put this fact to use in our method of listening for a quick subsequent hit. We know that immediately after the initial hit, the piezo’s signal is likely to still be quite high – so we’d only want to register a subsequent hit if we saw the signal go really high. A few milliseconds later, though, we’d expect the piezo’s signal to have tapered off a bit after the initial hit, so our threshold for registering a subsequent hit would be lower.

Here is the code I came up with – functional for one single drum pad, and turning its signal into USB MIDI note-ons thanks to Teensy. The line which references usbMIDI is the only bit that won’t work on a non-Teensy Arduino. Fine-tune the code by altering the constants at the top – I’m sure these are heavily dependent on the the piezo and pad-object you’re using.

#define triggerThreshold 10 // If this is set too low, hits on other pads will trigger a "hit" on this pad
#define initialHitReadDuration 500 // In microseconds. Shorter times will mean less latency, but less accuracy. 500 microseconds is nothing, anyway
#define midiVelocityScaleDownAmount 2 // Number of halvings that will be applied to MIDI velocity
#define inputPin A0

// Getting the ideal balance of these two constants will ensure that fast subsequent hits are perceived accurately, but false hits are not generated
#define subsequentHitThreshold 1.7
#define subsequentHitThresholdDecaySpeed 14

uint16_t highestYet;
uint32_t startReadingTime;
uint32_t highestValueTime;
boolean hitOccurredRecently = false;

void setup() {
}

void loop() {

  // Assume the normal hit-threshold
  uint16_t thresholdNow = triggerThreshold;

  // But, if a hit occurred very recently, we need to set a higher threshold for triggering another hit, otherwise the dissipating vibrations
  // of the previous hit would trigger another one now
  if (hitOccurredRecently) {

      // Work out how high a reading we'd need to see right now in order to conclude that another hit has occurred
      uint16_t currentDynamicThreshold = (highestYet >> ((micros() - highestValueTime) >> subsequentHitThresholdDecaySpeed)) * subsequentHitThreshold;

      // If that calculated threshold is now as low as the regular threshold, we can go back to just waiting for a regular, isolated hit
      if (currentDynamicThreshold <= triggerThreshold) hitOccurredRecently = false;

      // Otherwise, do use this higher threshold
      else thresholdNow = currentDynamicThreshold;
  }

  // Read the piezo
  uint16_t value = analogRead(inputPin);

  // If we've breached the threshold, it means we've got a hit!
  if (value >= thresholdNow) {
    startReadingTime = micros();
    highestYet = 0;

    // For the next few milliseconds, look out for the highest "spike" in the reading from the piezo. Its height is representative of the hit's velocity
    do {
      if (value > highestYet) {
        highestYet = value;
        highestValueTime = micros();
      }
      value = analogRead(inputPin);
    } while (timeGreaterOrEqual(startReadingTime + initialHitReadDuration, micros()));

    // Send the MIDI note
    usbMIDI.sendNoteOn(0, (highestYet >> midiVelocityScaleDownAmount) + 1, 1); // We add 1 onto the velocity so that the result is never 0, which would mean the same as a note-off
    Serial.println(highestYet); // Send the unscaled velocity value to the serial monitor too, for debugging / fine-tuning
    hitOccurredRecently = true;
  }
}

// Compares times without being prone to problems when the micros() counter overflows, every ~70 mins
boolean timeGreaterOrEqual(uint32_t lhs, uint32_t rhs) {
  return (((lhs - rhs) & 2147483648) == 0);
}

Having tuned the above code for use in my own construction, I can say that it works very nicely, registering quick subsequent hits surprisingly accurately and giving consistent velocity values. It’s even fairly good at correctly registering the quick successive hits achieved by momentarily “dribbling” a drum stick with one hand. But it’s not perfect, and after a while spent fine-tuning the code’s approximation of the expected decay-shape of the piezo’s signal after an initial hit (used to determine what signal-change should count as another successive hit, as discussed above), I decided to bite the bullet and write an additional bit of code to actually record the real decay-shape of a given piezo attached to a given drum pad – so the code can really, really know if a change in input signal at a given number of milliseconds after an initial hit can count as another one.

I haven’t spent time commenting or fully documenting the resulting code, but in case it’s any use to you, here it is. The code listens to as many test-hits as you care to play it, and keeps a running high-score of the signal-level (relative to the overall velocity of the hit) at each number of milliseconds after the hit began. This is stored in your Teensy or Arduino’s EEPROM. Set “learning” to 1 to put it in this learning mode, and then back to 0 to have the code function normally. While in learning mode, make sure your hits are at least ~300ms apart – even one hit too soon would completely corrupt the learned data and you’d have to start again. Try to hit your pad in a variety of positions, at a variety of velocities.

#include <EEPROM.h>

#define triggerThreshold 3 // If this is set too low, hits on other pads will trigger a "hit" on this pad
#define initialHitReadDuration 500 // In microseconds. Shorter times will mean less latency, but less velocity-accuracy
#define midiVelocityScaleDownAmount 2 // Number of halvings that will be applied to MIDI velocity
#define inputPin A0

#define learning 0

uint16_t highestYet;
uint32_t startReadingTime;
uint32_t highestValueTime;
boolean hitOccurredRecently = false;
boolean newRecordSet;

void setup() {
  if (learning) {
    for (int i = 0; i < 256; i++) {
      EEPROM.write(i, 0);
    }
  }
}

void loop() {

  // Assume the normal hit-threshold
  uint16_t thresholdNow = triggerThreshold;

  // Read the piezo
  uint16_t value = analogRead(inputPin);

  uint32_t msPassed;

  // But, if a hit occurred very recently, we need to set a higher threshold for triggering another hit, otherwise the dissipating vibrations
  // of the previous hit would trigger another one now
  if (hitOccurredRecently) {

      uint32_t usPassed = micros() - highestValueTime;
      msPassed = usPassed >> 10;

      if (learning) {
        if (msPassed >= 256) {
          hitOccurredRecently = false;
          if (newRecordSet) {
            Serial.println("----------------------------------------");
            for (int i = 0; i < 256; i++) {
              Serial.print(String((int)EEPROM.read(i)) + ", ");
              if (i % 16 == 0) Serial.println();
            }
          }
        }
        else {
          uint16_t nowComparedToHighest = ceil((float)value / (float)highestYet * 256);
          uint8_t previousRecord = EEPROM.read(msPassed);
          if (nowComparedToHighest > previousRecord) {
            newRecordSet = true;
            EEPROM.write(msPassed, min(255, nowComparedToHighest));
          }
        }
        thresholdNow = 1024;
      }

      else {
        if (msPassed >= 256) hitOccurredRecently = false;
        else {
          // Work out how high a reading we'd need to see right now in order to conclude that another hit has occurred
          uint32_t currentDynamicThreshold;
          if (usPassed < initialHitReadDuration) currentDynamicThreshold = highestYet;
          else currentDynamicThreshold = ((uint32_t)EEPROM.read(msPassed) * highestYet) >> 8;

          thresholdNow += currentDynamicThreshold;
        }
      }
  }

  // If we've breached the threshold, it means we've got a hit!
  if (value >= thresholdNow) {

    startReadingTime = micros();
    highestYet = 0;

    // For the next few milliseconds, look out for the highest "spike" in the reading from the piezo. Its height is representative of the hit's velocity
    do {
      if (value > highestYet) {
        highestYet = value;
        highestValueTime = micros();
      }
      value = analogRead(inputPin);
    } while (timeGreaterOrEqual(startReadingTime + initialHitReadDuration, micros()));

    // Send the MIDI note
    usbMIDI.sendNoteOn(0, (highestYet >> midiVelocityScaleDownAmount) + 1, 1); // We add 1 onto the velocity so that the result is never 0, which would mean the same as a note-off
    Serial.println(highestYet); // Send the unscaled velocity value to the serial monitor too, for debugging / fine-tuning
    hitOccurredRecently = true;
    newRecordSet = false;
  }
}

// Compares times without being prone to problems when the micros() counter overflows, every ~70 mins
boolean timeGreaterOrEqual(uint32_t lhs, uint32_t rhs) {
  return (((lhs - rhs) & 2147483648) == 0);
}

Update 2015-02-15: I have since developed a version of this sketch to work with multiple drum pads simultaneously, plus some other improvements. Apologies – this is even more un-commented than the above code, but if you do want to take a look, download it here.

An advanced MIDI foot-controller

P1050317

Building MIDI controllers is something I’ve spent a lot of time doing lately. As the user of an increasingly complicated computer-based music setup, involving processing a guitar signal and software synthesizers, currently based in Sensomusic Usine Hollyhock, there seems to be no limit to the number of parameters I want to control, or the number of things I want to be able to switch on and off.

So for my latest foot controller, I decided to make it as fully-featured as possible:

  • Compact and foldable USB MIDI foot controller
  • 36 metal footswitches
  • RGB LEDs for most of the switches – which respond to MIDI data coming back from the connected computer
  • A 6-character alphanumeric display, for selecting and displaying the names of presets
  • Connectivity with two external expression pedals
  • One of the footswitches is a “bank select” switch, so if I run out of switches to assign functions to, I can simply switch to the next bank
  • Large LEDs on the left to indicate the recording / playing status of Mobius – a software loop pedal
  • All LEDs flash white to the tempo of whatever loop I’ve created in Mobius, and a headphone jack plays a metronome-style click – to keep my (hypothetical) drummer in time with the loop

P1050323 P1050309 P1050305

I regret not taking more photos while I was constructing this – as you can hopefully see, it’s made from a lot of pieces of wood cut to size and with holes in carefully worked out places.

 

The brain

The central component in this foot controller is a Teensy++ 2.0 microcontroller. Teensies are an excellent choice for building MIDI controllers. They are compatible with Arduino – probably the most popularised and easy-for-beginners microcontroller – but unlike Arduinos, Teensies can appear to your computer as a MIDI device when connected by USB – exactly what we want here. They arguably also have better specs, especially for the price. (If you’re super-new to microcontrollers, a microcontroller is a “computer” on a tiny chip / circuit board, which will execute computer code which you write and upload to it – code which defines how it will interact with its connected components, like LEDs and switches.)

teensy

 

LEDs and switches

I can’t really give a good functional reason as to why I chose to use RGB LEDs rather than a single colour. The idea of being able to choose later, via software, what colour each separate one should be, and to have an eye-catching, multi-colour artifact, just seemed too alluring, even though the extra wiring involved added a few hours onto the project.

The LEDs and switches are connected in an “array” – a configuration which allows for many more LEDs and switches to be connected to the microcontroller than it has individual pins. In the configuration I’ve used, the LED and switch arrays share “ground”, or “column” as I’ve labelled them below, pins between the two arrays – an “original” method which I can’t find any other documentation on anywhere on the web. It works great, and saves a bunch of wiring.

This two-in-one array has 9 “column” connections to the microcontroller, 12 “row” LED connections (to write to all of the red, green and blue pins of 4 LEDs at the same time), and 4 “row” switch connections. I’ve used the words “row” and “column” here because the most common physical appearance of an LED or switch array is as a grid with rows and columns, so these concepts should be familiar to those who have worked with LED or switch arrays before. I’m not referring to the physical arrangement of the LEDs and switches in my foot-controller – in fact, the way I’ve configured it, a “row” refers to one of the four panels of the foot-controller, and a “column” refers to one of  the 9 “positions” that a switch / LED may take on any one of these four panels.

Because of the amount of current required to return into each “column” connection (the “row” connections don’t need to handle as much current in one go), each of the 9 “column” connections has to be buffered with a 2n2222 transistor. This allows all of the LEDs to be lit brightly enough.

The above schematic shows a bare-bones representation of this configuration – with just 4 single-colour LEDs and 4 switches (2 rows, 2 columns). In terms of Arduino / Teensy code to drive this configuration, you activate a “column” by making its “column” pin HIGH (not LOW as you might be used to, because the added transistor reverses the effect). Once a “column” is activated, you then switch on whichever of its LEDs you wish to by making the corresponding LED “row” pin HIGH, and you may also read either of the column’s switches by doing a digitalRead on the appropriate switch “row” pin, which you will have initially set up as an “INPUT_PULLUP” pin. The digitalRead will return HIGH/TRUE  if the switch is “open”, and LOW/FALSE if “closed”.

If you want more LEDs and switches, simply add columns and rows as required. For RGB LEDs, you’ll simply need 3 row-pins per “row” of LEDs.

Ideally, I should have actually added a diode in series with each switch. As a result of not having done so, pressing two switches simultaneously causes undesirable behaviour from the LEDs on the affected columns, and if I were to press three or more switches simultaneously, the microcontroller could “detect” additional switch-presses which aren’t really happening. That’s something I’d change next time – but for now, I usually only press one switch at a time anyway.

 

Expression pedals

Two inputs at the back allow for the connection of expression pedals, and this data is sent to the computer as 14-bit MIDI CC commands (although the Teensy++ 2.0 only actually reads the pedals in 10-bit).  I recommend getting a Daphon DF2210 off Ebay (it’s the cheapest Wah pedal out there) and modifying it to be an external expression pedal – they are very well suited to this. I may write another post about this in the future.

P1050342

 

Switching things

In its simplest form, this foot-controller is for switching individual guitar effects on and off. I use Sensomusic Usine Hollyhock as a live audio processing solution, hosting numerous effects, and being able to switch them on and off in the traditional foot-controlled way is essential.

Building on this functionality, the LEDs on the foot-controller don’t just light as a direct result of pressing a switch – instead, pressing a switch sends a MIDI command to the computer, the computer then switches the relevant effect on, and then sends a MIDI command back to the foot-controller saying that it’s been switched on, and the foot-controller then lights the LED to communicate this to the user. The advantage of doing it this way is that if I do something like change what preset I’m using on the computer, the computer can then tell the foot-controller what effects are now on or off, and the LEDs on the foot-controller update accordingly.

UPDATE: Since originally writing this post, I’ve discovered that Usine natively supports this kind of two-way communication with switches / LEDs, which is great news. Previously, I’d created complex scripts / patches in Usine and Bidule to implement this functionality.

 

Looping with Mobius

If you like loop pedals and are interested enough in computer-based live music to be reading this post, you should check out Mobius by Circular Labs. It has all the functions of a traditional loop pedal, plus a whole lot of extras (changing the loop speed or pitch, duplicating it so it’s twice as long, reversing, having multiple tracks…) – it’s so customisable in fact that it even has its own scripting language. It can be controlled by a MIDI foot-controller, so can behave very much like a loop pedal does.

Ideally you’ll also want some visual feedback of what’s going on with your looper though, and so I built into this foot-controller two large LEDs at the far left end – a red one to indicate “recording”, and a green one for “playing”. They’ll both light at the same time when I’m overdubbing. As far as the foot-controller is concerned, these LEDs respond to MIDI commands coming in from the computer / software, just like all the other LEDs. In order to get Mobius to send the correct commands to control the LEDs, I had to write scripts using its scripting language.

P1050325

Many hardware loop pedals have an LED which flashes to the tempo of a loop the user has created – a great feature for keeping in time with a loop if you can’t quite hear it clearly enough. My foot-controller does the same – while a loop is playing, every LED flashes white to the tempo. Mobius makes this easy – if configured correctly, any time a loop is playing, it will continuously output MIDI “clock” commands to indicate the tempo. If these are routed correctly, the foot-controller will receive these commands and flash the LEDs accordingly.

Taking things a step further still, I added a headphone jack to output a metronome-style “click”, to easily enable a drummer or anyone to keep in time with a playing loop. A volume pot is discretely accessible with a screwdriver, hiding down one of the holes beside the switches and LEDs. A couple of resistors and capacitors were needed for this circuit too. If only we’d had such a tool available in my old band, where in order to attain headphone “clicks” we instead came up with an Arduino-based solution involving blu-tacking a light-sensor onto a hardware loop pedal’s tempo-flash LED!

 

Alphanumeric display, and advanced interfacing with Usine

The alphanumeric display also shares 6 of the 9 “column” connections for the LED / switch array (see above), then has an additional 15 “row” connections from the microcontroller to control all 15 possible display-segments of a character of text.

P1050334

Usine is an exceptional piece of audio software. Not only will it let you patch audio and MIDI between plugins in any configuration imaginable, you can do the same for every parameter of a plugin or softsynth. You can even patch “arrays” of data between modules. And on top of all that, you can even create your own modules easily by programming in Pascal, allowing for advanced customised functionality.

usine patch

A portion of my current Usine patch. The audio “cables” are the green ones, midi is blue, and red and grey are data / control.

This will have to await a full explanation in a future post, but by creating some very custom scripts within Usine to allow two-way communication with the foot-controller, the foot-controller may be used to load or save a “preset” of plugin settings in Usine, selected by the preset’s name which is viewable on the foot-conroller’s alphanumeric display. The resulting system behaves a lot like a multi-fx pedal, but hugely more customisable and not only limited to guitar.

 

Source code

Feel free to message me if you’d like a copy of the source (Arduino / Teensy) code. It’s still a bit messy since I’ve developed it in quite a hurry, and hopefully I’ll eventually make it public on this page after it’s been refined some more.

How to use your computer as a foot-switchable guitar FX processor with Plogue Bidule

Have you ever thought of using your computer as a live guitar FX setup? Depending on what you want to do musically, this approach can have tremendous advantages. Not only will it probably be cheaper than a traditional hardware-based setup, it will also be smaller, lighter, and far more customisable. Maybe you want a more compact setup for when you go on tour. Or maybe you want to be able to change the order in which your effects are connected to each other, quickly and without messing around with patch cables. Or you want to store a number of “presets” for different songs, to avoid having to memorise and quickly recall the correct positions for all those hardware knobs. Perhaps you’re even interested in taking your setup beyond guitar-only territory and syncing a virtual drum machine up to your looper, and having a play with some software synthesizers while you’re at it. These more advanced applications will have to await explanation in future blog posts, but following the information in this post, you will easily be able to set your computer up to run a few guitar effects, and set them to be switched on and off with a foot-controller.

The idea of using a computer as a guitar FX processor can certainly be a daunting thought if you haven’t investigated the possibility before, and you’ll likely have some questions like: What software should I use? What hardware do I need? And will it really sound as good?

The question of whether it will sound good is possibly your number one concern. Historically, digital guitar FX have frequently failed to achieve the sound quality of their analog predecessors. Distortions, especially, have often sounded artificial when created digitally. However, the technology has improved significantly in recent years, and while I can’t quite guarantee that you’ll arrive at a computer-based setup which sounds as good as your analog pedals in every way, it is no longer an impracticality to end up with something at least workable, and at best excellent in terms of sound. See the bottom of this post for some specific plugin recommendations.

Many modern guitar FX pedals (particularly loopers, digital delays and pitch shifters) are purely digital anyway – they’re technically a computer, just a very low-spec, stripped-down one, set to perform only one relatively simple function. Your laptop, which you already own, is thousands of times more powerful, so it’s not hard to wonder: “Is there any way that I could just use my laptop in place of all these units that I keep spending $200+ on?” The answer is yes.

Finding a suitable audio interface

Many common audio interfaces are completely unsuitable for processing live guitar sound because their “round-trip latency” (the amount of time it takes for your guitar signal to go into the interface, get processed by your computer, and come back out again) is too high. With the wrong interface, there will be a noticeable delay between you hitting your instrument’s strings and you hearing the resulting sound.

Audio interfaces also vary in terms of the smoothness with which their drivers allow your computer to process audio in low-latency configurations. One audio interface might allow you to run hundreds of plugins simultaneously without problems, while with another you might notice audible crackling while only running a few as your CPU struggles.

Fortunately, the good folks at DAWbench have put a number of modern audio interfaces to the test under a variety of conditions. Their latest tabulated results are viewable here. (It should be noted that these tests were done on Windows, with the interfaces’ Windows drivers. Unfortunately I don’t know of any equivalent collation of data for Mac, but the optimist in me suggests that the results should be similar… hopefully.)

To summarise DAWbench’s findings, assuming that you want a USB-connecting device, and that two channels of input and output are sufficient, the most suitable device is the Avid Mbox 3. It can happily operate at a round-trip latency of 10.476 milliseconds, and will allow you to run more plugins simultaneously than any other USB device in this category, except for the super-pricey RME Babyface.

 mbox 3

10.476 milliseconds is certainly the highest you’d want to go in terms of round-trip latency. Any higher, and the delay will begin to become audible. But, 10.476 milliseconds is completely adequate, and is about the best you can do without either spending a fortune on the Babyface, or going for a FireWire (becoming obsolete) or PCI (desktop computer only) interface, or conceding to use less plugins at once than your computer would otherwise be capable of.

Software guitar effects

There are a number of pre-packaged software guitar FX solutions which you can buy, to do everything, all with just one product. The most well-known would be Guitar Rig and Amplitube. Go ahead and give them a try – perhaps they’re sufficient for what you want to achieve. The problem with these packages though is that they lack flexibility. You don’t like the chorus effect in Guitar Rig? Tough.

A far more customisable solution is to hand-pick your individual effects in the form of VST plugins (or AU plugins, but VSTs are far more common). This instantly puts thousands of different effects at your fingertips, as there are vast quantities of VST plugins available online for free or purchase.

VST plugins require a “host” program in order to connect them all together, and to allow your guitar signal to flow into them from your audio interface, and then back out again.

At the original time or writing this article, my program of choice for this purpose was Plogue Bidule, which is very good. I’m adding a mention here that I’ve since switched to Sensomusic Usine, which is far more powerful in terms of programmability, and efficiency on multi-core processors, and has a very usable free version. Anyway, with that noted, let’s get back to the original article on Bidule.

Bidule takes a “modular” approach to audio and MIDI. Whereas more common audio software such as Ableton Live or Reaper has the user organise things primarily within “tracks”, Bidule operates much like a guitarist’s pedal-board – your individual effects are each represented within the program as a small box with inputs and outputs, and you choose how to route the audio between these. This makes Bidule perfect for processing live effects for guitar.

bidule stock

Bidule costs $95 USD. There is a trial version of Bidule available here… sometimes. Curiously, each time Plogue releases a new version of Bidule (a couple of times a year), they make a trial version available which expires three months later. So if you’re reading this within three months of a Bidule release, you can try it out right now. Otherwise, you’ll have to wait until the next release.

There are a few other similar “modular” host programs which you might like to consider too. The well-known ones are Max/MSP, Reaktor, AudioMulch, and Usine. As I noted above, since originally publishing this post, I have now switched to Usine – it’s fantastic. Max/MSP isn’t really suitable because it has very limited support for hosting VST plugins – the very thing we want to do here. I haven’t used Reaktor or AudioMulch.

Playing your guitar through plugin effects in Bidule

So, you’ve got your audio interface plugged in and its drivers installed. You’ve got Bidule installed. You’ve got your guitar plugged into your audio interface’s input, and your audio interface’s output is going to your guitar amp just like the output from your final pedal normally would. Optionally at this stage, you might have a VST effect or two installed on your computer too.

First, let’s check that your audio interface is on the correct latency setting. Every audio interface should have a configuration panel which will allow you to set the latency or “buffer size”. Too high, and you’ll notice an audible delay in your guitar signal. Too low, and your computer will complain, probably by making your audio crackle. “128 samples” is probably the setting you want here, and in my experience is usually the best trade-off between the two extremes.

Next, open Bidule and create a blank project.

bidule 1

We want your Bidule workspace to contain a representation of your audio interface, so that we can receive its input, and then send it back output. Open up the “palette” (button at the top). Go Audio Devices -> Duplex -> ASIO, and then select your audio interface from the resulting list by dragging it onto the grey workspace.

bidule 3

Before we add any effects, let’s check that we’ve got audio correctly passing through the system. Assuming you’ve got your guitar plugged into input 1 on your audio interface, and it is output 1 that’s plugged into your amp, let’s create a virtual “patch cable” within Bidule by dragging from your audio interface’s first input to its first output.

bidule 4

All going to plan, you should now hear your guitar signal coming out of your amp. It’s passing through Bidule without being altered at this stage. Hopefully there’s no audible latency to the signal. If there is, check your audio interface’s latency settings, or consider the possibility that your audio interface might not be suitable for live guitar playing (see the “finding a suitable audio interface” section above).

Next, let’s try adding an effect in Bidule. If you have any VST effects installed and Bidule knows where they are (Edit -> Preferences -> VST -> VST Plugins path), then great – they’ll be available in the palette, under “VST”. If not, you can try one of Bidule’s built-in effects, such as the flanger available under “Effects” in the palette. Modify your patching arrangement now, so that your effect sits between your audio interface’s input and output in Bidule.

bidule 5

Hopefully you can now hear the effect being applied to your guitar signal. Well done – your computer is now a guitar FX processor.

Foot-switching your effects

Having your computer successfully processing guitar FX for you is great, but if you’re used to using pedals, you’ll probably want a way to switch them on and off with your feet. This is normally done using a “MIDI foot-controller” – a foot-switch device which plugs into your computer via USB. Such a device will communicate with your audio software (Bidule) via MIDI messages.

behringer

The most popular MIDI foot-controller is probably the Behringer FCB1010. It’s very fully-featured, as you can see above – 10 switches and even two expression pedals (yes, you can make use of them too with VST effects hosted in Bidule). If you want something cheaper, and perhaps don’t require so many switches, try searching on eBay for “usb midi foot controller” – there are a bunch of no-brand models which will work fine. It’s also surprisingly easy to build your own using a Teensy microcontroller. (Update: I’ve written about how I built one.)

Assuming that you now have a MIDI foot-controller, go ahead and plug it into your computer. Restart Bidule, and create an instance of your MIDI controller (an “input” instance) on your workspace, like so:

bidule 6

Bidule will allow you to switch an effect on and off with this controller’s MIDI data. Setting this up is a little tricky though, and requires the use of some of Bidule’s “building block” objects to manually create this behaviour by wrangling logic. So, I’ve done most of the work for you: one of Bidule’s great features is that it allows you to create and save “groups”, whose inner workings can be taken for granted. Download this one, and drag the file onto your Bidule workspace. Then patch your MIDI controller’s output (in the sense that it’s outputting data into Bidule) to my group (the MIDI-controlled bypass switcher)’s input.

bidule 7

Next, double-click on the MIDI-controlled bypass switcher to bring up its parameters. Enter the “note number” of the particular switch that you want to use on your foot-controller. (Check its instructions or experiment; hopefully note “0” will correspond to one of your switches.)

bidule 8

And finally, link the MIDI-controlled bypass switcher to the effect you wish to control – open the “parameters” window (button at top), and link the MIDI-controlled bypass switcher‘s “Mode controller” to your effect’s “Mode” by selecting both parameters (switcher on the left; effect on the right) and clicking “link”.

bidule 10

If you selected the correct “note number” for your foot-switch, pressing it should now toggle your effect between being bypassed and not, just like a conventional hardware guitar pedal. You’re good to go – your computer is now a foot-switchable guitar FX processor.

We’ve only just scratched the surface of what’s possible in Bidule though. If you get the urge, ctrl+doubleclick on my MIDI-controlled bypass switcher group to see the logic going on inside it (it also contains another group which you can also ctrl+doubleclick into). These groups’ behaviour is constructed from a number of low-level “building blocks”, which can be used to create almost any kind of behaviour you could describe in words. Maybe you want to use “forward” and “back” foot-switches to cycle you through a number presets, like on a hardware multi-FX unit. Or you want to make use of other inputs like knobs or an expression pedal. Not to mention the possibilities for manipulating MIDI data if you want to get into using software synthesizers. Bidule can be set up to do it all, and I strongly encourage you to get experimenting.

Plugin recommendations

Since delving into the world of computer-based guitar effects, I’ve trialed a range of plugins, often with the aim of creating similar sounds to the analog, hardware setup that I used previously. Here are some recommendations.

DelaySoundToys EchoBoy is the best I’ve found. It can do analog-sounding delays beautifully, and has a lot of options.

Distortion / amp simulation: Ohmforce Ohmicide is the only distortion plugin I’ve found which produces a reasonably-believable tube-like distortion, for use if you’re using a traditional guitar amp for your amplification. However, another option is to ditch your guitar amp entirely and delve into the world of guitar amp simulation. The idea here is to use software to mimic the characteristics of a tube amp and speaker cabinet, so you don’t need a real guitar amp (you’d instead run your audio interface’s output through monitor / PA speakers). One product completely blows the others away in this department – Scuffham S-Gear. Other common ones are Guitar Rig, Amplitube, and Vintage Amp Room. None of them come close. S-Gear’s simulated tube amps give better-sounding distortion than Ohmicide, too. Give it a try – S-Gear has a free 14-day trial. And it can be further improved if you opt to replace its basic speaker-simulation section with some “impulse responses” from RedWirez, which you’ll need to use with a convolution plugin like SIR2.

Looping: Mobius, by Circular Labs, is an advanced looping plugin – so advanced that it even has its own programming language if you want to customise it beyond its basic settings. Functions can be assigned to MIDI foot-switches, making it easily functional and powerful enough to replace a traditional loop pedal.

Pitch shifting / whammy effects: Ckpitchshifter (scroll down the page) is the best real-time pitch shifter plugin I’ve found. I wasn’t able to find many other options in this department – recommendations anyone?

Chorus / modulation: D16 Syntorus is pretty good, and the SoundToys EchoBoy has a CE-1 emulation preset which sounds good too.