Archive for the ‘Experimental’ Category

Poppin’ Caps

Monday, February 24th, 2014

The FPGA graphics engine (started around the last blog post from 2012) now has screen capture support! Here are a couple action shots from recent synth work:

Poking Around

Anti-aliased scope plotting!



You may wonder why the color scheme is so hideously fantastic. That comes from the loving care that went into picking the perfect colors and definitely is not just because this is an early prototype where the color scheme has been ignored…

Cheap FPGA Graphics, First Attempt

Sunday, December 30th, 2012

I need to find a better way to record video. An iPhone camera doesn’t do justice to the 70 frames per second of the screen.

This was a weekend project proof-of-concept for a low budget FPGA GPU. To be fair, it took a couple nights beforehand to get the display configured to recognize an RGB interface. That configuration is handled by a PIC at the moment.

The FPGA design is made of several engines running in parallel:

1) Background grid generator

2) Audio data plotter (including a UART receiver for getting data from a computer)

3) Geometry engines (one per shape)

4) Parallel RGB interface (this drives the LCD)

To keep the memory requirements tiny, there is no frame buffering of any kind for the geometry engines. The RGB interface steps through each pixel on the screen and passes the current coordinate location data to the other engines. Each engine returns a 1 (pixel on) or 0 (pixel off). The last step is a mixing block that defines the color and depth for the output of each engine. For example, the lowest layer is the background grid. Next up is the circle, and so on up to the audio plot. Only the highest illuminated pixel is shown for each location on the screen.

The geometry engines store the size and locations of their shapes in registers, so the only memory usage comes from the audio data drawn on top of everything. Audio data is being generated by Max/MSP and sent over a USB > serial cable. The FPGA double buffers it so that there aren’t any glitches due to synchronization issues.

A major downside to this general approach is that the amount of logic scales proportionally to the number of objects on the screen. If there are going to be 5 circles on the screen, this design needs 5 circle generators. One way to improve that is to use a faster clock in geometry calculations. Then each engine could handle multiple shapes per pixel.

Long-term goals: thick lines, anti-aliasing, sprites, and text rendering.

Tech details

The display is 320 * 240 pixels running at 70 fps. The complete design as shown uses 415 logic elements, 8192 bits of memory, and three 9-bit multipliers (for circle calculations). For a reference, the smallest Altera Cyclone IV FPGA has 6272 logic elements, 270 kbit of memory, and thirty 9-bit multipliers.

Early Tests of Max/MSP Controlling 2A03 (NES CPU) Audio

Monday, December 12th, 2011

My last post mentioned that I had an interface working for controlling the 2A03 at a reasonably fast rate. Last week I wrote a serial data receiver (UART in this case) into the 2A03 control logic so I could send the 2A03 commands from Max/MSP. I technically could’ve used MIDI, but at 31,250 bps it is far too slow for all the data I want to send as quickly as I want to send it. I opted for 1,000,000 bps with the option to speed it up further later.

The chain looks like this:
Max/MSP -> FTDI USB-to-UART cable -> FPGA development board -> 2A03 adapter

It works just as well as I hoped. I basically have real-time control over all the NES audio registers from Max/MSP. Here’s a screenshot of the big ol’ mess in Max:

It serves as a quick idea prototyping/test platform for the NES synth module, so it changes too frequently to bother making it tidy.

This post is boring without audio, so how about a few test recordings? These are all straight from an NES CPU into the preamps on my sound card.

Click here for clip 1 – triangle wave FM

The pitch of the triangle wave is modulated by a sine wave in Max/MSP. There is a lot of jitter in the timing not only because of the serial transmission, but also because I have to convert the sine from an audio thread in Max to control data to use with the “serial” object. Control data timing is not designed for audio. It worked decently given the circumstances.

Click here for clip 2 – pulse wave delay

One of my favorite Nintendo sounds is two pulse waves configured as an echo effect. I am just playing with a few settings (delay time, second wave volume and duty cycle). The percussive nature of the voices comes from an envelope with an attack time of zero and a short decay to silence. The envelope and all other data is being completely handled by Max and dumped out over USB. The pops in the audio are from a known control issue. They will get better and go away as I tweak the control logic.

Click here for clip 3 – noise bursts

I couldn’t post audio tests without including the noise channel. This is a steady stream of short bursts (zero attack time and fast release time) with pitch and timbre being adjusted by hand then linked to the amplitude envelope in fun ways.

Processing.js Test 5

Saturday, October 8th, 2011

Each of the sliders below controls one component (red, green, or blue) of the fill color across all the sliders. Click and drag.

Each slider is an “object” in the code so that I can create the coordinates once and let each slider mostly manage itself after that. The draw() and mouse functions end up being very simple.

Processing.js Test 4

Saturday, October 8th, 2011

This is a quick and dirty attempt to show my interpretation of a sine wave moving through air. The dots represent air molecules as they migrate away from high pressure toward low pressure. None of the dots actually move across the screen, they merely rock back and forth.

Processing.js Test 3

Saturday, June 25th, 2011

Animated sine wave rotated in two dimensions using OpenGL.

Edit: Code works in sketchpad, but not in the blog. Frowny face.

Click here for a dedicated website version. Processing.js uses WebGL for 3D, which is not supported by Internet Explorer. Try Chrome.

Processing.js Test 2

Tuesday, June 21st, 2011

…just a few circles and sine waves.

Processing.js Test

Sunday, June 19th, 2011


A Magic Trick

Sunday, July 25th, 2010

This was news to me. It is well known that any periodic waveform can be represented by an infinite sum of harmonic sine waves. What about making a sine wave from an infinite sum of harmonic square waves?



Each step in the animation doubles the number of square wave “harmonics” included to approach a pure sine wave. Ignore the numbers in the lower left hand corner despite the attention this sentence draws to them.

I take no credit for the math. I just wrote a GNU octave script to generate the plots based on an equation from

One Bit Sine Wave

Saturday, December 12th, 2009
Like Kicking a Slinky

Like Kicking a Slinky

Several weeks ago, I ported a 2nd order delta sigma D/A converter block diagram from “Principles of Digital Audio” into some Verilog for an FPGA.

The output is a 1-bit logic signal that, when smoothed, matches the input. The human ear does this smoothing naturally, so that slinky-looking wave will actually sound just like a sine wave. Notice that the 1-bit output looks more like an actual sound wave in air: variations in pressure following amplitude.

Delta sigma generates a stream of pulses that have a density corresponding to input amplitude. There is a lot of noise in addition to the input signal, but as long as it’s supersonic it does not audibly matter. I did learn, however, that it can really screw with a microphone preamp. Saying “2nd order” refers to the feedback system the converter uses. Higher orders push more converter noise past the range of hearing.

I ran a digital sine wave generator into my D/A and tied the FPGA pins straight into my soundcard. It was a just a quick sanity check.

Click Here to listen , but be aware it’s just a 1k sine wave

The converter I built was for a 16-bit input, and that recording ended up with a noise floor on par with 14-bit performance. The distortion is pretty high, but that could be clock jitter, a lack of proper filtering, or even the sine wave generator itself. I was just happy that it was making intelligible sound in the very first test on actual hardware.