At their heart, computer processors run machine code. This is the series of 1s and 0s called bits(Binary digITS) that the device translates into voltage highs and lows used to control the display, keyboard, motor, switches, lights and so forth, in whatever system it’s being used. This is true whether the device is the CPU in your laptop, the microcontroller for your car brakes, or the DSP in your digital effects pedal.
A binary bit stream looks like this:
In the early days of computing, engineers divided up the bits into groups of eight called octets, which came to be known as bytes. Eight 1s and 0’s provides 256 possible permutations, which can be used to represent human readable characters such as letters of the English alphabet. There’s a standard code for this that most systems use called ASCII. Let’s divide the bit stream into bytes:
1001101 1101001 1110011 1110011 1101001 1101111 1101110
That’s still a lot of digits. Hexadecimal, or base 16, is a convenient way to remap these values to something easier to handle, so let’s convert these to hex. For example 01100111 is 67 in hex. That reduces 8 digits down to two. Here’s our full binary stream in hex:
4D 69 73 73 69 6F 6E
Now if we If we convert those to ASCII, our long bit stream at the beginning becomes:
So, we may see a piece of machine code that looks something like this:
0x 60 00 00 80
0x A4 00 00 00
0x 60 01 00 84
0x A4 01 01 00
0x 60 02 00 00
0x 60 03 00 04
0x 60 04 00 00
0x 60 05 00 01
0x 08 00 00 02
0x 20 00 00 03
0x 20 04 04 05
0x 11 20 04 01
Even using hex, it’s very slow and error prone writing complex programs like this, so there are some further translations we can do. Assembly language is specific to the actual processor, but uses some more human readable and writable language. After writing the assembly code, we run it through a specialized program called an assembler. This translates the human written text files into object files of machine code that the processor can run. Here’s an example of some assembly code:
ADR r4,a ; get address for a
LDR r0,[r4] ; get value of a
ADR r4,b ; get address for b, reusing r4
LDR r1,[r4] ; get value of b
ADD r3,r0,r1 ; compute a+b
ADR r4,c ; get address for c
LDR r2,[r4] ; get value of c
Assembly language may be preferable in some cases in signal processing where certain timing issues may be easier to deal with. However, in many cases a higher-level programming language such as C may be appropriate. Here’s the equivalent to the above in C:
x = (a + b) – c; // Calculate x
C is a compiled language. You can write your code in any text editor, and then run it through a special program called a compiler that creates the output files to run on your particular device. Since C is so popular, there are usually compiler options for most devices.
C code can also be moved between devices relatively easily. This is called porting. You may have to change processors in your products at one time or another. Maybe a model you use becomes obsolete, or you need something more powerful to add some more features. Assembly code is specific to the device, and would have to be rewritten. C is not device specific, and often the same code can be recompiled and run on different devices with minimal changes.
Many digital effects have sophisticated programmable features such as upgradeable firmware that require the use of an editor. These apps run on another device such as a PC, Mac or smartphone. If you need to provide an app with your digital effect, you can also use C to write that. There are several object-oriented variants of C such as C++ and C#. These are C like in nature, but are optimized for reusable objects. Objects are pieces of code that can easily be moved around and reused. This is helpful when writing applications where things are often repeated such as drawing windows, creating menus etc. Object Oriented languages can be more complicated to learn, but a good investment if you need to write editor-like programs for your products.
A great way to get started programming is with Arduino. You can buy a small Arduino board for just a few dollars, and connect it to a Mac or PC via USB. Arduino provides a software development environment called an IDE that you can download for free. This includes all the parts you need to get started right away:
Editor: The window for reading and writing your source code. You can use any text editor to write code, but a code specific editor provides useful features such as color coding, and quick links to example code and help pages.
Compiler: Compiles your code into object files that run on the processor. The IDE compiler options are pre-configured for the AVR processors used on the Arduino boards, so that you can compile your code for the Arduino without any additional setup.
Programmer: Uploads the compiled object files to the Arduino board so you can run it.
The IDE puts some wrappers around C to make some of the common Arduino functions a little easier, but it’s still basically C code. It’s a great environment for learning to program in C. Once you have learned some of the basics, Google ‘Arduino effects pedal’ for some project ideas.