Connect with us

method to generate arbirtrary shaped sound energy

Discussion in 'Electronic Design' started by [email protected], Apr 27, 2006.

Scroll to continue with content
  1. Guest

    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

    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

    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?
  2. Mac

    Mac Guest

    Nothing analog about it. It is a bunch of numbers generated by computer
    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.

  3. Mochuelo

    Mochuelo Guest

    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
    where "x" is your input vector with random values, and "y" your output
    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
    - 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.
    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.

  4. Guest

    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?


  5. Guest

    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.
  6. DaveC

    DaveC Guest

    Thus spake :
    What's the end purpose of your endeavour?
  7. Usse my magic sinewave techniques.

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

    Many thanks,

    Don Lancaster voice phone: (928)428-4073
    Synergetics 3860 West First Street Box 809 Thatcher, AZ 85552
    rss: email:

    Please visit my GURU's LAIR web site at
  8. Guest

    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?
  9. Mochuelo

    Mochuelo Guest

    I know that Scilab is somewhat similar to Matlab, but I have never
    used it.

    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.

  10. Guest

    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

    Here's some info:
  11. Mac

    Mac Guest

    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.
  12. Guest

    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?
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day