chiark / gitweb /
typo fix
[disorder] / lib / coreaudio.c
... / ...
CommitLineData
1/*
2 * This file is part of DisOrder
3 * Copyright (C) 2009 Richard Kettlewell
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18/** @file lib/coreaudio.c
19 * @brief Support for @ref BACKEND_COREAUDIO
20 */
21
22#include "common.h"
23
24#if HAVE_COREAUDIO_AUDIOHARDWARE_H
25
26#include "coreaudio.h"
27#include "log.h"
28#include <CoreFoundation/CFString.h>
29
30/** @brief Return the default device ID */
31static AudioDeviceID coreaudio_use_default(void) {
32 OSStatus status;
33 UInt32 propertySize;
34 AudioDeviceID adid;
35
36 /* TODO should we use kAudioHardwarePropertyDefaultSystemOutputDevice
37 * instead? It is listed in the enumeration but is not documented, so we
38 * leave it alone until better information is available. */
39 propertySize = sizeof adid;
40 status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
41 &propertySize, &adid);
42 if(status)
43 fatal(0, "AudioHardwareGetProperty kAudioHardwarePropertyDefaultOutputDevice: %d", (int)status);
44 if(adid == kAudioDeviceUnknown)
45 fatal(0, "no output device");
46 return adid;
47}
48
49/** @brief Find a device by some string
50 * @param selector Selector for property to look for
51 * @param description Property description
52 * @param devs List of device IDs
53 * @param ndevs Number of device IDs in @p devs
54 * @param resultp Where to put device ID
55 * @return 1 if found, 0 if not found
56 */
57static int coreaudio_find_device(AudioObjectPropertySelector selector,
58 //const char *description,
59 const AudioDeviceID *devs,
60 unsigned ndevs,
61 CFStringRef dev,
62 AudioDeviceID *resultp) {
63 OSStatus status;
64 UInt32 propertySize;
65
66 for(unsigned n = 0; n < ndevs; ++n) {
67 CFStringRef name;
68 propertySize = sizeof name;
69 status = AudioDeviceGetProperty(devs[n], 0, FALSE,
70 selector,
71 &propertySize, &name);
72 if(status)
73 fatal(0, "AudioDeviceGetProperty: %d", (int)status);
74#if 0
75 UInt8 output[1024];
76 CFIndex used;
77 CFRange r = { 0, CFStringGetLength(name) };
78 CFStringGetBytes(name, r, kCFStringEncodingUTF8,
79 '?', FALSE, output, sizeof output,
80 &used);
81 output[used] = 0;
82 info("device %u %s: %s", n, description, (char *)output);
83#endif
84 if(CFStringCompare(dev, name,
85 kCFCompareCaseInsensitive|kCFCompareNonliteral)
86 == kCFCompareEqualTo) {
87 *resultp = devs[n];
88 CFRelease(name);
89 return 1;
90 }
91 CFRelease(name);
92 }
93 return 0; /* didn't find it */
94}
95
96/** @brief Identify audio device
97 * @param name Device name
98 * @return Device ID
99 */
100AudioDeviceID coreaudio_getdevice(const char *name) {
101 OSStatus status;
102 UInt32 propertySize;
103 int found;
104 AudioDeviceID adid;
105
106 if(!name
107 || !*name
108 || !strcmp(name, "default"))
109 return coreaudio_use_default();
110 /* Convert the configured device name to a CFString */
111 CFStringRef dev;
112 dev = CFStringCreateWithCString(NULL/*default allocator*/,
113 name,
114 kCFStringEncodingUTF8);
115 if(!dev)
116 fatal(0, "CFStringCreateWithBytes failed");
117 /* Get a list of available devices */
118 AudioDeviceID devs[1024];
119 unsigned ndevs;
120
121 propertySize = sizeof devs;
122 status = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
123 &propertySize, devs);
124 if(status)
125 fatal(0, "AudioHardwareGetProperty kAudioHardwarePropertyDevices: %d",
126 (int)status);
127 ndevs = propertySize / sizeof *devs;
128 if(!ndevs)
129 fatal(0, "no sound devices found");
130 /* Try looking up by UID first */
131 found = coreaudio_find_device(kAudioDevicePropertyDeviceUID, //"UID",
132 devs, ndevs, dev, &adid);
133 /* Failing that try looking up by name */
134 if(!found)
135 found = coreaudio_find_device(kAudioObjectPropertyName, //"name",
136 devs, ndevs, dev, &adid);
137 CFRelease(dev);
138 if(!found)
139 fatal(0, "cannot find device '%s'", name);
140 return adid;
141}
142
143#endif
144
145/*
146Local Variables:
147c-basic-offset:2
148comment-column:40
149fill-column:79
150indent-tabs-mode:nil
151End:
152*/