Important: Inside Macintosh: Sound is deprecated as of Mac OS X v10.5. For new audio development in Mac OS X, use Core Audio. See the Audio page in the ADC Reference Library.
Finding and Changing Component Capabilities
All sound components take a stream of input data and produce a (usually different) stream of output data. The Sound Manager needs to know what operations your component can perform, so that it knows what other sound components might need to be linked together to play a particular sound on the available sound output device. It calls your component'sSoundComponentGetInfo
andSoundComponentSetInfo
functions to get and set information about the capabilities and current settings of your sound component.To specify the kind of information it wants to get or set, the Sound Manager passes your component a sound component information selector. If your component does not support a particular selector, if should pass the selector to the specified sound source. If your component does support the selector, it should either return the desired information directly or alter its settings as requested.
The sound component information selectors can specify any of a large number of audio capabilities or component settings. For example, the selector
siRateMultiplier
is passed to get or set the current output sample rate multiplier value.
Your component's
- Note
- The Sound Manager uses many of the sound input device information selectors defined by the Sound Input Manager for communicating with sound input devices. See "Sound Input Manager" in this book for a description of the sound input device information selectors. A complete list of all sound component information selectors is provided in "Sound Component Information Selectors" beginning on page 5-22.
SoundComponentGetInfo
function has the following declaration:
pascal ComponentResult SoundComponentGetInfo (ComponentInstance ti, SoundSource sourceID, OSType selector, void *infoPtr);The sound component information selector is passed in theselector
parameter. The sound source is identified by the source ID passed in thesourceID
parameter. TheinfoPtr
parameter specifies the location in memory of the information returned bySoundComponentGetInfo
. If the information to be returned occupies four bytes or fewer, you can simply return the information in the location pointed to by that parameter. Otherwise, you should pass back in theinfoPtr
parameter a pointer to a record of typeSoundInfoList
, which contains an integer and a handle to an array of data items. In the second case, you'll need to allocate memory to hold the information you need to pass back. Listing 5-5 defines a component'sSoundComponentGetInfo
routine. It returns information to the Sound Manager about its capabilities and current settings.Listing 5-5 Getting sound component information
static pascal ComponentResult MySoundComponentGetInfo (SoundComponentGlobalsPtr globals, SoundSource sourceID, OSType selector, void *infoPtr) { HandleListPtr listPtr; short *sp, i; UnsignedFixed *lp; Handle h; HardwareGlobalsPtr hwGlobals = globals->hwGlobals; ComponentResult result = noErr; /*Make sure we got our global variables.*/ if (hwGlobals == nil) return (notEnoughHardwareErr); switch (selector) { case siSampleSize: /*return current sample size*/ *((short *) infoPtr) = hwGlobals->sampleSize; break; case siSampleSizeAvailable: /*return sample sizes available*/ h = NewHandle(sizeof(short) * kSampleSizesCount); if (h == nil) return (MemError()); listPtr = (HandleListPtr) infoPtr; listPtr->count = 0; /*num. sample sizes in handle*/ listPtr->handle = h; /*handle to be returned*/ sp = (short *) *h; /*store sample sizes in handle*/ for (i = 0; i < kSampleSizesCount; ++i) if (hwGlobals->sampleSizesActive[i]) { listPtr->count++; *sp++ = hwGlobals->sampleSizes[i]; } break; case siSampleRate: /*return current sample rate*/ *((Fixed *) infoPtr) = hwGlobals->sampleRate; break; case siSampleRateAvailable: /*return sample rates available*/ h = NewHandle(sizeof(UnsignedFixed) * kSampleRatesCount); if (h == nil) return (MemError()); listPtr = (HandleListPtr) infoPtr; listPtr->count = 0; /*num. sample rates in handle*/ listPtr->handle = h; /*handle to be returned*/ lp = (UnsignedFixed *) *h; /*If the hardware can support a range of sample rate values, the list count should be set to 0 and the minimum and maximum sample rate values should be stored in the handle.*/ if (hwGlobals->supportsRateRange) { *lp++ = hwGlobals->sampleRateMin; *lp++ = hwGlobals->sampleRateMax; } /*If the hardware supports a limited set of sample rates, the list count should be set to the number of sample rates and this list of rates should be stored in the handle.*/ else { for (i = 0; i < kSampleRatesCount; ++i) if (hwGlobals->sampleRatesActive[i]) { listPtr->count++; *lp++ = hwGlobals->sampleRates[i]; } } break; case siNumberChannels: /*return current num. channels*/ *((short *) infoPtr) = hwGlobals->numChannels; break; case siChannelAvailable: /*return channels available*/ h = NewHandle(sizeof(short) * kChannelsCount); if (h == nil) return (MemError()); listPtr = (HandleListPtr) infoPtr; listPtr->count = 0; /*num. channels in handle*/ listPtr->handle = h; /*handle to be returned*/ sp = (short *) *h; /*store channels in handle*/ for (i = 0; i < kChannelsCount; ++i) if (hwGlobals->channelsActive[i]) { listPtr->count++; *sp++ = hwGlobals->channels[i]; } break; case siHardwareVolume: *((long *)infoPtr) = hwGlobals->volume; break; /*If you do not handle a selector, delegate it up the chain.*/ default: result = SoundComponentGetInfo(globals->sourceComponent, sourceID, selector, infoPtr); break; } return (result); }You can define yourMySoundComponentSetInfo
routine in an exactly similar fashion.