Archive for the ‘Light Technical’ Category

Hurdles

Sunday, July 29th, 2012

The 2nd version Atari synth prototypes came back from assembly early this week, but something has them bricked.
The worst case is that there might be hardware damage (soldering too hot, static zap during handling, moisture problems), since that leaves little I can prove in a post-mortem. At $500 a run, prototypes are not cheap.

<geek notes>
The power supplies measure fine, and JTAG diagnostic tests on the FPGA pass with flying colors. The configuration pins all check out, too. Yet somehow the FPGA will not run. It is not simply a code issue, because the part won’t even run factory code from the manufacturer.
The 2.5V I/O banks appear to be driving out 0.45V intermittently, which can’t be a good sign of anything.
</geek notes>

So that is unfortunate.

To get back to something that *is* working, the 2A03 synth is coming along. It currently has voltage control of:
Pulse wave 1 pitch
Pulse wave 1 volume
Pulse wave 2 pitch
Pulse wave 2 volume
Triangle wave pitch
Noise wave volume

…and knob controls for:
Pulse wave 1 pitch
Pulse wave 1 volume
Pulse wave 1 duty cycle
Pulse wave 2 pitch
Pulse wave 2 volume
Pulse wave 2 duty cycle
Triangle wave pitch
Noise wave pitch
Noise wave volume

Click here for audio of one pulse wave modulated by a couple envelope generators

One of the downsides to using the actual NES CPU is that it has unobvious quirks. It would be far easier to make an FPGA clone of the 2A03 audio engine and just fix the quirks, but what’s the challenge in that?

The pulse wave pitch control registers are a good example. They are 11 bits wide, which isn’t anything special. On the other hand, any write command to the greatest 3 bits will cause a phase reset in the output waveform. In a videogame soundtrack where each note starts with a volume of 0, it might never be a problem. In a synthesizer where oscillators are “on” constantly, it leads to clicking as pitch changes.

I am experimenting with workarounds. One trick is to use the pitch sweep hardware built into the part to trigger an increase or decrease in the upper 3 bits without issuing a write command. That has two downsides:
1) Worst case, it takes almost 20 times longer than just letting the click happen
2) It is more difficult to keep stable

It takes so much longer because it involves writing several non-pitch registers multiple times. That ends up lowering the sample rate on pitch control voltage. The stability issue is just that I see the pulse wave pitch occasionally lock up and refuse to change for several seconds. It is probably due to some corner case I have not found yet, but it never happens in the clicky version.

I cannot take credit for the clever idea to use the sweep unit, by the way. That came from the nesdev.parodius.com forum.

I made a demo to show the difference. The following audio file alternates clicky/smooth/clicky/smooth through some pitch modulation.

Click here for audio

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?

Blasphemy

Blasphemy

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 http://www.dspdimension.com/

Pokey Oscillator Aliasing

Thursday, April 22nd, 2010

While waiting to hear back from Xilinx on some FPGA questions, I started a legitimate FPGA emulation of a Pokey chip. The sound generation hardware is, from what I can tell, completely digital up to the D/A converters. The outputs from different channels on a real chip modulate each other in the analog world, but it should be possible to get most of the way there in an FPGA.

My favorite “problem” with the Pokey is that the same frequency settings at two different times can create different sounds or even go from sound to silence. This happens because the noise generators run at very high speeds, but they are “sampled” by lower speed clocks to generate the output. The net result is 1-bit aliasing that creates predictably unpredictable results.

Obviously any true hardware emulation should have the same problems, so I put together some Verilog based on my current understanding of how the Pokey internals work. If my understanding is correct, I should be able to create patterns from one frequency value that give different timbres or even silence.

For the sake of brevity: it worked! I simulated the engine running with different frequency values until I found frequency values where a low speed clock synchronized with a pattern in the higher speed noise generators. By then jumping to a different frequency and back, the phase of this synchronization shifts and the output pattern changes timbre.

First is an extremely wide output shot from a logic simulation. “N” is the frequency register setting (AUDF in the Pokey datasheet). Several output configurations are shown as the bottom three lines. Notice that N is 3 most of the time, but the shape of T_4_OUT changes each time N jumps to 100 and back.

Sync In, Sync Out

Sync In, Sync Out

Click the image for a full-scale version.

Next is the money shot. There had to be a case where an output could “disappear” by grabbing a pattern of all zeros or all ones.

Everything and the Kitchen

Everything and the Kitchen

I’m not vouching that my Verilog code is 100% correct, especially given that it’s based on my understanding of some conflicting/incomplete data. It’s just nice to know that it has the right problems. It’s the good kind of bad, the Powerglove kind of bad.

As a side note, the Pokey datasheet and the De Re Atari chapter (7) on the Pokey contradict each other. De Re shows every distortion setting going through a divide-by-2, while the Pokey datasheet shows that some configurations, in fact, do not divide by 2. I believe the datasheet is correct in this case, though the block diagram in De Re Atari is useful for getting a general idea of the structure. The divide-by-2 settings just seem to mean “run through a T flip-flop.”

SID Oscillator Verilog Fun

Monday, April 12th, 2010

The past few days I’ve been waiting for Pokey synth front panel circuit boards to come in, so I thought I’d play around with some “soundchip” Verilog. Kevtris has already done a SID emulation in an FPGA (and understands the internals of the SID far better than I do), but I haven’t seen any code posted. I saw this blog post and eventually ended up at this interview I bookmarked a year or so ago.

I wrote some Verilog strictly according to the interview, specifically making an oscillator with triangle, saw, pulse, and noise outputs. I added in the logic “AND” of the triangle and saw waves as an additional waveform, according to Bob Yannes’ comments about multiple waveforms being selected at once. Here’s what the digital outputs looks like:

Only the Waviest

Only the Waviest

My source code is available here. I included excerpts from the interview as comments because it just felt so right. Open it with Notepad++ for best results (if you want all the formatting to line up properly).

What I still need to figure out:

The interview mentions that the LFSR for noise generation is clocked by one of the accumulator bits. Which bit is it?

Another excerpt from the interview that I’m partially unclear about: “The combination was actually a logical ANDing of the bits of each waveform, which produced unpredictable results, so I didn’t encourage this, especially since it could lock up the pseudo-random sequence generator by filling it with zeroes.” A linear feedback shift register shouldn’t be able to get filled with all zeros on its own. This implies that the LFSR shift register does not take feedback taps from itself, but actually taps somewhere further down the line (after the logical AND). Is it actually feeding back from the Waveform D/A input bits? In that case, what happens to the LFSR while it isn’t selected as a waveform?

Are the inputs to the Waveform D/A registered synchronously to the master clock, or do glitches pop up from not having every bit change at exactly the same time?

At this point I really need to fire up an actual SID to start checking my assumptions, but I’m afraid that if I touch a SID now then I’ll end up too distracted when the Pokey synth prototype PCBs come in.

1-bit FPGA D/A Update

Monday, February 8th, 2010

Most of my hobby time lately has been spent sourcing parts and doing circuit layout for the Pokey module, but yesterday I spent a little more time with the 1-bit D/A I was working on. Spectral plots are in order!

Running the output of the FPGA directly into my soundcard with a couple wires, this is the output spectrum for a 1k sine wave:

Blue Picket Fences

Blue Picket Fences

Alright, so that looks pretty terrible. The sine wave data is 16-bit, so the noise floor should be around -96 dB (the bottom line of the graph), yet it’s in the -86 range. There’s also a lot of distortion: both even and odd harmonics.

One potential reason for these problems is that my soundcard probably does not like 25 MHz input frequencies. To help that a little bit, I added an RC filter between the FPGA and soundcard. Using 16 kHz as a cutoff, the new result looks like this:

Noise Censorship

Noise Censorship

That’s much better. True CD quality would just have one spike at 1000 (for 1 kHz), as 2k, 3k, 4k… are distortions. The worst case offender is just under -40dB, giving this converter noise performance greater than 16-bit, but distortion performance that’s around 7-bit. I do not have an obvious solution for the distortion problem, nor can I prove with my current setup that it *isn’t* just a result of my soundcard not being able to handle the high frequency energy. If anyone has any insights, please add a comment or two.

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.

Pokey Control: Better, Faster, Stronger

Saturday, December 5th, 2009

The Pokey.synth module uses a microprocessor to control the Pokey. It works well, but it is a little slow. In this case, slow means that register writes happen around 100,000 times per second. That means all the sample rates preceding it can’t total more than 100 kHz. Since there are two channels of pitch control, two channels of volume control, and one bit crusher, each ends up with a pretty low sample rate.

The two limiting factors are the speed of the microprocessor and the interface between the micro and Pokey. The Pokey clocks address and data bits on specific edges of its clock, so writes have to either be done slowly or carefully. The instructions in a PIC run at 1/4th the chip’s clock speed, so even a 60 MHz clock can only toggle pins at a rate of 15 MHz. Factoring in everything else the processor needs to do, there isn’t a whole lot left for careful data transfers. The process becomes throwing data onto a bus in the cheapest way that sticks.

Clocking a Pokey at  its standard 1.79 MHz theoretically means it can handle 1,790,000 register writes per second. I had never heard of anyone actually testing that, so I made a project of it in hopes of getting much better FM control. Instead of controlling a Pokey from a microprocessor, I’m now using an FPGA. The nice thing about FPGAs is that they are essentially customizable hardware. I wrote an interface for the Pokey that can transfer data on literally every clock cycle… 1.79 Megabytes of data per second.

The test sequence is a pulse wave pattern done using a single channel’s D/A directly. It writes alternating values of 0 and 15 to the channel. The resulting wave looks like this:

Peaks and Valleys

Shark Conga Line

That wave is switching at a full 1.79 MHz. The data is actually switching so fast that the hardware cannot track it well. At audio frequencies the pulse wave looks perfect, but up here parasitic effects slew the square edges into exponential curves. The extra long pulse at the end is because the pattern isn’t exactly 10101010101010… it was simpler to double a data value every few cycles.

I would post an audio clip, but not even your pet bat would be able to hear it.

*poke*

Tuesday, October 6th, 2009

Tonight I solved a hardware problem with the Pokey module that had been a mystery for quite some time. In celebration, it only makes sense to post about an unrelated change from last weekend.

When the Pokey adjusts pitch on a noise waveform, it can often change timbre completely or even go silent. With analog tuning control, an incoming voltage can end up teetering on the brink of stability between two different sounds. For very slow pitch changes, it can end up sounding like a bad connection.

Click here to hear some “before” pitch changes

A common solution would be to add hysteresis. That is, keep a record of *how* the signal is changing. If it has been increasing and keeps increasing, let it pass as-is. If it has been increasing and tries to decrease, ignore the change unless it is more than some set amount.

That sure is a lot of logic to add, though. It requires looking at the last direction moved, the current direction, and how far it is trying to move. Instead, I went with a simpler approach. I’ll spare the math, but the resulting process looks like the following graph. Red is the noisy input signal and blue is the smoothed output.

The red represents the eternal struggle between order and chaos... or something

Red represents the eternal struggle between order and chaos... or something

It looks just like it’s been low pass filtered, but the overall frequency response has actually changed very little.

Click here for some “after” pitch changes

Listen to how sudden the transitions are now. There is no more loitering between timbres.

I’m currently doing an updated circuit board layout with all the minor changes I made to the prototype. Hopefully in a matter of weeks I will have the first few completed modules to use for demos and beta testing.

2A03 Horizons

Thursday, August 27th, 2009

I made an Octave script to simulate and graph all the 2A03 sweep unit settings as they change pitch over time. It is based entirely on my understanding of some documentation I found online… no measurements have actually been done. Each staircase represents one iterated combination of bit shifting and clock dividing. Something about the various quantizations weaving in and out of each other is strangely hypnotic.

Sweeeeeeeep

Sweeeeeeeep

Droppin Logs

Droppin' Logs

Open them in a new window for the full glory.

2A03 Triangle Wave Volume

Sunday, July 26th, 2009

As many developers have found, the 2A03 triangle wave registers are missing a relatively important feature: volume control. The noise channel gets 16 steps, the square channels get 16 steps, and the PCM channel gets 128 or so.  As for the triangle channel, it’s either “on” or “off.”

Limitations lead to creativity. The triangle, noise, and PCM channels all share the same output pin on the 2A03. The actual NES audio output design leads to some messy non-linearity. The result is a triangle wave that can be modulated by the PCM channel. I cannot name any games that use this effect, but it is relatively well-known.

So what does it mean?

As the signal on the PCM channel increases, the triangle wave gets quieter. If the PCM channel isn’t being used, it can provide crude volume control.

Under Control

Under Control

That picture shows the result of a test program that I made. It is a looped series of 128 triangle wave bursts. With each burst, the value on the PCM channel is increased by one. Over 128 bursts the volume drop is noticeable. It can be seen and heard.

Click here to hear the whole thing*

The two large pops (and all the small spikes in the picture) are related to DC offset issues. That is a story for another day.

*+1000 bonus points if you pictured the title screen to Uninvited after the first 2 seconds of this