|
38 | 38 | Spec format; |
39 | 39 | AudioQueueRef audioQueue; |
40 | 40 | Callback callback; |
41 | | - void* mUserData; |
42 | 41 | }; |
43 | 42 |
|
44 | 43 | OSXAudioDriver::OSXAudioDriver() |
|
49 | 48 |
|
50 | 49 | initDeviceMapListener(); |
51 | 50 | updateDeviceMap(); |
52 | | - |
53 | | - m_deviceId = DEFAULT_DEVICE_ID; |
54 | 51 | } |
55 | 52 |
|
56 | 53 | OSXAudioDriver::~OSXAudioDriver() |
|
64 | 61 |
|
65 | 62 | std::string OSXAudioDriver::name() const |
66 | 63 | { |
67 | | - return "MUAUDIO(OSX)"; |
| 64 | + return "OSX"; |
| 65 | +} |
| 66 | + |
| 67 | +muse::audio::AudioDeviceID OSXAudioDriver::defaultDevice() const |
| 68 | +{ |
| 69 | + return DEFAULT_DEVICE_ID; |
68 | 70 | } |
69 | 71 |
|
70 | 72 | bool OSXAudioDriver::open(const Spec& spec, Spec* activeSpec) |
|
77 | 79 | return 0; |
78 | 80 | } |
79 | 81 |
|
80 | | - *activeSpec = spec; |
81 | | - activeSpec->format = Format::AudioF32; |
82 | | - m_data->format = *activeSpec; |
| 82 | + if (activeSpec) { |
| 83 | + *activeSpec = spec; |
| 84 | + } |
| 85 | + |
| 86 | + m_data->format = spec; |
83 | 87 | m_activeSpecChanged.send(m_data->format); |
84 | 88 |
|
85 | 89 | AudioStreamBasicDescription audioFormat; |
|
88 | 92 | audioFormat.mFramesPerPacket = 1; |
89 | 93 | audioFormat.mChannelsPerFrame = spec.output.audioChannelCount; |
90 | 94 | audioFormat.mReserved = 0; |
91 | | - switch (activeSpec->format) { |
92 | | - case Format::AudioF32: |
93 | | - audioFormat.mBitsPerChannel = 32; |
94 | | - audioFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat; |
95 | | - break; |
96 | | - case Format::AudioS16: |
97 | | - audioFormat.mBitsPerChannel = 16; |
98 | | - audioFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; |
99 | | - break; |
100 | | - } |
| 95 | + audioFormat.mBitsPerChannel = 32; |
| 96 | + audioFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat; |
101 | 97 | audioFormat.mBytesPerPacket = audioFormat.mBitsPerChannel * spec.output.audioChannelCount / 8; |
102 | 98 | audioFormat.mBytesPerFrame = audioFormat.mBytesPerPacket * audioFormat.mFramesPerPacket; |
103 | 99 |
|
104 | 100 | m_data->callback = spec.callback; |
105 | | - m_data->mUserData = spec.userdata; |
106 | 101 |
|
107 | 102 | OSStatus result = AudioQueueNewOutput(&audioFormat, OnFillBuffer, m_data.get(), NULL, NULL, 0, &m_data->audioQueue); |
108 | 103 | if (result != noErr) { |
109 | 104 | logError("Failed to create Audio Queue Output, err: ", result); |
110 | 105 | return false; |
111 | 106 | } |
112 | 107 |
|
113 | | - audioQueueSetDeviceName(outputDevice()); |
| 108 | + audioQueueSetDeviceName(m_data->format.deviceId); |
114 | 109 |
|
115 | 110 | AudioValueRange bufferSizeRange = { 0, 0 }; |
116 | 111 | UInt32 bufferSizeRangeSize = sizeof(AudioValueRange); |
|
164 | 159 | return false; |
165 | 160 | } |
166 | 161 |
|
167 | | - LOGI() << "Connected to " << outputDevice() << " with bufferSize " << bufferSizeOut << ", sampleRate " << spec.output.sampleRate; |
| 162 | + LOGI() << "Connected to " << m_data->format.deviceId |
| 163 | + << " with bufferSize " << bufferSizeOut |
| 164 | + << ", sampleRate " << spec.output.sampleRate; |
168 | 165 |
|
169 | 166 | return true; |
170 | 167 | } |
|
216 | 213 | return m_availableOutputDevicesChanged; |
217 | 214 | } |
218 | 215 |
|
219 | | -muse::audio::AudioDeviceID OSXAudioDriver::outputDevice() const |
220 | | -{ |
221 | | - return m_deviceId; |
222 | | -} |
223 | | - |
224 | 216 | void OSXAudioDriver::updateDeviceMap() |
225 | 217 | { |
226 | 218 | std::lock_guard lock(m_devicesMutex); |
|
306 | 298 | m_availableOutputDevicesChanged.notify(); |
307 | 299 | } |
308 | 300 |
|
309 | | -bool OSXAudioDriver::setOutputDeviceBufferSize(unsigned int bufferSize) |
310 | | -{ |
311 | | - if (m_data->format.output.samplesPerChannel == bufferSize) { |
312 | | - return true; |
313 | | - } |
314 | | - |
315 | | - bool reopen = isOpened(); |
316 | | - close(); |
317 | | - m_data->format.output.samplesPerChannel = bufferSize; |
318 | | - |
319 | | - bool ok = true; |
320 | | - if (reopen) { |
321 | | - ok = open(m_data->format, &m_data->format); |
322 | | - } |
323 | | - |
324 | | - if (ok) { |
325 | | - m_bufferSizeChanged.notify(); |
326 | | - } |
327 | | - |
328 | | - return ok; |
329 | | -} |
330 | | - |
331 | | -async::Notification OSXAudioDriver::outputDeviceBufferSizeChanged() const |
332 | | -{ |
333 | | - return m_bufferSizeChanged; |
334 | | -} |
335 | | - |
336 | | -std::vector<unsigned int> OSXAudioDriver::availableOutputDeviceBufferSizes() const |
| 301 | +std::vector<samples_t> OSXAudioDriver::availableOutputDeviceBufferSizes() const |
337 | 302 | { |
338 | 303 | OSXAudioDeviceID osxDeviceId = this->osxDeviceId(); |
339 | 304 | AudioObjectPropertyAddress bufferFrameSizePropertyAddress = { |
|
346 | 311 | UInt32 dataSize = sizeof(AudioValueRange); |
347 | 312 | OSStatus rangeResult = AudioObjectGetPropertyData(osxDeviceId, &bufferFrameSizePropertyAddress, 0, NULL, &dataSize, &range); |
348 | 313 | if (rangeResult != noErr) { |
349 | | - logError("Failed to get device " + outputDevice() + " bufferFrameSize, err: ", rangeResult); |
| 314 | + logError("Failed to get device " + m_data->format.deviceId + " bufferFrameSize, err: ", rangeResult); |
350 | 315 | return {}; |
351 | 316 | } |
352 | 317 |
|
353 | | - unsigned int minimum = std::max(static_cast<samples_t>(range.mMinimum), MINIMUM_BUFFER_SIZE); |
354 | | - unsigned int maximum = std::min(static_cast<samples_t>(range.mMaximum), MAXIMUM_BUFFER_SIZE); |
| 318 | + samples_t minimum = std::max(static_cast<samples_t>(range.mMinimum), MINIMUM_BUFFER_SIZE); |
| 319 | + samples_t maximum = std::min(static_cast<samples_t>(range.mMaximum), MAXIMUM_BUFFER_SIZE); |
355 | 320 |
|
356 | | - std::vector<unsigned int> result; |
357 | | - for (unsigned int bufferSize = maximum; bufferSize >= minimum;) { |
| 321 | + std::vector<samples_t> result; |
| 322 | + for (samples_t bufferSize = maximum; bufferSize >= minimum;) { |
358 | 323 | result.push_back(bufferSize); |
359 | 324 | bufferSize /= 2; |
360 | 325 | } |
|
364 | 329 | return result; |
365 | 330 | } |
366 | 331 |
|
367 | | -bool OSXAudioDriver::setOutputDeviceSampleRate(unsigned int sampleRate) |
368 | | -{ |
369 | | - if (m_data->format.output.sampleRate == sampleRate) { |
370 | | - return true; |
371 | | - } |
372 | | - |
373 | | - bool reopen = isOpened(); |
374 | | - close(); |
375 | | - m_data->format.output.sampleRate = sampleRate; |
376 | | - |
377 | | - bool ok = true; |
378 | | - if (reopen) { |
379 | | - ok = open(m_data->format, &m_data->format); |
380 | | - } |
381 | | - |
382 | | - if (ok) { |
383 | | - m_sampleRateChanged.notify(); |
384 | | - } |
385 | | - |
386 | | - return ok; |
387 | | -} |
388 | | - |
389 | | -async::Notification OSXAudioDriver::outputDeviceSampleRateChanged() const |
390 | | -{ |
391 | | - return m_sampleRateChanged; |
392 | | -} |
393 | | - |
394 | | -std::vector<unsigned int> OSXAudioDriver::availableOutputDeviceSampleRates() const |
| 332 | +std::vector<sample_rate_t> OSXAudioDriver::availableOutputDeviceSampleRates() const |
395 | 333 | { |
396 | 334 | return { |
397 | 335 | 44100, |
|
463 | 401 |
|
464 | 402 | UInt32 OSXAudioDriver::osxDeviceId() const |
465 | 403 | { |
466 | | - AudioDeviceID deviceId = outputDevice(); |
| 404 | + AudioDeviceID deviceId = m_data->format.deviceId; |
467 | 405 | if (deviceId == DEFAULT_DEVICE_ID) { |
468 | 406 | deviceId = defaultDeviceId(); |
469 | 407 | } |
470 | 408 |
|
471 | 409 | return QString::fromStdString(deviceId).toInt(); |
472 | 410 | } |
473 | 411 |
|
474 | | -bool OSXAudioDriver::selectOutputDevice(const AudioDeviceID& deviceId /*, unsigned int bufferSize*/) |
475 | | -{ |
476 | | - if (m_deviceId == deviceId) { |
477 | | - return true; |
478 | | - } |
479 | | - |
480 | | - bool reopen = isOpened(); |
481 | | - close(); |
482 | | - m_deviceId = deviceId; |
483 | | - |
484 | | - bool ok = true; |
485 | | - if (reopen) { |
486 | | - ok = open(m_data->format, &m_data->format); |
487 | | - } |
488 | | - |
489 | | - if (ok) { |
490 | | - m_outputDeviceChanged.notify(); |
491 | | - } |
492 | | - |
493 | | - return ok; |
494 | | -} |
495 | | - |
496 | | -bool OSXAudioDriver::resetToDefaultOutputDevice() |
497 | | -{ |
498 | | - return selectOutputDevice(DEFAULT_DEVICE_ID); |
499 | | -} |
500 | | - |
501 | | -async::Notification OSXAudioDriver::outputDeviceChanged() const |
502 | | -{ |
503 | | - return m_outputDeviceChanged; |
504 | | -} |
505 | | - |
506 | | -void OSXAudioDriver::resume() |
507 | | -{ |
508 | | -} |
509 | | - |
510 | | -void OSXAudioDriver::suspend() |
511 | | -{ |
512 | | -} |
513 | | - |
514 | 412 | void OSXAudioDriver::logError(const std::string message, OSStatus error) |
515 | 413 | { |
516 | 414 | if (error == noErr) { |
@@ -561,6 +459,6 @@ static OSStatus onDeviceListChanged(AudioObjectID inObjectID, UInt32 inNumberAdd |
561 | 459 | void OSXAudioDriver::OnFillBuffer(void* context, AudioQueueRef, AudioQueueBufferRef buffer) |
562 | 460 | { |
563 | 461 | Data* pData = (Data*)context; |
564 | | - pData->callback(pData->mUserData, (uint8_t*)buffer->mAudioData, buffer->mAudioDataByteSize); |
| 462 | + pData->callback((uint8_t*)buffer->mAudioData, buffer->mAudioDataByteSize); |
565 | 463 | AudioQueueEnqueueBuffer(pData->audioQueue, buffer, 0, NULL); |
566 | 464 | } |
0 commit comments