Forums

Audio synthesis problem

Started by Brent January 4, 2007
Hi,

I would like to generate an audio clip with a varying
frequency. A few attempts using either matlab/octave or
Python code have made "interesting" sounds but not what
I'm looking for yet.

The sound I want will have an initial frequency F0 which
will shift (interpolate) to a frequency F1 midway through
the clip, and remain at F1 until the end.
For example, in a two-second clip the frequency starts
at 110Hz and smoothly increases to 220Hz at the 1-second
point. 220Hz is maintained to the clip end at 2 seconds.

I've tried just changing the frequency in  sin(2*pi*F*t)
w.r.t. the time parameter t, but the resulting wave
is discontinuous, buzzy, etc.

I've also tried using FM sythesis but I don't understand
enough about how the I and Fm terms behave with the phase
shifting (as in  sin(2*pi*Fc*t + I*sin(2*pi*Fm*t))).

What am I doing wrong, or what techniques would make this
easier?
If FM sythesis can be used, what values for Fc,I,Fm are
suggested for the clip described above?
If you have sample code that shows how to do this, I
would appreciate seeing it (c,c++,python,matlab, etc).

thanks,
Brent

p.s. Sample Python code:
#
import sys, math, wave, array

def sourceFM(Fc, t, I, Fm):
     return math.sin(twopi * Fc * t  +
                     I * math.sin(twopi * Fm * t))

twopi = 2.0 * math.pi
Fs = 44100
secs = 2.0
numsamples = int(Fs * secs)

samples = [0.0] * numsamples
Fc = 110
I = 110
Fm = 0.25
print "Generating...%d samples" % (numsamples)
for i in range(numsamples):
     samples[i] = sourceFM(Fc, float(i)/numsamples, I, Fm)

# ...rest of code normalized, converted to 16-bit ints,
# and wrote a .wav file.
# - EOF
Brent wrote:

> Hi, > > I would like to generate an audio clip with a varying > frequency. A few attempts using either matlab/octave or > Python code have made "interesting" sounds but not what > I'm looking for yet. > > The sound I want will have an initial frequency F0 which > will shift (interpolate) to a frequency F1 midway through > the clip, and remain at F1 until the end. > For example, in a two-second clip the frequency starts > at 110Hz and smoothly increases to 220Hz at the 1-second > point. 220Hz is maintained to the clip end at 2 seconds. > > I've tried just changing the frequency in sin(2*pi*F*t) > w.r.t. the time parameter t, but the resulting wave > is discontinuous, buzzy, etc. > > I've also tried using FM sythesis but I don't understand > enough about how the I and Fm terms behave with the phase > shifting (as in sin(2*pi*Fc*t + I*sin(2*pi*Fm*t))). > > What am I doing wrong, or what techniques would make this > easier? > If FM sythesis can be used, what values for Fc,I,Fm are > suggested for the clip described above? > If you have sample code that shows how to do this, I > would appreciate seeing it (c,c++,python,matlab, etc). > > thanks, > Brent > > p.s. Sample Python code: > # > import sys, math, wave, array > > def sourceFM(Fc, t, I, Fm): > return math.sin(twopi * Fc * t + > I * math.sin(twopi * Fm * t)) > > twopi = 2.0 * math.pi > Fs = 44100 > secs = 2.0 > numsamples = int(Fs * secs) > > samples = [0.0] * numsamples > Fc = 110 > I = 110 > Fm = 0.25 > print "Generating...%d samples" % (numsamples) > for i in range(numsamples): > samples[i] = sourceFM(Fc, float(i)/numsamples, I, Fm) > > # ...rest of code normalized, converted to 16-bit ints, > # and wrote a .wav file. > # - EOF
You need to integrate your phase step-by-step. I.e., for each sample: * figure out the frequency you want * set phase = phase + frequency * deltaT * calculate x = sin(phase) where phase is the integral of frequency, and deltaT is your sampling interval (i.e. 1/44000 if you're sampling at 44000Hz). -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Posting from Google? See http://cfaj.freeshell.org/google/ "Applied Control Theory for Embedded Systems" came out in April. See details at http://www.wescottdesign.com/actfes/actfes.html
Tim Wescott wrote:
> Brent wrote: > >> Hi, >> >> I would like to generate an audio clip ... >> ... > > You need to integrate your phase step-by-step. I.e., for each sample: > > * figure out the frequency you want > * set phase = phase + frequency * deltaT > * calculate x = sin(phase) > > where phase is the integral of frequency, and deltaT is your sampling > interval (i.e. 1/44000 if you're sampling at 44000Hz). >
Thank you. I tried to track phase in one of my earlier non-FM attempts and danced all around it, but had it wrong. -Brent