[comp.sys.mac.programmer] Sound Manager and rateCmd

hpoppe@bierstadt.ucar.edu (Herb Poppe) (01/03/90)

I have a(nother) Sound Manager problem (system 6.0.2, Mac Plus, LSP 2.01):

I am experimenting with pitch bending effects using the rateCmd. (I want
to simulate the Doppler shift a stationary observer experiences when
hearing a sound emitted from a moving platform).

Quoting from IM V p. 490:

  cmd = rateCmd    param1 = NIL   param2 = rate

  Sets the rate at which succeeding buffer commands will be played.
  RateCmd is similar to frequencyCmd except that it lets you specify the
  rate as a multiplier of the original sampling rate; in other words,
  a rate of 2 is an octave higher, 0.667 a fifth lower. The rate is
  specified as a fixed-point number (of type Fixed).

Note the phrase "original sampling rate". I'll come back to that later.

The description above seems to imply that the rateCmd can only be used
in conjunction with the buffer command; fortunately (for what I want
to do), this is not the case. Those of you who would like to use the
rateCmd in conjunction with the bufferCmd in the manner described are 
out of luck. According to "The Sound Manager" by Jim Reekes (October
2nd, 1988) p. 34 (under Sound Manager Bugs - bufferCmd):

  Sending a bufferCmd will reset the channel's amplitude and rate
  settings. Since the amplitude is already being ignored and the rate
  isn't typically used, this problem is not of much concern at this
  time.

But I digress... The rateCmd is described in the following way in
"The Sound Manager" by Jim Reekes (October 2nd, 1988) p. 27:

  cmd=rateCmd    param1=0    param2=rate

  This command is sent by applications to modify the pitch of the
  sampled sound currently playing. The current pitch is multiplied by
  the rate in param2. It is used for pitch bending effects. The default
  rate of a channel is 1.0. To cause a pitch to fall an octave (or
  half of its frequency), send the rateCmd with param2 equal to one
  half as shown below.

  myCmd.cmd := rateCmd;
  myCmd.param1 := 0;
  myCmd.param2 := FixedRatio(1, 2);
  myErr := SndDoImmediate(myChan, myCmd);

To get a sound "currently playing", I do the following:

  I read the 'snd ' resource into memory.
  I move the handle high and lock the handle.
  I obtain a pointer to the sound header.
  I open a sound channel, specifying the sampled synth.
  SndDoCommand is called with a soundCmd to install the appropriate
  sound as an instrument in the channel.
  SndDoCommand is called with a freqCmd to play the sound for an
  indefinite duration (the sound has loopback points set).

I followed this with the code segment shown above to change the pitch of
the sound.

The first problem I had is that there is no ToolBox routine called
"FixedRatio"; rather, it is called "FixRatio".

The second problem is that 
SndDoImmediate is not appropriate for my code: I'm guessing that the sound
had not yet starting playing when the synth got the immediate rateCmd.
In any case, I didn't get any pitch bending until I replaced
SndDoImmediate with SndDoCommand.

The third problem was that a rate of 1/2 on the first sound I tried
resulted in no change in pitch. A rate of 1/1 resulted in a pitch an
octave higher; 1/4 an octave lower. It occurred to me that this effect
might be related to the original sampling rate; which, for the first
sound I tried, was 11khz. I then tried a sound sampled at 22khz. For
this sound, a rate of 1/2 gave a pitch an octave lower; 1/1 gave no
change in pitch and 2/1 gave a pitch an octave higher.

The first Sound Manager documentation quote above says "lets you specify the
rate as a multiplier of the original sampling rate". Apparently this
should read: "lets you specify the rate as a multiplier of a 22khz sampling
rate". Actually, I think the documentation is right and that this is
a Sound Manager bug. THE RATE SPECIFIED IN THE RATECMD OUGHT TO BE
RELATIVE TO THE ORIGINAL SAMPLING RATE. That is, a rate of 1/2 ought to
give a pitch an octave lower regardless of the original sampling rate.

The fourth problem surfaced when I sent a second rate command with the
same rate as the first. I got no change in pitch. The second Sound Manager
documentation quote above says "The current pitch is multiplied by
the rate in param2". Since the current pitch at the time of the second
rate command is 1/2 the original pitch, then I would have expected the
pitch after the second rate command to be 1/4 the original pitch. The first
Sound Manager documentation quote above says "lets you specify the
rate as a multiplier of the original sampling rate". Apparently, the first
quote describes the way the software works (with the exception noted above);
the second quote is wrong.

Is my third problem a bug?

If so, can/will a fix be added to the next version of the Sound
Manager (the one to be released with System 7)?

Will the new Sound Manager be supported in new versions of System 6?
(Apple has said it will continue to support System 6 since it intends
to continue to sell one megabyte machines after System 7 is released).

The rest of my problems seem to be documentation related. Although Jim
Reekes' Sound Manager document purports to replace the Sound Manager
chapter in IM V it does not include all of the information from
IM V (for example, Jim doesn't, but IM V does discuss the result codes
that can occur when calling the various Sound Manager routines), still has
errors (fourth problem) and ambiguities (I have no idea what I should
expect to hear when pauseCmd "suspends processing"). I hope Apple will rework
this documentation yet again for System 7.

Herb Poppe      NCAR                         INTERNET: hpoppe@ncar.ucar.edu
(303) 497-1296  P.O. Box 3000                   CSNET: hpoppe@ncar.CSNET
		Boulder, CO  80307               UUCP: hpoppe@ncar.UUCP