Hello guys,
I have been working since the arrival of my Teensy 3.5/3.6 on a guitar distortion/amp modeling code that is now sufficiently mature to share with you.
The hardware implementation is not the greatest as it is just a bunch of components hooked together but it works pretty well in a typical hacker fashion...:
- An high impedance input buffer for guitar signal: here DIY "Klon" type buffer = transparent opamp buffer with a little less than unity gain (see here : http://tagboardeffects.blogspot.ch/2011/04/klon-buffer.html ).
- a MicroE WM8731 audi codec board but PJRC Audio board should work as well with a little bit more noise though.
- A Teensy 3.5 (the one I use now) or 3.6 (better, but I fried mine...).
- A 2.2'' 320x240 ILI9341 TFT for GUI.
- Two latching foot switches: one for True bypass, the other for preset switching.
- One simple switch to trigger preset or editing mode
- 4x 100k linear rotary potentiometers for master volume, gain, treble and bass controls
- one rotary encoder + switch for menu navigation and editing (type EC11 or similar).
My quick and dirty development prototype pedal looks like this:
My code is based on Teensy audio library and its 32bit floating point extension by Chipaudette (Openaudio arduino library).
The distortion modeling implements the following elements :
- a pre-eq & pre-impulse (FIR) filter for tone shaping before distortion
- a compressor and noise gate (pre distortion)
- up to 4 distortion stages (single or push-pull tube stage or waveshaper based stage) each with their own pre- and post gains as well as bias, low and high pass filters. All distortion and pre filters are implemented in 32bit floating point for maximum dynamics and distortion can run up to 2x oversampling with Hermite or cubic interpolation of the waveshaping tables on Teensy 3.5 in real time (86% peak cpu load with everything on). The code is based on the concept of independent waveshapers with their own filtering and coupled through adjustable high pass filters which allows to capture the dynamic excursion of input voltage (dynamic shift of bias/operating point).
- a post FIR and post EQ for modeling a tone stack or final shaping of the sound.
- optional support for USB audio input and output to act as a sound card (both mixed with physical inputs and outputs) and an option to "plot" the input/out (Arduino plotter tool) for debugging.
- 4 banks of 4 dual (A/B) presets, for a total of 32 presets stored in Teensy's EEPROM
The signal flow is shown in the picture below:
In terms of Audio processing objects, I have implemented those new elements (in floating point):
- a single stage waveshaper distortion block with variable oversampling and different interpolation types (my first steps, unused in latest version)
- a multistage distortion object with many waveshaping tables for tubes (12AX7, 12AT7, 12AU7, 6V6, KT88), and other classic mathematical waveshaping functions (hyperbolic tangent, cubic and asymmetric laws of Doidic et al, power or exponential laws, soft clipping). Each stage can be eitehr single ended or push-pull and bias can be adjusted on the fly to generate different levels of odd/even harmonics. The DSP code performance can be adjusted to select different types of table interpolation (linear, quadratic, cubic spline of Hermite), change the number of point of the wave tables or choose between 1x or 2x oversampling. All the code is floating point 32bit.
- a simple compressor/noise gate block (noise gate needs to be fixed though).
- an easy to use floating point IIR equalizer block with automatic calculation of coefficients for high or low pass, peak or shelving filters.
The GUI code is relatively well separated from the processing and it implements a simple menu system with "bar" representation of parameter values for interactive parameter editing and a preset management system (not the cleanest code so might be difficult to port).
The code is available here with some simple docs: https://github.com/jcugnoni/TeensyDist
My short term plan is to add more waveshaping table for solid state stages and improve/add other impulse for improved tone shaping, and also implement a sag model for a more dynamic feel (you can already get some sag by using the compressor though: gain 2.5, threshold 0.4, attack 250ms, release 250ms). Another point could be to add a simple cabinet simulation and tone stack module as a cascade of IIR filters. At the moment, I prefer to use a Raspberry Pi 3 with jconvolver for high resolution (3k sample stereo) impulse response modeling of cabs... another project that I need to document.
Longer term, I would like to further develop my Octave amp/pedal profiling & identification code to allow anyone to capture the impulse response and match the distortion characteristics of his own gear as other commercial products already do. A simple approach based on swept sine and harmonic content analysis seems to already work in some cases but I would like to be able to automate it and maybe implement it in the Teensy.
Anyway, i hope that you will like it.
Feel free to test, improve this code as you wish, or maybe if you want to to port this code to another architecture...
I have not much time to maintain it but I will appreciate any feedback.
I have been working since the arrival of my Teensy 3.5/3.6 on a guitar distortion/amp modeling code that is now sufficiently mature to share with you.
The hardware implementation is not the greatest as it is just a bunch of components hooked together but it works pretty well in a typical hacker fashion...:
- An high impedance input buffer for guitar signal: here DIY "Klon" type buffer = transparent opamp buffer with a little less than unity gain (see here : http://tagboardeffects.blogspot.ch/2011/04/klon-buffer.html ).
- a MicroE WM8731 audi codec board but PJRC Audio board should work as well with a little bit more noise though.
- A Teensy 3.5 (the one I use now) or 3.6 (better, but I fried mine...).
- A 2.2'' 320x240 ILI9341 TFT for GUI.
- Two latching foot switches: one for True bypass, the other for preset switching.
- One simple switch to trigger preset or editing mode
- 4x 100k linear rotary potentiometers for master volume, gain, treble and bass controls
- one rotary encoder + switch for menu navigation and editing (type EC11 or similar).
My quick and dirty development prototype pedal looks like this:
My code is based on Teensy audio library and its 32bit floating point extension by Chipaudette (Openaudio arduino library).
The distortion modeling implements the following elements :
- a pre-eq & pre-impulse (FIR) filter for tone shaping before distortion
- a compressor and noise gate (pre distortion)
- up to 4 distortion stages (single or push-pull tube stage or waveshaper based stage) each with their own pre- and post gains as well as bias, low and high pass filters. All distortion and pre filters are implemented in 32bit floating point for maximum dynamics and distortion can run up to 2x oversampling with Hermite or cubic interpolation of the waveshaping tables on Teensy 3.5 in real time (86% peak cpu load with everything on). The code is based on the concept of independent waveshapers with their own filtering and coupled through adjustable high pass filters which allows to capture the dynamic excursion of input voltage (dynamic shift of bias/operating point).
- a post FIR and post EQ for modeling a tone stack or final shaping of the sound.
- optional support for USB audio input and output to act as a sound card (both mixed with physical inputs and outputs) and an option to "plot" the input/out (Arduino plotter tool) for debugging.
- 4 banks of 4 dual (A/B) presets, for a total of 32 presets stored in Teensy's EEPROM
The signal flow is shown in the picture below:
In terms of Audio processing objects, I have implemented those new elements (in floating point):
- a single stage waveshaper distortion block with variable oversampling and different interpolation types (my first steps, unused in latest version)
- a multistage distortion object with many waveshaping tables for tubes (12AX7, 12AT7, 12AU7, 6V6, KT88), and other classic mathematical waveshaping functions (hyperbolic tangent, cubic and asymmetric laws of Doidic et al, power or exponential laws, soft clipping). Each stage can be eitehr single ended or push-pull and bias can be adjusted on the fly to generate different levels of odd/even harmonics. The DSP code performance can be adjusted to select different types of table interpolation (linear, quadratic, cubic spline of Hermite), change the number of point of the wave tables or choose between 1x or 2x oversampling. All the code is floating point 32bit.
- a simple compressor/noise gate block (noise gate needs to be fixed though).
- an easy to use floating point IIR equalizer block with automatic calculation of coefficients for high or low pass, peak or shelving filters.
The GUI code is relatively well separated from the processing and it implements a simple menu system with "bar" representation of parameter values for interactive parameter editing and a preset management system (not the cleanest code so might be difficult to port).
The code is available here with some simple docs: https://github.com/jcugnoni/TeensyDist
My short term plan is to add more waveshaping table for solid state stages and improve/add other impulse for improved tone shaping, and also implement a sag model for a more dynamic feel (you can already get some sag by using the compressor though: gain 2.5, threshold 0.4, attack 250ms, release 250ms). Another point could be to add a simple cabinet simulation and tone stack module as a cascade of IIR filters. At the moment, I prefer to use a Raspberry Pi 3 with jconvolver for high resolution (3k sample stereo) impulse response modeling of cabs... another project that I need to document.
Longer term, I would like to further develop my Octave amp/pedal profiling & identification code to allow anyone to capture the impulse response and match the distortion characteristics of his own gear as other commercial products already do. A simple approach based on swept sine and harmonic content analysis seems to already work in some cases but I would like to be able to automate it and maybe implement it in the Teensy.
Anyway, i hope that you will like it.
Feel free to test, improve this code as you wish, or maybe if you want to to port this code to another architecture...
I have not much time to maintain it but I will appreciate any feedback.