# How to gradually increase or decrease an FMSound frequency over time?

8 messages
Open this post in threaded view
|

## How to gradually increase or decrease an FMSound frequency over time?

 Maybe someone can point me in the right direction...I am trying to figure out how to gradually change the frequency of an FMSound over time, for example a gradual slide from, say, 99.12Hz to 109.56Hz over a given amount of time (sort of like a very slow Doppler shift in a way, I guess).  The actual function governing the frequency change could in theory be just about anything, but for now I am probably just looking at linear slides, and the length of time the slide could take could be seconds to minutes. I still consider myself a Smalltalk beginner, and my first instinct is always to "do it myself" because I have a hard time reading the existing code to figure out what has already been done.  Thus, my first idea was to try to output small segments (say 1 sec each) of a fixed frequency into a SequentialSound, and increase the frequency [of each segment] over time.   This  "works," but with the fractional cycles inherent in non-integral frequencies and/or times it results in a sharp transient at the junction of each new frequency segment--resulting in unwanted audible clicks. Is there a way to "manually" adjust the phase of each subsequent SequentialSound so I can "line them up," or will the PitchEnvelope class completely take care of this for me and I just can't figure it out?! Overall, though, I have to say I am impressed with the depth of the classes in the Sound-Synthesis category, I just don't know how to use them!  However, I am guessing  that Squeak knows how to do exactly what I want to do! Thanks in advance for any help;  I still have a hard time knowing if I am even looking in the right direction.  I hope I explained the problem well enough--a picture would have been easier in this case!Thanks again, Rob RothwellP.S.  If the answer is at all related to how I would fade the volume of a sound in or out over 15 to 30 seconds, could you let me know?
Open this post in threaded view
|

## Re: How to gradually increase or decrease an FMSound frequency over time?

 Just send >>pitch: to the FMSound at the appropriate times, sweeping between your two values? -C -- Craig Latta improvisational musical informaticist www.netjam.org Smalltalkers do: [:it | All with: Class, (And love: it)]
Open this post in threaded view
|

## Re: How to gradually increase or decrease an FMSound frequency over time?

 In reply to this post by Rob Rothwell Craig,Thanks for your reply:>       Just send >>pitch: to the FMSound at the appropriate times, sweeping>between your two values? I had thought of doing that, but I was hoping that I could end up at a specific frequency at a specific time.  However, for my purposes, the frequencies are more important to me than the times, so that may be what I end up doing. Basically, I am trying to use Squeak to generate Binaural Beat Sequences for brainwave entrainment.  A Binaural Beat basically consists of a beat@carrier frequency pair, so I want to be able to write something like:      sequence := BinauralSequence new.     sequence to: [hidden email] for: 2.75 minutes.     sequence to: [hidden email] over: 15 seconds for: 2.75 minutes.     etc...     ...and have it produce the desired effect, which in this case would be produce a beat frequency of 10.00Hz around a center carrier frequency of 109.65Hz (104.65 Left pan and 114.65 Right pan) for 2.75 minutes, then slide the beat and carrier frequency to [hidden email] over 15 seconds, hold for another 2.75 minutes, etc...The BinauralSequence would just be a part of a BinauralProgram, which would basically create a MixedSound with background sounds (rain, babbling brook, etc...) mixed in as desired, fade in and out as necessary, etc... While there are available tools to do this, it is either difficult or time consuming to tell the tool what you want it to do, and the natural message format of Smalltalk would just be perfect for this!However, for the time being, maybe I'll have the times in the above example be more of a request than a command, and fudge the time to keep the frequencies in phase and avoid any clicks or pops... I still think it would be fun to know how to phase shift a wave form in Squeak, though, and I still have to figure out how to fade in and out, but other than that, it's really pretty straightforward in Squeak once you start getting used to the classes! Thanks again,Rob
Open this post in threaded view
|

## Re: How to gradually increase or decrease an FMSound frequency over time?

 Rob Rothwell wrote: > Craig, > > Thanks for your reply: > > >       Just send >>pitch: to the FMSound at the appropriate times, > sweeping > >between your two values? > >  I had thought of doing that, but I was hoping that I could end up at > a specific frequency at a specific time.  However, for my purposes, > the frequencies are more important to me than the times, so that may > be what I end up doing. > > Basically, I am trying to use Squeak to generate Binaural Beat > Sequences for brainwave entrainment.  A Binaural Beat basically > consists of a beat@carrier frequency pair, so I want to be able to > write something like: Have you looked at the PitchEnvelope class? It allows you to sweep a sound between frequencies. You would need to take into account that it's working on a logarithmic scale, so it does not interpolate frequencies linearly, but musical notes. In many cases this would be the desired behaviour, I don't know enough about your application to say whether it is acceptable here as well. Cheers, Hans-Martin
Open this post in threaded view
|

## Re: How to gradually increase or decrease an FMSound frequency over time?

 Here is essentially what I want to do, which gives a "smooth" (stepped) progression from f1 to f2.  stepsPerSecond sort of controls the "smoothness" of the progression.    f1 := 330.50.    f2 := 440.90.    f := f1.    t := 0.    sec := 15.    stepsPerSecond := 10.0.         df := (f2-f1) / (sec*stepsPerSecond).    ss := SequentialSound new.    f := f-df."   Sweep smoothly from f1 to just shy of f2 over the specified time, re-calculating the amount of time for each step     based on the integral number of frequencies that can be completed within the estimated step size.    We should end up just shy of the target frequency, at the end of a complete cycle..."    1 to: (sec*stepsPerSecond) do: [         :i |        dt := (((i asFloat)/stepsPerSecond)-(t asFloat)).        f := (f + df).        cycles := (f*dt) roundTo: 1.0.         dt := cycles / f.        Transcript show: f; tab; show: dt; cr.         ss add: (FMSound new setPitch: f dur: dt loudness: 0.5).        t := t + dt.    ].        "   Add the the final frequency and play it briefly..."    Transcript show: f2; cr.     ss add: (FMSound new setPitch: f2 dur: 1.0 loudness: 0.5).    ss storeWAVOnFileNamed: 'test.wav'.        ss play.I would do something similar with the times if I wanted to "step" sharply from one frequency to another without the slide, but without introducing an audible "click."  Basically I just need to make sure that the transition from one frequency to another happens on an integral number of wave cycles. However, this seems somewhat inelegant given the apparent richness of the sound classes.  It *feels* like I am doing something "by hand" that is probably already built into the system.  It seems like the PitchEnvelope class *should* work, if I understood it better!  Furthermore, without understanding the VolumeEnvelope class, I would do something like the above to fade-in and fade-out, changing volume levels instead of frequencies. Thanks,RobOn 4/20/06, Hans-Martin Mosner <[hidden email]> wrote:>Have you looked at the PitchEnvelope class? It allows you to sweep a >sound between frequencies.>You would need to take into account that it's working on a logarithmic>scale, so it does not interpolate frequencies linearly, but musical>notes. In many cases this would be the desired behaviour, I don't know >enough about your application to say whether it is acceptable here as well.>>Cheers,>Hans-Martin
Open this post in threaded view
|

## Re: How to gradually increase or decrease an FMSound frequency over time?

 Rob Rothwell wrote: > Here is essentially what I want to do, which gives a "smooth" > (stepped) progression from f1 to f2.  stepsPerSecond sort of controls > the "smoothness" of the progression. > >     f1 := 330.50. >     f2 := 440.90. >     f := f1. >     t := 0. >     sec := 15. ... Here's a version with PitchEnvelope, which is really smooth and much less complicated:     f1 := 330.50.     f2 := 440.90.     sec := 15.     envelope := (PitchEnvelope             points: (Array                 with: 0 @ 1                 with: sec*1000 @ ((f2*2 / f1) log / 2 log))             loopStart: 2 loopEnd: 2)             centerPitch: f1.     (FMSound new setPitch: f1 dur: sec loudness: 0.5)         addEnvelope: envelope;         play Note that due to the logarithmic pitch slope, the frequency at t=7.5 is 381.73 and not 385.70. You should really experiment with PitchEnvelope a little more (and VolumeEnvelope for fade-in/fade-out). I'm certain that you can achieve your goals with it. When adding more slope points to the envelope, always remember to set loopStart and loopEnd to the size of the points array, as you don't want to have a looping part. Cheers, Hans-Martin