Search This Blog

Wednesday, August 1, 2018

Audio sw - ADC processing (part deuce)

 Projects / Audio Switching  Original post date:07/05/2016

I have rewritten the signal processing routines. The old code sequentially takes a batch approach to collecting audio data and processing. The new routines now uses a circular buffer for a continuous conversion and processing. The DMA controller interrupts the CPU at 50% and 100% mark of the buffer and sets a flag for the processing code in the event loop in the main program.

To get an idea of the time that the CPU spent processing each block of data , I set a GPIO bit at the IRQ and clears it just before it finishes the processing.

Sampling rate: 20ksps and 128 samples per interrupt. 1/20000 s * 128 = 6.4ms

Processing:
Averaging (4 audio channels + 1 channel of button) for DC offset, Volume (4 audio channels), Average Volume, Peak Volume and threshold detection.

Processing time:
It uses 533us to process each block of data and 8.33% of the overall CPU cycles. The CPU can easily process the streaming data.

I notice that my previous code for handling the DC Offset is incorrect. I should have subtracted the DC offset before adding up the volume. I am using the average values for the 128 samples as DC offset and that seems to be good enough.

The new DC offset and volume code seem to be working. I can now set a reasonably low threshold level (~2mV) for detecting active audio input without false triggering. This is around 1 LSB on the ADC.

I have unrolled the inner loops in my processing code which saves ~36% clock cycles. I have also increased the sampling rate to 38.4ksps with only a modest increase in CPU cycles.


I picked 38.4ksps because it is divisible by 128. The 300Hz IRQ is also a nice number that can be divided down in software to trigger tasks and screen updates.

I am playing around with a 128-point Discrete Time Fourier Transform using the intfft code from Elm-chan's "AC Load Analyer". This is a good excuse to learn to make a spectrum plot. The following screenshots shows the execution time for the volume calculation and FFT. They use up about 1/3 of the free processor cycles before the next block of sample arrive. Even low end chips like this have a lot of oomph for DSP using integer math.


The code mixed the selected Left/Right channel and applied Hann Window, perform the FFT and compute the sum of squares of the real and imaginary part in 840us. I am leaving out the square root for the complex number magnitude calculation and log for dB scale and going to use a table look up for plotting the results.

Real Time Spectrum Plot

Original post date:07/11/2016

Here is what a spectrum plot looks like.

There are still some rough edges as this is the first working code. This is purely eye candy visualization for this project, but most of the signal processing code can be reused for something else.


This is a neat one. The old fashion phone ringing in "The Matrix" movie.


The X axis is linear from 300Hz to 12.6kHz with each colum correspond to a 300Hz "bin". 38.2ksps/(128/2) = 300Hz. The Y axis is log scale. I probably going to fool around with the scaling a bit.

To test the FFT, I am using Audacity to generate a "Chirp" - a linear frequency sweep between 20Hz to 12kHz. It seems to be working. There seems to be some bleeding through from DC to the first bin in the plot.


Aliasing starts at around 13kHz. The anti-alias filter -3dB point is around 14kHz, so the amplitude is a bit lower, but there is only so much a passive first order RC filter can do.

Aliasing shows up as a reflection in the low frequency
This shows the amount of processor cycles needed. The plotting has very little code and it is limited by the LCD SPI clock speed at 4MHz. The LCD data transfer is done by DMA. There is still 490us left before the next DMA ADC block arrives.


I overclock the LCD (from 3MHz) to 6MHz and it still takes quite a bit of time. There is now 1.285ms until the next block of data arrives.


The LCD frame rate can be driven as high as 300/sec to keep up with the data rate, but are limited to what the display can show clearly.

II have decided to add a minimalistic VU as well. The VU meter will be overwritten by the Spectrum plot when needed.

This has minimal impact on CPU usage.


The LCD plastic sheet finally fell off, so I glue on a piece of clear plastic from a dollar store picture frame with a strip of double sided tape.

I move the VU bargraph to the right hand side to make it more consistent. The spectrum plot is from 600Hz to 19.2kHz. There is a bit of leakage of the DC level into the 300Hz, so I have decided to not to plot that frequency bin..

For testing, I generated a linear frequency sweep using the "chirp" generator in Audacity.


 The anti-alias filter attenuation the peak as the frequency increases towards the right hand side. Looks like the aliasing issues I have seen earlier might have been an artefact of the firmware.


No comments:

Post a Comment

Note: Only a member of this blog may post a comment.