Sie sind auf Seite 1von 3

Title

3D Spectrum Analyser 
By Dooie Friend on Wednesday 18 March 2015 23:09 ­ Comments (8)
Category: ­, Views: 7551

More than a year ago, a friend of mine asked me to write the software for his 3D Spectrum Analyser (3DSA): a device That takes as input an audio
signal, and outputs its visualization on a 3D matrix of LEDs. If the above description does not quite ring a bell, simply watch the end result in
action:

For the hardware fans amongst you, my friend meticulously documented the construction process:

It's definitely worth watching, eg the guy literally built his own fracking PCB from scratch! I, However, am more a software kinda guy In this log,
I'll describe the basic building blocks we needed to get a sound spectrum analyzing algorithm going.

Intro

First things first though, the microprocessor to be programmed was an Olimex 80MHz PIC32, soldered to the PIC32­PINGUINO OTG
development board. (For Those Who ever tinkered with Arduino boards: it's the same, only with a faster chip and Fewer builtin  libraries) The
Algorithm had to sample the input signal at regular time intervals, convert this signal to the frequency domain, and visualize the detected
frequencies on a 16x16x5 LED matrix.
Mathematics

Of course, before writing any code, we had to figure out how to convert input samples to a frequency distribution. This thing is done all the time in
signal processing by applying the Discrete Fourier Transform (DFT) to the input signal. Given a signal sampled at a constant frequency, a DFT
outputs a set of amplitude or frequency bands residing in the signal. For example, When Your signal Mainly Consists of the middle C (or Do) tone,
a DFT will assign a relatively high amplitude to the frequency band encompassing the correspondance thing 262 Hz frequency. However, the
human ear Perceives sound logarithmically, meaning That a doubling or the frequency of a sound signal is perceived only as a linearly higher tone.
In order to Compensate for this, we used the Constant Q transform (CQT) Instead of the DFT. In short, where a DFT returns amplitudes for
frequency bands f­2f­3f­4f­etc., A CQT works with frequency bands f­2f­4f 8f­etc. So from a theoretical perspective, the algorithm needed for the
3DSA was quite simple: sample the input signal at regular time intervals, apply a CQT calculating amplitudes for 16 frequency bands, and make
each of the 16 LED columns blink Appropriately. Given That the Pinguino development board supported C, we Assumed Implementing this
algorithm would not Be That Hard. However, some challenges always pop up

Interrupts: a poor man's multithreading

First obstacle: how do you sample a signal at regular time intervals if you only have one thread? A simple solution would be to take a sample,
calculate the CQT and visualization, and let the thread sleep until a time period certainement HAS passed before starting a new sample calculte­
visualize cycle. However, we wanted our sampling rate to be 14 kHz­which on an 80 MHz microprocessor left les than 6k clock cycles between
samples to calculate the CQT. This Proved Insufficient ­ in the end we used ~ 1M clock cycles for each calculate­visualize cycle, so we had to
figure out how to take new samples while doing the CQT calculation and LED visualization for old samples. After perusing many a Pinguino
forum , the solution arrived in the form of interrupts: a piece of code That Has A higher priority than other code to run, and is executed by the
processor at designated time intervals. Since the Pinguino devs dont providence a C library for interrupts on the PIC32, we had to manually
implement this by setting some bit processor to the right value. Having grown up a Java programmer, I could almost feel the silicone under our
code

Floating points are slow (without hardware support)

The other large obstacle turned out to be the non­existing floating point capabilities of the PIC32 chip. Doing any floating point arithmetic in the
inner loop of our CQT implementation slowed down the code by an order of magnitude, turning the LED visualization in a slideshow (now I know
how an old GPU must  feel). In order to remedy this, we resorted to an improvised fixed­point number format, using 10 fractional bits. It
complicated multiplication a bit, but got the job done. On a related note, at the heart of a CQT lie a sine and cosine calculation, for­which the
builtin functions ook were way too slow. The fix was to implement our own third­order approximation, Taylor expansion for the sine function,
based on an excellent blog or Jasper Vijn. Coincidentally, he alsoused fixed­point arithmetic, So THAT was a natural fit. Seeing our hand­written
bit optimizations speed up our algorithm by a factor of 10 was ofcourse quite satisfying

Conclusion

In the end, our code could sample the input signal at 14 kHz, calculate frequency amplitudes in the range of 20­7000 Hz, and get a refresh rate of
80 FPS on the PIC32 chip, meaning each CQT­visualization walk firing only about 12 ms. It definitely was an instructive hobby project would
program again Thanks for reading! Link to source code  

Comments
Original text

In  the  end,  our  code  could  sample  the  input  signal  at  14  kHz,
By reminding Lowik, Wednesday 18 March 2015 23:35 calculate frequency amplitudes in the range of 20 ­ 7000 Hz, and get
a  refresh  rate  of  80  FPS  on  the  PIC32  chip,  meaning  each  CQT­
Volgensmij there is a mistake in your conclusion: 80 fps / Hz means that you only have 12 ms and 120 ms not. So is it 8 FPS with 120ms
visualization loop took only about 12 ms.
calculation time or 80 FPS with 12 ms calculation time? 
Contribute a better translation
Furthermore fun project

[Comment edited on Wednesday 18 March 2015 23:36]

By Dooie Friend, Thursday 19 March 2015 00:11

brake Lowik wrote on Wednesday 18 March 2015 @ 23:35:
volgensmij there is a mistake in your conclusion: 80 fps / Hz means that you only have 12 ms and 120 ms not. So is it 8 FPS with
120ms calculation time or 80 FPS with 12 ms calculation time? 
Furthermore fun project

80 FPS, so 12ms. Well spotted!

By masauri, Thursday 19 March 2015 10:20

This is really nice, the math is not for me, but to see it so be built, etc. A really nice project!

By GP500, Thursday 19 March 2015 16:52

Very nice, I would say start a business.

By sebastius, Thursday 19 March 2015 19:10

The making­of video is very impressive. I know all the techniques, but he explains it really neat, calm and organized out. Super!

By weekend warrior, Friday 20 March 2015 00:05

Very nice project 

By Sissors, Friday 20 March 2015 10:23

That's the fun of MCUs, you're much more directly on the hardware. But at the same time should also, you do not have the processing power and
memory to run inefficient code, you should do it  right. Is of course the requirements of your program and where you do it, but that seems to me
if you C ++ for the PC writes often a good idea to replace arrays vectors, many MCUs will not have even enough memory to include in your
vector.h.

By Mart Indo, Tuesday 24 March 2015 21:16

The concept of a three­dimensional matrix of LEDs is a fairly well­known project, but this application is very cool! For the rest, good
documentation for the mathematics behind it.

Das könnte Ihnen auch gefallen