Maker Pro
Maker Pro

method to generate arbirtrary shaped sound energy

I am trying to generate a special type of noise. Its not pink or white,
or another color, it has a specific "spectrum" so to speak. Its
basically filtered white noise, but I think it would be too difficult
to recreate reliably and cheaply with multiple analog filters. It looks
like pink noise from 20 hz to about 700 hz, then it has various peaks
and valleys. I would like to make a very inexpensive playback device
for this noise sound, based on clocking out a cheap flash memory into
an RC filter. The process would go like this:

1) mathematically generate the sound somehow in the analog domain (pure
math)

2) take the pure math sound, and generate an appropriate bit stream,
designed to recreate the analog sound by playing the bitstream into an
RC filter

so what we are doing here is taking an analog domain sound (the pure
math) and mathematically transforming it into a bitstream that when
played into a simple rc filter will recreate the original analog sound.
this is possible right?

I dont know how to do steps 1 or 2. I figure step 1 should be easy to
do in C. So since I want a 20khz upper frequency to be reproduced, each
second of sound will require 40000 samples, right? So if I want this
noise sound to loop every 5 seconds (to keep the size of the flash
memory down), I will need 40000 * 5 samples, which is 200,000 samples.
So in C, make a 200,000 byte array, and then starting at 20hz, create a
sine wave whose amplitude matches the energy of the spectrum of the
desired noise at 20 hz, and put it in the array. The move to 20hz +
..001hz, and do it again, but mix it with the existing sound in the
array, and continue this process until you get to 20,000hz. Then you
have a 5 second long array of an analog-domain sound which matches the
spectrum of the sound I want to recreate.

Now to play this array back using our flash memory/rc filter setup, we
have to take the array, and transform it into a bitstream which when
played back on the rc filter, will recreate the original sound (which
we are starting with). I suppose you could use some simple closed loop
method, http://www.romanblack.com/picsound.htm.

Does this make sense?

Could you recreate white noise using this method? And does it matter
what phase I start the sine wave at when creating the array?
 
M

Mac

I am trying to generate a special type of noise. Its not pink or white,
or another color, it has a specific "spectrum" so to speak. Its
basically filtered white noise, but I think it would be too difficult
to recreate reliably and cheaply with multiple analog filters. It looks
like pink noise from 20 hz to about 700 hz, then it has various peaks
and valleys. I would like to make a very inexpensive playback device
for this noise sound, based on clocking out a cheap flash memory into
an RC filter. The process would go like this:

1) mathematically generate the sound somehow in the analog domain (pure
math)

2) take the pure math sound, and generate an appropriate bit stream,
designed to recreate the analog sound by playing the bitstream into an
RC filter

so what we are doing here is taking an analog domain sound (the pure
math) and mathematically transforming it into a bitstream that when
played into a simple rc filter will recreate the original analog sound.
this is possible right?

Yes.

I dont know how to do steps 1 or 2. I figure step 1 should be easy to
do in C. So since I want a 20khz upper frequency to be reproduced, each
second of sound will require 40000 samples, right? So if I want this
noise sound to loop every 5 seconds (to keep the size of the flash
memory down), I will need 40000 * 5 samples, which is 200,000 samples.
So in C, make a 200,000 byte array, and then starting at 20hz, create a
sine wave whose amplitude matches the energy of the spectrum of the
desired noise at 20 hz, and put it in the array. The move to 20hz +
.001hz, and do it again, but mix it with the existing sound in the
array, and continue this process until you get to 20,000hz. Then you
have a 5 second long array of an analog-domain sound which matches the
spectrum of the sound I want to recreate.

Nothing analog about it. It is a bunch of numbers generated by computer
code.
Now to play this array back using our flash memory/rc filter setup, we
have to take the array, and transform it into a bitstream which when
played back on the rc filter, will recreate the original sound (which
we are starting with). I suppose you could use some simple closed loop
method, http://www.romanblack.com/picsound.htm.

Does this make sense?

I didn't follow the link. But what you are saying more or less makes sense.
Could you recreate white noise using this method? And does it matter
what phase I start the sine wave at when creating the array?

I don't think step 2 is necessary. Once you have the numbers representing
voltage, (or SPL, I guess) you have everything you need. These numbers
are, in essence, samples of the noise you want to make. Just like the
numbers in a .WAV file.

The idea you are talking about above is feeding a pulse-width modulated
(PWM) output into an RC filter as a way of converting from digital to
analog. Another way is to just send your generated samples to a DAC. This
might be easier, if not cheaper.

If you do want to do the PWM thing, the easiest way might be to have a
microcontroller with a PWM output read the samples directly from the ROM
(Flash or whatever) and load them into the PWM register. Then the PWM
output goes to the RC filter.

Making the bitstream into a PWM signal directly (this is your step 2,
above) seems like a waste of ROM to me, although it is possible, if you
have enough ROM space.

--Mac
 
M

Mochuelo

I am trying to generate a special type of noise. Its not pink or white,
or another color, it has a specific "spectrum" so to speak. Its
basically filtered white noise, but I think it would be too difficult
to recreate reliably and cheaply with multiple analog filters. It looks
like pink noise from 20 hz to about 700 hz, then it has various peaks
and valleys. I would like to make a very inexpensive playback device
for this noise sound, based on clocking out a cheap flash memory into
an RC filter. The process would go like this:

1) mathematically generate the sound somehow in the analog domain (pure
math)

2) take the pure math sound, and generate an appropriate bit stream,
designed to recreate the analog sound by playing the bitstream into an
RC filter

so what we are doing here is taking an analog domain sound (the pure
math) and mathematically transforming it into a bitstream that when
played into a simple rc filter will recreate the original analog sound.
this is possible right?
Yes.

I dont know how to do steps 1 or 2. I figure step 1 should be easy to
do in C. So since I want a 20khz upper frequency to be reproduced, each
second of sound will require 40000 samples, right? So if I want this
noise sound to loop every 5 seconds (to keep the size of the flash
memory down), I will need 40000 * 5 samples, which is 200,000 samples.
So in C, make a 200,000 byte array, and then starting at 20hz, create a
sine wave whose amplitude matches the energy of the spectrum of the
desired noise at 20 hz, and put it in the array. The move to 20hz +
.001hz, and do it again, but mix it with the existing sound in the
array, and continue this process until you get to 20,000hz. Then you
have a 5 second long array of an analog-domain sound which matches the
spectrum of the sound I want to recreate.

There is a better way to do that. Design/choose a digital filter (FIR
or IIR) whose frequency response matches the desired frequency shape
of your noise. Generate white noise (with rnd function) and feed it to
your digital filter. The output from the filter is noise with the
desired frequency shape.

In your case, since the desired freq shape is not simple, you may need
to play with some filter design tool, to manually create the shape you
need. Matlab can help you with that. For instance, the pole/zero
editor in the signal processing GUI tool (command "sptool") lets you
manually create almost any kind of filter. Once you have chosen your
filter (vectors "a" and "b." "b" is the numerator of your filter," and
"a" is the denominator. If FIR, "a"=1), filtering is as
straightforward as executing
y=filter(b,a,x);
where "x" is your input vector with random values, and "y" your output
vector.
Now to play this array back using our flash memory/rc filter setup, we
have to take the array, and transform it into a bitstream which when
played back on the rc filter, will recreate the original sound (which
we are starting with). I suppose you could use some simple closed loop
method, http://www.romanblack.com/picsound.htm.

Some options:
- The flash stores 8-bit samples, and you use a DAC to convert them
into 256-level pulses, which can be easily RC filtered.
- Since you won't find 1-bit wide flash chips, you can use a
parallel-to-serial converter to convert the 8-bit output from your
flash into a 1-bit stream that can be also RC filtered. You need more
math to do this, since you have to design/choose what kind of
bitstream you want to use. You don't need a DAC, but you need a
parallel-to-serial converter, and some extra glue logic to synchronize
them.
- An MCU extracts data from the flash, and generates a PWM (easy) or
any other kind of bitstream (can be more complex), that is finally RC
filtered. PWM adds distortion, but if you can live with it, it can be
a good alternative to the DAC.

If you need a very cheap solution, you can use option one without a
DAC. A few resistors and a logic inverter (say 4049UB) with negative
feedback can do D-to-A conversion with reasonable quality. I once gave
as a present a circuit like this to a friend, with my voice greeting
recorded on the (by then) EEPROM.
Does this make sense?

Could you recreate white noise using this method? And does it matter
what phase I start the sine wave at when creating the array?

If you want to generate the noise the way you explained, I believe you
would need to give each sine wave a random phase value, including the
first one.

Best,
 
Thanks for your response Mochuelo. I like your idea of using matlab to
generate the digital filter and then the actual shaped-spectrum noise
directly, so that all I have to do next is work on getting a DAC or
filtered PWM running. Might you know of a freeware alternative to
Matlab that would accomplish the same thing?

Thanks!

Asa
 
I am trying to generate a special type of noise. Its not pink or white,
or another color, it has a specific "spectrum" so to speak. Its
basically filtered white noise, but I think it would be too difficult
to recreate reliably and cheaply with multiple analog filters. It looks
like pink noise from 20 hz to about 700 hz, then it has various peaks
and valleys. I would like to make a very inexpensive playback device
for this noise sound, based on clocking out a cheap flash memory into
an RC filter. The process would go like this:

1) mathematically generate the sound somehow in the analog domain (pure
math)

2) take the pure math sound, and generate an appropriate bit stream,
designed to recreate the analog sound by playing the bitstream into an
RC filter

so what we are doing here is taking an analog domain sound (the pure
math) and mathematically transforming it into a bitstream that when
played into a simple rc filter will recreate the original analog sound.
this is possible right?

I dont know how to do steps 1 or 2. I figure step 1 should be easy to
do in C. So since I want a 20khz upper frequency to be reproduced, each
second of sound will require 40000 samples, right? So if I want this
noise sound to loop every 5 seconds (to keep the size of the flash
memory down), I will need 40000 * 5 samples, which is 200,000 samples.
So in C, make a 200,000 byte array, and then starting at 20hz, create a
sine wave whose amplitude matches the energy of the spectrum of the
desired noise at 20 hz, and put it in the array. The move to 20hz +
.001hz, and do it again, but mix it with the existing sound in the
array, and continue this process until you get to 20,000hz. Then you
have a 5 second long array of an analog-domain sound which matches the
spectrum of the sound I want to recreate.

Now to play this array back using our flash memory/rc filter setup, we
have to take the array, and transform it into a bitstream which when
played back on the rc filter, will recreate the original sound (which
we are starting with). I suppose you could use some simple closed loop
method, http://www.romanblack.com/picsound.htm.

Does this make sense?

Could you recreate white noise using this method? And does it matter
what phase I start the sine wave at when creating the array?

You can do this, but there are a few things you should consider:

1) You don't need to calculate so many frequencies. You want to cover
20Hz to 20kHz, so you only need multiples of 20 Hz, which is less than
1000 of them.

2) You should either increase your playback rate and the number of
samples, or reduce your upper frequency limit to maybe 15 kHz because
the 2F Nyquist criterion is only a minimum theoretical value for an
infinitely long sample.

3) You must randomize the starting phase of each sine wave or all
you'll get is a series of pulses at 20 Hz.

4) You can save a lot of memory if you record just 1 second of noise
and loop it. You'll get some pulsation at 1 Hz, but you may be able to
choose an optimal looping point that sounds best.
 
D

DaveC

Thus spake [email protected]:
I am trying to generate a special type of noise. Its not pink or white,
or another color, it has a specific "spectrum" so to speak. Its
basically filtered white noise, but I think it would be too difficult
to recreate reliably and cheaply with multiple analog filters. It looks
like pink noise from 20 hz to about 700 hz, then it has various peaks
and valleys. I would like to make a very inexpensive playback device
for this noise sound, based on clocking out a cheap flash memory into
an RC filter. The process would go like this:

What's the end purpose of your endeavour?
 
D

Don Lancaster

Mac said:
Nothing analog about it. It is a bunch of numbers generated by computer
code.




I didn't follow the link. But what you are saying more or less makes sense.




I don't think step 2 is necessary. Once you have the numbers representing
voltage, (or SPL, I guess) you have everything you need. These numbers
are, in essence, samples of the noise you want to make. Just like the
numbers in a .WAV file.

The idea you are talking about above is feeding a pulse-width modulated
(PWM) output into an RC filter as a way of converting from digital to
analog. Another way is to just send your generated samples to a DAC. This
might be easier, if not cheaper.

If you do want to do the PWM thing, the easiest way might be to have a
microcontroller with a PWM output read the samples directly from the ROM
(Flash or whatever) and load them into the PWM register. Then the PWM
output goes to the RC filter.

Making the bitstream into a PWM signal directly (this is your step 2,
above) seems like a waste of ROM to me, although it is possible, if you
have enough ROM space.

--Mac

Usse my magic sinewave techniques.

Which routinely use 44,000 bit words to create quite specific "sounds".

http://www.tinaja.com/magsn01.asp


--
Many thanks,

Don Lancaster voice phone: (928)428-4073
Synergetics 3860 West First Street Box 809 Thatcher, AZ 85552
rss: http://www.tinaja.com/whtnu.xml email: [email protected]

Please visit my GURU's LAIR web site at http://www.tinaja.com
 
Thanks for your interesting reply Joe! When I go to iteratively mix
each frequency, I add the existing value in the array to the current
value right? Not multiply? I.e. the first pass will yield a big array
with 20hz in it. The second pass, at 40 hz, should be added to the
array or mutplied by the values in the array?
 
M

Mochuelo

Thanks for your response Mochuelo. I like your idea of using matlab to
generate the digital filter and then the actual shaped-spectrum noise
directly, so that all I have to do next is work on getting a DAC or
filtered PWM running. Might you know of a freeware alternative to
Matlab that would accomplish the same thing?

I know that Scilab is somewhat similar to Matlab, but I have never
used it.
http://www.scilab.org/

On the other hand, computing the output from your filter is as simple
as solving for y(n) in

a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)
- a(2)*y(n-1) - ... - a(na+1)*y(n-na),

which is what Matlab does. You can easily do that with any programming
language. To design the filter, however, some high-level functions do
help. You need to find "b" (if FIR) or "a" and "b" (if IIR) such that
your response is as close as possible to the desired one.

Best,
 
Thanks for your interesting reply Joe! When I go to iteratively mix
each frequency, I add the existing value in the array to the current
value right? Not multiply? I.e. the first pass will yield a big array
with 20hz in it. The second pass, at 40 hz, should be added to the
array or mutplied by the values in the array?

Added, not multiplied.

Of course, each frequency component must first be scaled by the
corresponding amplitude of your frequency response function. You should
also consider gradually fading in the first decade of frequencies (from
20 Hz to 200 Hz), and fading out the last decade (from 2 kHz to 20 kHz)
by a nice smooth "windowing" function to avoid the effects of a sudden
change from zero to full power at the ends of your band of frequencies.

What you are actually doing is computing a discrete inverse Fourier
transform using phase shifted sine functions instead of the usual
complex exponential function. The main difference, as far as you are
concerned, is that the complex exponential form expresses the phase as
relative proportions of orthogon sine and cosine components. But your
system is easier to understand if you don't know complex function
theory.

Here's some info:

http://en.wikipedia.org/wiki/Fourier_transform#Discrete_Fourier_transform
 
M

Mac

[...]Might you know of a freeware alternative to Matlab that would
accomplish the same thing?

Octave is a free Matlab clone. Of course it is not as full featured as
Matlab, and I don't know if it runs on Windows.
Thanks!

Asa

--Mac
 
Hi Joe,

I tried the inverse discrete FFT method you described, and it worked!
Problem is I get wierd warbling at very low frequencies, it sounds like
a heartbeat. But I did a spectral analysis of the original and my
reproduction and the spectrums are identical, except mine is less
smooth especially below 100hz where there are very large peaks and
valleys. I though this might be becase I was using a 2.4hz "step" when
generating random-phase waveforms. I tried decreasing the step size to
0.1hz, by simply duplicating the amplitude of the previous 2.4hz step
until the next step in 0.1hz increments, but I got what appears to be
white noise, with a flat spectrum that seems to increase by about 3db
per octave and sounds white. I am not sure whats going on now. Perhaps
I am not using big enough numbers (I am using 4 byte floating point max
6 significant digits) and 0.1hz differences cant even be put into my
array and all the energy is lumping up somehow?

I figured I couldnt use 20hz steps like you suggested because I have a
gentle slope from 20hz to 500hz that I dont think could be recreated
with such a large step. Am I wrong? How would the energy at say 45hz be
recreated? Wouldnt there be big gaps in the spectrum?
 
Top