Using CoreAudio API's to replace existing QT and Sound Manager calls
Using CoreAudio API's to replace existing QT and Sound Manager calls
- Subject: Using CoreAudio API's to replace existing QT and Sound Manager calls
- From: Babak Shakib <email@hidden>
- Date: Tue, 19 Aug 2003 15:11:23 -0700
Hi All,
We have an app that currently uses a combination of the Sound Manager
and the QT API's to get the audio stuff working and on OS9 everything
runs great but after doing a carbon port on OSX it works very
inconsistantly. Like sometimes a weird Robotic voice when you capture
audio. On my G4 powerbook it is fixed if you bring up QT's audio dialog
and set speaker to on then off!!!!! On other systems it never works
right!
Anyways, I was thinking of replacing the sound stuff with the newer
coreAudio API's on the OSX side. I don't know much about the Core Audio
API to get something working quickly? Or is it very involved. It's not
very clear by reading the docs but I have looked at the "daisy" sample
code which seems to do a lot more than what we need. Also I could not
get the daisy app working with the telex usb headset I have! Which
worries me a bit since our code has to work with other input devices
than the internal mic and speakers.
Below is a snapshot of the QT and Sound Manager API's we are using.
Any pointers would be greatly appreciated.
thanks,
babak
We use the QT API to let the user choose and configure the capture
device,
as follows:
// create SG audio channel so we can use SGSettingsDialog to config
capture
gAU_Digitizer_SG = OpenDefaultComponent(seqGrabComponentType,0);
SGInitialize(gAU_Digitizer_SG);
SGNewChannel(gAU_Digitizer_SG,
SoundMediaType,&gAU_Digitizer_SGAudioChannel);
// get input driver for SoundManager API
SGGetSoundInputDriver(gAU_Digitizer_SGAudioChannel);
// Let SG know whenever we have reconfigured the device with
SoundManager
API
SGSoundInputDriverChanged(gAU_Digitizer_SGAudioChannel);
// Let user choose input device and set gain
SGSettingsDialog(gAU_Digitizer_SG, gAU_Digitizer_SGAudioChannel,
0,...);
// get the channel settings to save in Prefs and restore on next
launch
SGGetChannelSettings(gAU_Digitizer_SG, gAU_Digitizer_SGAudioChannel,
&ud,
0L);
// restore the user chosen channel settings at launch
SGSetChannelSettings(gAU_Digitizer_SG, gAU_Digitizer_SGAudioChannel,
ud,
0L);
Then we use the SoundManager to set capture format we desire (if
possible).
continuous= 1;
err= SPBSetDeviceInfo(gAU_Digitizer_DeviceRefNum, siContinuous, (Ptr)
&continuous);
numChannels= 1;
err= SPBSetDeviceInfo(gAU_Digitizer_DeviceRefNum, siNumberChannels,
(Ptr)&numChannels);
sampleSize = 16;
err= SPBSetDeviceInfo(gAU_Digitizer_DeviceRefNum, siSampleSize, (Ptr)
&sampleSize);
sampleRate= rate44khz;
err= SPBSetDeviceInfo(gAU_Digitizer_DeviceRefNum, siSampleRate, (Ptr)
&sampleRate);
//// Read back actual values
// Get Sample Rate
err= SPBGetDeviceInfo(gAU_Digitizer_DeviceRefNum, siSampleRate, (Ptr)
&gAU_Digitizer_DeviceSampleRate);
// Get Sample Size
err= SPBGetDeviceInfo(gAU_Digitizer_DeviceRefNum, siSampleSize, (Ptr)
&gAU_Digitizer_DeviceSampleSize);
// Get 2's complement
err= SPBGetDeviceInfo(gAU_Digitizer_DeviceRefNum,
siTwosComplementOnOff,
(Ptr) &twosComplement);
// Get Buffer Size
err= SPBGetDeviceInfo(gAU_Digitizer_DeviceRefNum, siDeviceBufferInfo,
(Ptr)
&gAU_Digitizer_DeviceBufferSize);
// Get num channels
err= SPBGetDeviceInfo(gAU_Digitizer_DeviceRefNum, siNumberChannels,
(Ptr)
&numChannels);
Then, we use continuous recording with interruptRoutine to be called
whenever SoundManager has filled it's internal buffers.
// Start Recording
gAU_Transmit_SPBParamBlock.inRefNum= gAU_Digitizer_DeviceRefNum;
gAU_Transmit_SPBParamBlock.count= 0;
gAU_Transmit_SPBParamBlock.milliseconds= 0;
gAU_Transmit_SPBParamBlock.bufferLength= 0;
gAU_Transmit_SPBParamBlock.bufferPtr= nil;
gAU_Transmit_SPBParamBlock.completionRoutine= nil;
gAU_Transmit_SPBParamBlock.interruptRoutine=
gAU_Transmit_InterruptUPP;
gAU_Transmit_SPBParamBlock.userLong= 0;
gAU_Transmit_SPBParamBlock.error= 0;
gAU_Transmit_SPBParamBlock.unused1= 0;
err= SPBRecord(&gAU_Transmit_SPBParamBlock, true);
The interruptRoutine is designed to take whatever the SoundManager
gives us
for SampleRate,SampleSize,BufferSize, and numChannels, and convert it
to
what we need: 50 msec segments, with 16 bit mono, sampled at 8Khz.
The
interruptRoutine installs a Deferred Task to convert the format,
compress
the data, and put it on the network.
// stop recording
err= SPBStopRecording(gAU_Digitizer_DeviceRefNum);
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.