source: trunk/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

  • Property svn:eol-style set to native
File size: 11.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtMultimedia module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of other Qt classes. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51//
52
53#include <QtCore/qstringlist.h>
54#include <QtCore/qlist.h>
55#include <QtCore/qbytearray.h>
56#include <QtCore/qdatastream.h>
57#include <QtCore/qdebug.h>
58#include <private/qcore_mac_p.h>
59
60#include <QtMultimedia/qaudiodeviceinfo.h>
61#include "qaudio_mac_p.h"
62#include "qaudiodeviceinfo_mac_p.h"
63
64
65
66QT_BEGIN_NAMESPACE
67
68
69QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray const& handle, QAudio::Mode)
70{
71 QDataStream ds(handle);
72 quint32 did, tm;
73
74 ds >> did >> tm >> name;
75 deviceId = AudioDeviceID(did);
76 mode = QAudio::Mode(tm);
77}
78
79bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const
80{
81 return format.codec() == QString::fromLatin1("audio/pcm");
82}
83
84QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const
85{
86 QAudioFormat rc;
87
88 UInt32 propSize = 0;
89
90 if (AudioDeviceGetPropertyInfo(deviceId,
91 0,
92 mode == QAudio::AudioInput,
93 kAudioDevicePropertyStreams,
94 &propSize,
95 0) == noErr) {
96
97 const int sc = propSize / sizeof(AudioStreamID);
98
99 if (sc > 0) {
100 AudioStreamID* streams = new AudioStreamID[sc];
101
102 if (AudioDeviceGetProperty(deviceId,
103 0,
104 mode == QAudio::AudioInput,
105 kAudioDevicePropertyStreams,
106 &propSize,
107 streams) == noErr) {
108
109 for (int i = 0; i < sc; ++i) {
110 if (AudioStreamGetPropertyInfo(streams[i],
111 0,
112 kAudioStreamPropertyPhysicalFormat,
113 &propSize,
114 0) == noErr) {
115
116 AudioStreamBasicDescription sf;
117
118 if (AudioStreamGetProperty(streams[i],
119 0,
120 kAudioStreamPropertyPhysicalFormat,
121 &propSize,
122 &sf) == noErr) {
123 rc = toQAudioFormat(sf);
124 break;
125 }
126 }
127 }
128 }
129
130 delete streams;
131 }
132 }
133
134 return rc;
135}
136
137QAudioFormat QAudioDeviceInfoInternal::nearestFormat(const QAudioFormat& format) const
138{
139 QAudioFormat rc(format);
140 QAudioFormat target = preferredFormat();
141
142 if (!format.codec().isEmpty() && format.codec() != QString::fromLatin1("audio/pcm"))
143 return QAudioFormat();
144
145 rc.setCodec(QString::fromLatin1("audio/pcm"));
146
147 if (rc.frequency() != target.frequency())
148 rc.setFrequency(target.frequency());
149 if (rc.channels() != target.channels())
150 rc.setChannels(target.channels());
151 if (rc.sampleSize() != target.sampleSize())
152 rc.setSampleSize(target.sampleSize());
153 if (rc.byteOrder() != target.byteOrder())
154 rc.setByteOrder(target.byteOrder());
155 if (rc.sampleType() != target.sampleType())
156 rc.setSampleType(target.sampleType());
157
158 return rc;
159}
160
161QString QAudioDeviceInfoInternal::deviceName() const
162{
163 return name;
164}
165
166QStringList QAudioDeviceInfoInternal::codecList()
167{
168 return QStringList() << QString::fromLatin1("audio/pcm");
169}
170
171QList<int> QAudioDeviceInfoInternal::frequencyList()
172{
173 QSet<int> rc;
174
175 // Add some common frequencies
176 rc << 8000 << 11025 << 22050 << 44100;
177
178 //
179 UInt32 propSize = 0;
180
181 if (AudioDeviceGetPropertyInfo(deviceId,
182 0,
183 mode == QAudio::AudioInput,
184 kAudioDevicePropertyAvailableNominalSampleRates,
185 &propSize,
186 0) == noErr) {
187
188 const int pc = propSize / sizeof(AudioValueRange);
189
190 if (pc > 0) {
191 AudioValueRange* vr = new AudioValueRange[pc];
192
193 if (AudioDeviceGetProperty(deviceId,
194 0,
195 mode == QAudio::AudioInput,
196 kAudioDevicePropertyAvailableNominalSampleRates,
197 &propSize,
198 vr) == noErr) {
199
200 for (int i = 0; i < pc; ++i)
201 rc << vr[i].mMaximum;
202 }
203
204 delete vr;
205 }
206 }
207
208 return rc.toList();
209}
210
211QList<int> QAudioDeviceInfoInternal::channelsList()
212{
213 QList<int> rc;
214
215 // Can mix down to 1 channel
216 rc << 1;
217
218 UInt32 propSize = 0;
219 int channels = 0;
220
221 if (AudioDeviceGetPropertyInfo(deviceId,
222 0,
223 mode == QAudio::AudioInput,
224 kAudioDevicePropertyStreamConfiguration,
225 &propSize,
226 0) == noErr) {
227
228 AudioBufferList* audioBufferList = static_cast<AudioBufferList*>(qMalloc(propSize));
229
230 if (audioBufferList != 0) {
231 if (AudioDeviceGetProperty(deviceId,
232 0,
233 mode == QAudio::AudioInput,
234 kAudioDevicePropertyStreamConfiguration,
235 &propSize,
236 audioBufferList) == noErr) {
237
238 for (int i = 0; i < int(audioBufferList->mNumberBuffers); ++i) {
239 channels += audioBufferList->mBuffers[i].mNumberChannels;
240 rc << channels;
241 }
242 }
243
244 qFree(audioBufferList);
245 }
246 }
247
248 return rc;
249}
250
251QList<int> QAudioDeviceInfoInternal::sampleSizeList()
252{
253 return QList<int>() << 8 << 16 << 24 << 32 << 64;
254}
255
256QList<QAudioFormat::Endian> QAudioDeviceInfoInternal::byteOrderList()
257{
258 return QList<QAudioFormat::Endian>() << QAudioFormat::LittleEndian << QAudioFormat::BigEndian;
259}
260
261QList<QAudioFormat::SampleType> QAudioDeviceInfoInternal::sampleTypeList()
262{
263 return QList<QAudioFormat::SampleType>() << QAudioFormat::SignedInt << QAudioFormat::UnSignedInt << QAudioFormat::Float;
264}
265
266static QByteArray get_device_info(AudioDeviceID audioDevice, QAudio::Mode mode)
267{
268 UInt32 size;
269 QByteArray device;
270 QDataStream ds(&device, QIODevice::WriteOnly);
271 AudioStreamBasicDescription sf;
272 CFStringRef name;
273 Boolean isInput = mode == QAudio::AudioInput;
274
275 // Id
276 ds << quint32(audioDevice);
277
278 // Mode
279 size = sizeof(AudioStreamBasicDescription);
280 if (AudioDeviceGetProperty(audioDevice, 0, isInput, kAudioDevicePropertyStreamFormat,
281 &size, &sf) != noErr) {
282 return QByteArray();
283 }
284 ds << quint32(mode);
285
286 // Name
287 size = sizeof(CFStringRef);
288 if (AudioDeviceGetProperty(audioDevice, 0, isInput, kAudioObjectPropertyName,
289 &size, &name) != noErr) {
290 qWarning() << "QAudioDeviceInfo: Unable to find device name";
291 }
292 ds << QCFString::toQString(name);
293
294 CFRelease(name);
295
296 return device;
297}
298
299QByteArray QAudioDeviceInfoInternal::defaultInputDevice()
300{
301 AudioDeviceID audioDevice;
302 UInt32 size = sizeof(audioDevice);
303
304 if (AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &size,
305 &audioDevice) != noErr) {
306 qWarning() << "QAudioDeviceInfo: Unable to find default input device";
307 return QByteArray();
308 }
309
310 return get_device_info(audioDevice, QAudio::AudioInput);
311}
312
313QByteArray QAudioDeviceInfoInternal::defaultOutputDevice()
314{
315 AudioDeviceID audioDevice;
316 UInt32 size = sizeof(audioDevice);
317
318 if (AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size,
319 &audioDevice) != noErr) {
320 qWarning() << "QAudioDeviceInfo: Unable to find default output device";
321 return QByteArray();
322 }
323
324 return get_device_info(audioDevice, QAudio::AudioOutput);
325}
326
327QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode)
328{
329 QList<QByteArray> devices;
330
331 UInt32 propSize = 0;
332
333 if (AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propSize, 0) == noErr) {
334
335 const int dc = propSize / sizeof(AudioDeviceID);
336
337 if (dc > 0) {
338 AudioDeviceID* audioDevices = new AudioDeviceID[dc];
339
340 if (AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propSize, audioDevices) == noErr) {
341 for (int i = 0; i < dc; ++i) {
342 QByteArray info = get_device_info(audioDevices[i], mode);
343 if (!info.isNull())
344 devices << info;
345 }
346 }
347
348 delete audioDevices;
349 }
350 }
351
352 return devices;
353}
354
355
356QT_END_NAMESPACE
357
Note: See TracBrowser for help on using the repository browser.