I have a little problem and could use some FFT-type analysis software.
We want to digitally generate programmable-bandwidth, lowpass/bandlimited Gaussian noise, at constant amplitude. What we have is a 4096-point, 16-bit wide RAM feeding a DAC, clocked by a DDS based address generator (phase accumulator) running at 128 MHz.
What I'd like to do is load the ram with a snippet of a bandlimited gaussian noise pattern corresponding to, say, 1 volt RMS at the dac output. I can generate the 4096 data points on a PC, and copy the data into my embedded assembly language program, which can in turn load the noise pattern into the ram when my user decides he wants noise on one channel (it will also do standard waveforms and arb.) The DDS phase accumulate value "plays" the waveform at a variable rate, setting the noise bandwidth.
Since the waveform will be played continuously, I don't want a "seam" at the transition from ram address 4095 to 0. It's sort of like a
360-degree panoramic photograph with no seam anywhere.My thinking is this:
Using some software tool, PowerBasic or one of the math things, define an array of 4096 floats. Load the array with random numbers in the range -1 to +1.
Now make a pass through all entries, applying a weighting function such as to change the probability distribution from flat to nearly Gaussian, with some reasonable crest factor. (I'm not sure this step is necessary.)
The points now look like hell, as they have no adjacent-point correlation; they need to be lowpass filtered.
Filter the points as follows: look at the data as an input array arranged as a ring instead of a linear vector. Create an null output array. Now we want to lowpass filter the input ring array into the output array seamlessly. Two ideas:
- Define a lowpass response as a FIR filter, determine its coefficients, and walk that filter (envision it as a arc-section of a circle) around the input ring, one step at a time. At each step, do the multiply-accumulate (convolution) thing and poke the resulting value into the output array.
- Simulate a single-pole lowpass filter as out = out + (in-out)/K. "Connect" it to the input data ring, walk it around one loop to "charge it up", then walk around another loop, with the "out" value now loading the output loop.
Lastly, I can normalise the output array to 1 volt RMS, remove any residual DC component, and quantize to 16 bits.
So I can code this without much trouble, and come up with some candidate algorithms and coefficients. I can export the data as a csv or whatever. What I need is a nice, easy-to-drive frequency analysis program, a fun Windows FFT utility. Any suggestions?
I'm thinking also that my "noise" spectrum will be a bunch of lines, not continuous, because my waveform is actually periodic. So we might somewhat randomize the DDS input frequency value to smear the lines in the frequency domain, jittering the waveform in the time domain. The effects of this needs to be analyzed, too, so the datasets may get large. Worst case, we could do the experiment all in hardware and use a real (classic, sweeping) spectrum analyzer.
Or maybe we need another algorithm for digitally generating bandlimited Gaussian noise. This one does fit our existing ARB architecture with minimal damage... we have a pipelined ARB architecture that we'd rather not trash much.
Ideas?
John