Rendering PCM with simulated phosphor persistence

When PCM waveforms and similar oscillograms are displayed on screen, computational speed is often preferred over beauty and information content. For example, Audacity only draws the local maximum envelope amplitude and (what appears to be) RMS power when zoomed out, and when zoomed in, displays a very straightforward linear interpolation between samples.

Here's the startup beep of my Kenwood TK-2302, rendered by Audacity:

[Image: Screenshot showing the oscillogram viewer of Audacity. 500 milliseconds of a signal is shown, beginning as a thin line that suddenly makes a positive rise, a slightly slower fall and then changes into a wide, solidly filled surface, with a lighter color in the middle.]

Analogue oscilloscopes, on the other hand, do things differently. An electron beam scans a phosphor screen at a constant X velocity, lighting a dot everywhere it hits. The dot brightness is proportional to the time the electron beam was directed at it. Because the X speed of the beam is constant and the Y position is modulated by the waveform, brightness gives information about the local derivative of the function.

Of course, PCM is all about "dots" as well, so we could possibly mimic this behavior digitally. I'm going to simulate an electron beam by first oversampling the above waveform by an insane amount – at 1 megahertz, that is. Lowpass filtering follows, with a cutoff frequency at the Nyquist frequency of the original PCM. Now, a program reads in the processed PCM and for each sample will make the corresponding dot on the XY plane a little brighter. (Actually each sample will affect 4 image pixels because of bilinear interpolation.) This method gives us a much more interesting rendering:

[Image: An oscillogram with the same features as in the above picture, but the solid surface appears transparent and there are variations to its brightness in both X and Y directions, revealing structures not present in the above image.

Now how cool is that? It looks like an X-ray of the signal. We can see right away that the beep is roughly a square wave, because there's light on top and bottom of the oscillation envelope but mostly darkness in between. Minute changes in the harmonic content are also visible as interesting banding and ribbons.

At very high zoom, Audacity doesn't even bother reconstructing the actual waveform but just thinks of it as a "connect the dots" puzzle. This is computationally feasible, of course. Oversampling at 3,000,017 Hz and downpass filtering at the original Nyquist frequency, on the other hand, results in an apparent reconstruction of the analogue wave:

[Image: An Audacity oscillogram zoomed in so much that only a few dozen samples span the picture. Samples are drawn as dots that are connected by straight lines. Below it, another oscillogram of the same waveform, with a smooth waveform passing through all the samples.]

Finally, the soprano section of the Finnish Radio Chamber Choir singing a D note in a piece by Einojuhani Rautavaara:

[Image: An oscillogram of a signal varying in both time and frequency, revealing inner structure as brightness variations.]

Relevant code for scientific interest in this Gist.


  1. That last one is pretty sweet!

  2. so nice! Sometimes I still pull out an old analog spectrum from the 70ties as it's the only thing at the lab that's fast enough to show the "ghosts" of parametric oscillations etc.

  3. This is visually just way to awesome !

    I read through your blog, and only now realized that the aweseome modem sound poster was done by you. I hope you know you made a lot of people very happy for half an hour.

  4. Since Audacity is Open Source, have you considered letting the developers know about these *AWESOME* ideas? Having been a Geek since I could walk, ;) I am VERY familiar with the unique and very revealing characteristics of oscilloscope displays. Having an OPTION to select such a display in Audacity would be totally awesome! I'd gladly sacrifice some computing speed to get O'Scope-like renderings like this! However, I don't use Audacity, I use Cool Edit 2000. (I paid for it, and by golly, I am going to use it until the bits wear out!) ;) If they added this feature to Audacity, I'd install it JUST FOR THAT! :)

  5. I've also looked into this a bit. I wrote a simple cairo-based program that can do sinc interpolation and phosphorus-like waveform rendering based on the (estimated) derivative of the signal. is my current result. It is missing gamma correction so it looks a bit poor at this moment.

    1. Adding to below: the test.png file has now been updated with gamma corrected rendering using 12 bits per pixel resolution.

  6. Beautiful! The people who make popular waveform editors should be encouraged to show the data this way, or at least include the option.

  7. How did you oversample the sound at 3MHz? I can't sample anything higher than the rates in the dropdown list, even if the rate is a multiple of 44.1k.

  8. This is gorgeous, thanks for the writeup. Also your other posts are consistently awesome as well, it's always nice to find blogs/sites like this with such high signal/noise ratio!

  9. Just a drive by comment. Saw a project on news.ycombinator and thought of your work from around this timeframe. May never be useful but comments are still free:


Please browse through the FAQ first, it might be that your question is already answered.

Spammers have even found comments sections, so this comments section is pre-moderated; it will take some time for the comment to show up.