EsounD: patch for Mac OS X coreaudio device selection
Ojas Parekh <[email protected]>
| Newsgroups | gmane.comp.gnome.multimedia |
|---|---|
| Message-ID | <[email protected]> |
I've included a patch to audio_coreaudio.c that allows coreaudio
device specification, e.g.:
[dbook: /tmp]$ esd -d "Built-in Input"
- using device Built-in Input
using device Soundflower (2ch) for output:
with sample rate 44100.000000, 2 channels and 32-bit sample
using device Built-in Input for input:
with sample rate 44100.000000, 2 channels and 32-bit sample
A complication is that a specified device may not have both input and
output capabilities, in which case the driver resorts to the default
input or output device. In the above example, "Built-in Input" does
not have any output channels, so the driver selected "Soundflower
(2ch)," which is the default output device on my system, for output.
-Ojas
_______________________________________________
gnome-multimedia mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gnome-multimedia
esound-audio_coreaudio.patch
(application/octet-stream, 7.6 KB)
diff -urN esound-0.2.36.orig/audio_coreaudio.c esound-0.2.36/audio_coreaudio.c
--- esound-0.2.36.orig/audio_coreaudio.c 2003-06-18 08:12:23.000000000 -0400
+++ esound-0.2.36/audio_coreaudio.c 2007-09-07 18:53:46.000000000 -0400
@@ -90,7 +90,7 @@
#define ARCH_esd_audio_devices
const char *esd_audio_devices()
{
- return "coreaudio API only";
+ return "Built-in Output, Built-in Input, etc.";
}
/*
@@ -116,18 +116,158 @@
return (0);
}
- /********************** playback section ***************************/
- /* get default output device */
- propertySize = sizeof(gOutputDeviceID);
- status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
- &propertySize,
- &gOutputDeviceID);
- if (status) {
- fprintf(stderr, "get default output device failed, status = %d\n",
- (int)status);
- return (-2);
+ if (esd_audio_device) {
+ /* search for DeviceID of specified device */
+ UInt32 outSize;
+ UInt32 devIndex, numDevs;
+ UInt32 buffIndex, numChannels;
+ AudioDeviceID dev, *devList = NULL;
+ AudioBufferList *buffList = NULL;
+
+ outSize = 0;
+ status = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
+ &outSize,
+ NULL);
+ if (status || outSize == 0) {
+ fprintf(stderr, "get device list info failed, status = %d\n",
+ (int)status);
+ return (-2);
+ }
+
+ numDevs = outSize/sizeof(AudioDeviceID);
+
+ /* allocate and get the device list */
+ devList = (AudioDeviceID*)malloc(outSize);
+ if (!devList) {
+ fprintf(stderr, "memory allocation failed\n");
+ return (-2);
+ }
+ status = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
+ &outSize,
+ devList);
+ if (status) {
+ fprintf(stderr, "get device list failed, status = %d\n",
+ (int)status);
+ if (devList) free(devList);
+ return (-2);
+ }
+
+ /* iterate through device list */
+ for (devIndex = 0; devIndex < numDevs; ++devIndex) {
+ outSize = LEN_DEVICE_NAME;
+ status = AudioDeviceGetProperty(devList[devIndex],
+ 0,
+ 0,
+ kAudioDevicePropertyDeviceName,
+ &outSize,
+ deviceName);
+ if (status) {
+ fprintf(stderr, "get device name failed, status = %d\n",
+ (int)status);
+ if (devList) free(devList);
+ return (-2);
+ }
+
+ /* is this the specified device? */
+ if (strncmp(deviceName, esd_audio_device, strlen(esd_audio_device)) == 0) {
+ /* device found, now probe for num inputs/outputs */
+ dev = devList[devIndex];
+
+ /* get number of input channels */
+ outSize = 0;
+ numChannels = 0;
+ status = AudioDeviceGetPropertyInfo(dev,
+ 0,
+ 1,
+ kAudioDevicePropertyStreamConfiguration,
+ &outSize,
+ NULL);
+ if(!status && (outSize != 0)) {
+ buffList = (AudioBufferList*)malloc(outSize);
+ if (!buffList) {
+ fprintf(stderr, "memory allocation failed\n");;
+ return (-2);
+ }
+ /* get the input stream configuration */
+ status = AudioDeviceGetProperty(dev,
+ 0,
+ 1,
+ kAudioDevicePropertyStreamConfiguration,
+ &outSize,
+ buffList);
+ if(!status) {
+ /* count the total number of input channels in the stream */
+ for(buffIndex = 0; buffIndex < buffList->mNumberBuffers; ++buffIndex)
+ numChannels += buffList->mBuffers[buffIndex].mNumberChannels;
+ }
+ }
+
+ /* set input device */
+ if (numChannels == 0)
+ gInputDeviceID = kAudioDeviceUnknown;
+ else
+ gInputDeviceID = dev;
+
+
+ /* get number of output channels */
+ outSize = 0;
+ numChannels = 0;
+ status = AudioDeviceGetPropertyInfo(dev,
+ 0,
+ 0,
+ kAudioDevicePropertyStreamConfiguration,
+ &outSize,
+ NULL);
+ if(!status && (outSize != 0)) {
+ buffList = (AudioBufferList*)malloc(outSize);
+ if (!buffList) {
+ fprintf(stderr, "memory allocation failed\n");
+ return (-2);
+ }
+ /* get the input stream configuration */
+ status = AudioDeviceGetProperty(dev,
+ 0,
+ 0,
+ kAudioDevicePropertyStreamConfiguration,
+ &outSize,
+ buffList);
+ if(!status) {
+ // count the total number of input channels in the stream
+ for(buffIndex = 0; buffIndex < buffList->mNumberBuffers; ++buffIndex)
+ numChannels += buffList->mBuffers[buffIndex].mNumberChannels;
+ }
+ }
+
+ if (numChannels == 0)
+ gOutputDeviceID = kAudioDeviceUnknown;
+ else
+ gOutputDeviceID = dev;
+
+ /* found specified device so break */
+ break;
+ }
+ }
+ if (devList) free(devList);
+ if (devIndex >= numDevs) {
+ fprintf(stderr, "device not found\n");
+ return (-2);
+ }
}
+ /********************** playback section ***************************/
+ if (gOutputDeviceID == kAudioDeviceUnknown) {
+ /* get default output device */
+ propertySize = sizeof(gOutputDeviceID);
+ status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+ &propertySize,
+ &gOutputDeviceID);
+ if (status) {
+ fprintf(stderr, "get default output device failed, status = %d\n",
+ (int)status);
+ return (-2);
+ }
+ }
+
if (gOutputDeviceID != kAudioDeviceUnknown) {
/* got default output device */
coreaudio_has_output_device = 1;
@@ -206,15 +346,17 @@
}
/********************** record section ***************************/
- /* get default input device */
- propertySize = sizeof(gInputDeviceID);
- status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
- &propertySize,
- &gInputDeviceID);
- if (status) {
- fprintf(stderr, "get default input device failed, status = %d\n",
- (int)status);
- return (-2);
+ if (gInputDeviceID == kAudioDeviceUnknown) {
+ /* get default input device */
+ propertySize = sizeof(gInputDeviceID);
+ status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
+ &propertySize,
+ &gInputDeviceID);
+ if (status) {
+ fprintf(stderr, "get default input device failed, status = %d\n",
+ (int)status);
+ return (-2);
+ }
}
if (gInputDeviceID != kAudioDeviceUnknown) {