Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
miniaudio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
miniaudio
Commits
575009da
Commit
575009da
authored
Sep 28, 2019
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Core Audio: Fix bugs with automatic stream routing.
parent
6c5119f0
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
274 additions
and
114 deletions
+274
-114
miniaudio.h
miniaudio.h
+274
-114
No files found.
miniaudio.h
View file @
575009da
...
@@ -2199,6 +2199,7 @@ struct ma_context
...
@@ -2199,6 +2199,7 @@ struct ma_context
ma_proc AudioObjectGetPropertyDataSize;
ma_proc AudioObjectGetPropertyDataSize;
ma_proc AudioObjectSetPropertyData;
ma_proc AudioObjectSetPropertyData;
ma_proc AudioObjectAddPropertyListener;
ma_proc AudioObjectAddPropertyListener;
ma_proc AudioObjectRemovePropertyListener;
ma_handle hAudioUnit; /* Could possibly be set to AudioToolbox on later versions of macOS. */
ma_handle hAudioUnit; /* Could possibly be set to AudioToolbox on later versions of macOS. */
ma_proc AudioComponentFindNext;
ma_proc AudioComponentFindNext;
...
@@ -17343,6 +17344,7 @@ typedef OSStatus (* ma_AudioObjectGetPropertyData_proc)(AudioObjectID inObjectID
...
@@ -17343,6 +17344,7 @@ typedef OSStatus (* ma_AudioObjectGetPropertyData_proc)(AudioObjectID inObjectID
typedef OSStatus (* ma_AudioObjectGetPropertyDataSize_proc)(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32* outDataSize);
typedef OSStatus (* ma_AudioObjectGetPropertyDataSize_proc)(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32* outDataSize);
typedef OSStatus (* ma_AudioObjectSetPropertyData_proc)(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32 inDataSize, const void* inData);
typedef OSStatus (* ma_AudioObjectSetPropertyData_proc)(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32 inDataSize, const void* inData);
typedef OSStatus (* ma_AudioObjectAddPropertyListener_proc)(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, AudioObjectPropertyListenerProc inListener, void* inClientData);
typedef OSStatus (* ma_AudioObjectAddPropertyListener_proc)(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, AudioObjectPropertyListenerProc inListener, void* inClientData);
typedef OSStatus (* ma_AudioObjectRemovePropertyListener_proc)(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, AudioObjectPropertyListenerProc inListener, void* inClientData);
#endif
#endif
/* AudioToolbox */
/* AudioToolbox */
...
@@ -18733,28 +18735,6 @@ ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_device_
...
@@ -18733,28 +18735,6 @@ ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_device_
}
}
void ma_device_uninit__coreaudio(ma_device* pDevice)
{
ma_assert(pDevice != NULL);
ma_assert(ma_device__get_state(pDevice) == MA_STATE_UNINITIALIZED);
if (pDevice->coreaudio.audioUnitCapture != NULL) {
((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitCapture);
}
if (pDevice->coreaudio.audioUnitPlayback != NULL) {
((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
}
if (pDevice->coreaudio.pAudioBufferList) {
ma_free(pDevice->coreaudio.pAudioBufferList);
}
if (pDevice->type == ma_device_type_duplex) {
ma_pcm_rb_uninit(&pDevice->coreaudio.duplexRB);
}
}
OSStatus ma_on_output__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pActionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufferList)
OSStatus ma_on_output__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pActionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufferList)
{
{
ma_device* pDevice = (ma_device*)pUserData;
ma_device* pDevice = (ma_device*)pUserData;
...
@@ -19027,10 +19007,15 @@ void on_start_stop__coreaudio(void* pUserData, AudioUnit audioUnit, AudioUnitPro
...
@@ -19027,10 +19007,15 @@ void on_start_stop__coreaudio(void* pUserData, AudioUnit audioUnit, AudioUnitPro
}
}
#if defined(MA_APPLE_DESKTOP)
#if defined(MA_APPLE_DESKTOP)
static ma_uint32 g_DeviceTrackingInitCounter_CoreAudio = 0;
static ma_mutex g_DeviceTrackingMutex_CoreAudio;
static ma_device** g_ppTrackedDevices_CoreAudio = NULL;
static ma_uint32 g_TrackedDeviceCap_CoreAudio = 0;
static ma_uint32 g_TrackedDeviceCount_CoreAudio = 0;
OSStatus ma_default_device_changed__coreaudio(AudioObjectID objectID, UInt32 addressCount, const AudioObjectPropertyAddress* pAddresses, void* pUserData)
OSStatus ma_default_device_changed__coreaudio(AudioObjectID objectID, UInt32 addressCount, const AudioObjectPropertyAddress* pAddresses, void* pUserData)
{
{
ma_device* pDevice = (ma_device*)pUserData;
ma_device_type deviceType;
ma_assert(pDevice != NULL);
/* Not sure if I really need to check this, but it makes me feel better. */
/* Not sure if I really need to check this, but it makes me feel better. */
if (addressCount == 0) {
if (addressCount == 0) {
...
@@ -19038,56 +19023,223 @@ OSStatus ma_default_device_changed__coreaudio(AudioObjectID objectID, UInt32 add
...
@@ -19038,56 +19023,223 @@ OSStatus ma_default_device_changed__coreaudio(AudioObjectID objectID, UInt32 add
}
}
if (pAddresses[0].mSelector == kAudioHardwarePropertyDefaultOutputDevice) {
if (pAddresses[0].mSelector == kAudioHardwarePropertyDefaultOutputDevice) {
deviceType = ma_device_type_playback;
} else if (pAddresses[0].mSelector == kAudioHardwarePropertyDefaultInputDevice) {
deviceType = ma_device_type_capture;
} else {
return noErr; /* Should never hit this. */
}
ma_mutex_lock(&g_DeviceTrackingMutex_CoreAudio);
{
ma_uint32 iDevice;
for (iDevice = 0; iDevice < g_TrackedDeviceCount_CoreAudio; iDevice += 1) {
ma_result reinitResult;
ma_result reinitResult;
ma_device* pDevice;
pDevice = g_ppTrackedDevices_CoreAudio[iDevice];
if (pDevice->type == deviceType || pDevice->type == ma_device_type_duplex) {
if (deviceType == ma_device_type_playback) {
pDevice->coreaudio.isSwitchingPlaybackDevice = MA_TRUE;
pDevice->coreaudio.isSwitchingPlaybackDevice = MA_TRUE;
reinitResult = ma_device_reinit_internal__coreaudio(pDevice, ma_device_type_playback
, MA_TRUE);
reinitResult = ma_device_reinit_internal__coreaudio(pDevice, deviceType
, MA_TRUE);
pDevice->coreaudio.isSwitchingPlaybackDevice = MA_FALSE;
pDevice->coreaudio.isSwitchingPlaybackDevice = MA_FALSE;
} else {
pDevice->coreaudio.isSwitchingCaptureDevice = MA_TRUE;
reinitResult = ma_device_reinit_internal__coreaudio(pDevice, deviceType, MA_TRUE);
pDevice->coreaudio.isSwitchingCaptureDevice = MA_FALSE;
}
if (reinitResult == MA_SUCCESS) {
if (reinitResult == MA_SUCCESS) {
ma_device__post_init_setup(pDevice, ma_device_type_playback
);
ma_device__post_init_setup(pDevice, deviceType
);
/* Restart the device if required. If this fails we need to stop the device entirely. */
/* Restart the device if required. If this fails we need to stop the device entirely. */
if (ma_device__get_state(pDevice) == MA_STATE_STARTED) {
if (ma_device__get_state(pDevice) == MA_STATE_STARTED) {
OSStatus status = ((ma_AudioOutputUnitStart_proc)pDevice->pContext->coreaudio.AudioOutputUnitStart)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
OSStatus status;
if (deviceType == ma_device_type_playback) {
status = ((ma_AudioOutputUnitStart_proc)pDevice->pContext->coreaudio.AudioOutputUnitStart)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
if (status != noErr) {
if (status != noErr) {
if (pDevice->type == ma_device_type_duplex) {
if (pDevice->type == ma_device_type_duplex) {
((ma_AudioOutputUnitStop_proc)pDevice->pContext->coreaudio.AudioOutputUnitStop)((AudioUnit)pDevice->coreaudio.audioUnitCapture);
((ma_AudioOutputUnitStop_proc)pDevice->pContext->coreaudio.AudioOutputUnitStop)((AudioUnit)pDevice->coreaudio.audioUnitCapture);
}
}
ma_device__set_state(pDevice, MA_STATE_STOPPED);
ma_device__set_state(pDevice, MA_STATE_STOPPED);
}
}
} else if (deviceType == ma_device_type_capture) {
status = ((ma_AudioOutputUnitStart_proc)pDevice->pContext->coreaudio.AudioOutputUnitStart)((AudioUnit)pDevice->coreaudio.audioUnitCapture);
if (status != noErr) {
if (pDevice->type == ma_device_type_duplex) {
((ma_AudioOutputUnitStop_proc)pDevice->pContext->coreaudio.AudioOutputUnitStop)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
}
ma_device__set_state(pDevice, MA_STATE_STOPPED);
}
}
}
}
}
}
}
}
}
}
ma_mutex_unlock(&g_DeviceTrackingMutex_CoreAudio);
if (pAddresses[0].mSelector == kAudioHardwarePropertyDefaultInputDevice) {
(void)objectID; /* Unused. */
ma_result reinitResult;
return noErr;
}
pDevice->coreaudio.isSwitchingPlaybackDevice = MA_TRUE;
static ma_result ma_context__init_device_tracking__coreaudio(ma_context* pContext)
reinitResult = ma_device_reinit_internal__coreaudio(pDevice, ma_device_type_capture, MA_TRUE);
{
pDevice->coreaudio.isSwitchingPlaybackDevice = MA_FALSE
;
ma_assert(pContext != NULL)
;
if (reinitResult == MA_SUCCESS) {
if (ma_atomic_increment_32(&g_DeviceTrackingInitCounter_CoreAudio) == 1) {
ma_device__post_init_setup(pDevice, ma_device_type_capture);
AudioObjectPropertyAddress propAddress;
propAddress.mScope = kAudioObjectPropertyScopeGlobal;
propAddress.mElement = kAudioObjectPropertyElementMaster;
/* Restart the device if required. If this fails we need to stop the device entirely. */
ma_mutex_init(pContext, &g_DeviceTrackingMutex_CoreAudio);
if (ma_device__get_state(pDevice) == MA_STATE_STARTED) {
OSStatus status = ((ma_AudioOutputUnitStart_proc)pDevice->pContext->coreaudio.AudioOutputUnitStart)((AudioUnit)pDevice->coreaudio.audioUnitCapture);
propAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
if (status != noErr) {
((ma_AudioObjectAddPropertyListener_proc)pContext->coreaudio.AudioObjectAddPropertyListener)(kAudioObjectSystemObject, &propAddress, &ma_default_device_changed__coreaudio, NULL);
if (pDevice->type == ma_device_type_duplex) {
((ma_AudioOutputUnitStop_proc)pDevice->pContext->coreaudio.AudioOutputUnitStop)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
propAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
((ma_AudioObjectAddPropertyListener_proc)pContext->coreaudio.AudioObjectAddPropertyListener)(kAudioObjectSystemObject, &propAddress, &ma_default_device_changed__coreaudio, NULL);
}
}
ma_device__set_state(pDevice, MA_STATE_STOPPED);
return MA_SUCCESS;
}
static ma_result ma_context__uninit_device_tracking__coreaudio(ma_context* pContext)
{
ma_assert(pContext != NULL);
if (ma_atomic_decrement_32(&g_DeviceTrackingInitCounter_CoreAudio) == 0) {
AudioObjectPropertyAddress propAddress;
propAddress.mScope = kAudioObjectPropertyScopeGlobal;
propAddress.mElement = kAudioObjectPropertyElementMaster;
propAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
((ma_AudioObjectRemovePropertyListener_proc)pContext->coreaudio.AudioObjectRemovePropertyListener)(kAudioObjectSystemObject, &propAddress, &ma_default_device_changed__coreaudio, NULL);
propAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
((ma_AudioObjectRemovePropertyListener_proc)pContext->coreaudio.AudioObjectRemovePropertyListener)(kAudioObjectSystemObject, &propAddress, &ma_default_device_changed__coreaudio, NULL);
/* At this point there should be no tracked devices. If so there's an error somewhere. */
ma_assert(g_ppTrackedDevices_CoreAudio == NULL);
ma_assert(g_TrackedDeviceCount_CoreAudio == 0);
ma_mutex_uninit(&g_DeviceTrackingMutex_CoreAudio);
}
}
return MA_SUCCESS;
}
static ma_result ma_device__track__coreaudio(ma_device* pDevice)
{
ma_result result;
ma_assert(pDevice != NULL);
result = ma_context__init_device_tracking__coreaudio(pDevice->pContext);
if (result != MA_SUCCESS) {
return result;
}
}
ma_mutex_lock(&g_DeviceTrackingMutex_CoreAudio);
{
/* Allocate memory if required. */
if (g_TrackedDeviceCap_CoreAudio <= g_TrackedDeviceCount_CoreAudio) {
ma_uint32 newCap;
ma_device** ppNewDevices;
newCap = g_TrackedDeviceCap_CoreAudio * 2;
if (newCap == 0) {
newCap = 1;
}
}
ppNewDevices = (ma_device**)ma_realloc(g_ppTrackedDevices_CoreAudio, sizeof(*g_ppTrackedDevices_CoreAudio) * newCap);
if (ppNewDevices == NULL) {
ma_mutex_unlock(&g_DeviceTrackingMutex_CoreAudio);
return MA_OUT_OF_MEMORY;
}
}
(void)objectID; /* Unused. */
g_ppTrackedDevices_CoreAudio = ppNewDevices;
return noErr;
g_TrackedDeviceCap_CoreAudio = newCap;
}
g_ppTrackedDevices_CoreAudio[g_TrackedDeviceCount_CoreAudio] = pDevice;
g_TrackedDeviceCount_CoreAudio += 1;
}
ma_mutex_unlock(&g_DeviceTrackingMutex_CoreAudio);
return MA_SUCCESS;
}
static ma_result ma_device__untrack__coreaudio(ma_device* pDevice)
{
ma_result result;
ma_assert(pDevice != NULL);
ma_mutex_lock(&g_DeviceTrackingMutex_CoreAudio);
{
ma_uint32 iDevice;
for (iDevice = 0; iDevice < g_TrackedDeviceCount_CoreAudio; iDevice += 1) {
if (g_ppTrackedDevices_CoreAudio[iDevice] == pDevice) {
/* We've found the device. We now need to remove it from the list. */
ma_uint32 jDevice;
for (jDevice = iDevice; jDevice < g_TrackedDeviceCount_CoreAudio-1; jDevice += 1) {
g_ppTrackedDevices_CoreAudio[jDevice] = g_ppTrackedDevices_CoreAudio[jDevice+1];
}
g_TrackedDeviceCount_CoreAudio -= 1;
/* If there's nothing else in the list we need to free memory. */
if (g_TrackedDeviceCount_CoreAudio == 0) {
ma_free(g_ppTrackedDevices_CoreAudio);
g_ppTrackedDevices_CoreAudio = NULL;
g_TrackedDeviceCap_CoreAudio = 0;
}
break;
}
}
}
ma_mutex_unlock(&g_DeviceTrackingMutex_CoreAudio);
result = ma_context__uninit_device_tracking__coreaudio(pDevice->pContext);
if (result != MA_SUCCESS) {
return result;
}
return MA_SUCCESS;
}
}
#endif
#endif
void ma_device_uninit__coreaudio(ma_device* pDevice)
{
ma_assert(pDevice != NULL);
ma_assert(ma_device__get_state(pDevice) == MA_STATE_UNINITIALIZED);
#if defined(MA_APPLE_DESKTOP)
/*
Make sure we're no longer tracking the device. It doesn't matter if we call this for a non-default device because it'll
just gracefully ignore it.
*/
ma_device__untrack__coreaudio(pDevice);
#endif
if (pDevice->coreaudio.audioUnitCapture != NULL) {
((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitCapture);
}
if (pDevice->coreaudio.audioUnitPlayback != NULL) {
((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
}
if (pDevice->coreaudio.pAudioBufferList) {
ma_free(pDevice->coreaudio.pAudioBufferList);
}
if (pDevice->type == ma_device_type_duplex) {
ma_pcm_rb_uninit(&pDevice->coreaudio.duplexRB);
}
}
typedef struct
typedef struct
{
{
/* Input. */
/* Input. */
...
@@ -19486,14 +19638,7 @@ ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_device_typ
...
@@ -19486,14 +19638,7 @@ ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_device_typ
if (pDevice->coreaudio.pAudioBufferList) {
if (pDevice->coreaudio.pAudioBufferList) {
ma_free(pDevice->coreaudio.pAudioBufferList);
ma_free(pDevice->coreaudio.pAudioBufferList);
}
}
} else if (deviceType == ma_device_type_playback) {
#if defined(MA_APPLE_DESKTOP)
pDevice->coreaudio.deviceObjectIDCapture = (ma_uint32)data.deviceObjectID;
#endif
pDevice->coreaudio.audioUnitCapture = (ma_ptr)data.audioUnit;
pDevice->coreaudio.pAudioBufferList = (ma_ptr)data.pAudioBufferList;
}
if (deviceType == ma_device_type_playback) {
data.formatIn = pDevice->playback.format;
data.formatIn = pDevice->playback.format;
data.channelsIn = pDevice->playback.channels;
data.channelsIn = pDevice->playback.channels;
data.sampleRateIn = pDevice->sampleRate;
data.sampleRateIn = pDevice->sampleRate;
...
@@ -19509,11 +19654,6 @@ ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_device_typ
...
@@ -19509,11 +19654,6 @@ ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_device_typ
((ma_AudioOutputUnitStop_proc)pDevice->pContext->coreaudio.AudioOutputUnitStop)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
((ma_AudioOutputUnitStop_proc)pDevice->pContext->coreaudio.AudioOutputUnitStop)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitPlayback);
}
}
#if defined(MA_APPLE_DESKTOP)
pDevice->coreaudio.deviceObjectIDPlayback = (ma_uint32)data.deviceObjectID;
#endif
pDevice->coreaudio.audioUnitPlayback = (ma_ptr)data.audioUnit;
}
}
data.bufferSizeInFramesIn = pDevice->coreaudio.originalBufferSizeInFrames;
data.bufferSizeInFramesIn = pDevice->coreaudio.originalBufferSizeInFrames;
data.bufferSizeInMillisecondsIn = pDevice->coreaudio.originalBufferSizeInMilliseconds;
data.bufferSizeInMillisecondsIn = pDevice->coreaudio.originalBufferSizeInMilliseconds;
...
@@ -19524,6 +19664,33 @@ ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_device_typ
...
@@ -19524,6 +19664,33 @@ ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_device_typ
return result;
return result;
}
}
if (deviceType == ma_device_type_capture) {
#if defined(MA_APPLE_DESKTOP)
pDevice->coreaudio.deviceObjectIDCapture = (ma_uint32)data.deviceObjectID;
#endif
pDevice->coreaudio.audioUnitCapture = (ma_ptr)data.audioUnit;
pDevice->coreaudio.pAudioBufferList = (ma_ptr)data.pAudioBufferList;
pDevice->capture.internalFormat = data.formatOut;
pDevice->capture.internalChannels = data.channelsOut;
pDevice->capture.internalSampleRate = data.sampleRateOut;
ma_copy_memory(pDevice->capture.internalChannelMap, data.channelMapOut, sizeof(data.channelMapOut));
pDevice->capture.internalBufferSizeInFrames = data.bufferSizeInFramesOut;
pDevice->capture.internalPeriods = data.periodsOut;
} else if (deviceType == ma_device_type_playback) {
#if defined(MA_APPLE_DESKTOP)
pDevice->coreaudio.deviceObjectIDPlayback = (ma_uint32)data.deviceObjectID;
#endif
pDevice->coreaudio.audioUnitPlayback = (ma_ptr)data.audioUnit;
pDevice->playback.internalFormat = data.formatOut;
pDevice->playback.internalChannels = data.channelsOut;
pDevice->playback.internalSampleRate = data.sampleRateOut;
ma_copy_memory(pDevice->playback.internalChannelMap, data.channelMapOut, sizeof(data.channelMapOut));
pDevice->playback.internalBufferSizeInFrames = data.bufferSizeInFramesOut;
pDevice->playback.internalPeriods = data.periodsOut;
}
return MA_SUCCESS;
return MA_SUCCESS;
}
}
...
@@ -19581,18 +19748,13 @@ ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device_config
...
@@ -19581,18 +19748,13 @@ ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device_config
pDevice->capture.internalBufferSizeInFrames = data.bufferSizeInFramesOut;
pDevice->capture.internalBufferSizeInFrames = data.bufferSizeInFramesOut;
pDevice->capture.internalPeriods = data.periodsOut;
pDevice->capture.internalPeriods = data.periodsOut;
/* TODO: This needs to be made global. */
#if defined(MA_APPLE_DESKTOP)
#if defined(MA_APPLE_DESKTOP)
/*
/*
If we are using the default device we'll need to listen for changes to the system's default device so we can seemlessly
If we are using the default device we'll need to listen for changes to the system's default device so we can seemlessly
switch the device in the background.
switch the device in the background.
*/
*/
if (pConfig->capture.pDeviceID == NULL) {
if (pConfig->capture.pDeviceID == NULL) {
AudioObjectPropertyAddress propAddress;
ma_device__track__coreaudio(pDevice);
propAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
propAddress.mScope = kAudioObjectPropertyScopeGlobal;
propAddress.mElement = kAudioObjectPropertyElementMaster;
((ma_AudioObjectAddPropertyListener_proc)pDevice->pContext->coreaudio.AudioObjectAddPropertyListener)(kAudioObjectSystemObject, &propAddress, &ma_default_device_changed__coreaudio, pDevice);
}
}
#endif
#endif
}
}
...
@@ -19646,18 +19808,13 @@ ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device_config
...
@@ -19646,18 +19808,13 @@ ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device_config
pDevice->playback.internalBufferSizeInFrames = data.bufferSizeInFramesOut;
pDevice->playback.internalBufferSizeInFrames = data.bufferSizeInFramesOut;
pDevice->playback.internalPeriods = data.periodsOut;
pDevice->playback.internalPeriods = data.periodsOut;
/* TODO: This needs to be made global. */
#if defined(MA_APPLE_DESKTOP)
#if defined(MA_APPLE_DESKTOP)
/*
/*
If we are using the default device we'll need to listen for changes to the system's default device so we can seemlessly
If we are using the default device we'll need to listen for changes to the system's default device so we can seemlessly
switch the device in the background.
switch the device in the background.
*/
*/
if (pConfig->playback.pDeviceID == NULL) {
if (pConfig->playback.pDeviceID == NULL && (pConfig->deviceType != ma_device_type_duplex || pConfig->capture.pDeviceID != NULL)) {
AudioObjectPropertyAddress propAddress;
ma_device__track__coreaudio(pDevice);
propAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
propAddress.mScope = kAudioObjectPropertyScopeGlobal;
propAddress.mElement = kAudioObjectPropertyElementMaster;
((ma_AudioObjectAddPropertyListener_proc)pDevice->pContext->coreaudio.AudioObjectAddPropertyListener)(kAudioObjectSystemObject, &propAddress, &ma_default_device_changed__coreaudio, pDevice);
}
}
#endif
#endif
}
}
...
@@ -19789,6 +19946,7 @@ ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma_contex
...
@@ -19789,6 +19946,7 @@ ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma_contex
pContext->coreaudio.AudioObjectGetPropertyDataSize = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyDataSize");
pContext->coreaudio.AudioObjectGetPropertyDataSize = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyDataSize");
pContext->coreaudio.AudioObjectSetPropertyData = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectSetPropertyData");
pContext->coreaudio.AudioObjectSetPropertyData = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectSetPropertyData");
pContext->coreaudio.AudioObjectAddPropertyListener = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectAddPropertyListener");
pContext->coreaudio.AudioObjectAddPropertyListener = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectAddPropertyListener");
pContext->coreaudio.AudioObjectRemovePropertyListener = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectRemovePropertyListener");
/*
/*
It looks like Apple has moved some APIs from AudioUnit into AudioToolbox on more recent versions of macOS. They are still
It looks like Apple has moved some APIs from AudioUnit into AudioToolbox on more recent versions of macOS. They are still
...
@@ -19834,6 +19992,7 @@ ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma_contex
...
@@ -19834,6 +19992,7 @@ ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma_contex
pContext->coreaudio.AudioObjectGetPropertyDataSize = (ma_proc)AudioObjectGetPropertyDataSize;
pContext->coreaudio.AudioObjectGetPropertyDataSize = (ma_proc)AudioObjectGetPropertyDataSize;
pContext->coreaudio.AudioObjectSetPropertyData = (ma_proc)AudioObjectSetPropertyData;
pContext->coreaudio.AudioObjectSetPropertyData = (ma_proc)AudioObjectSetPropertyData;
pContext->coreaudio.AudioObjectAddPropertyListener = (ma_proc)AudioObjectAddPropertyListener;
pContext->coreaudio.AudioObjectAddPropertyListener = (ma_proc)AudioObjectAddPropertyListener;
pContext->coreaudio.AudioObjectRemovePropertyListener = (ma_proc)AudioObjectRemovePropertyListener;
#endif
#endif
pContext->coreaudio.AudioComponentFindNext = (ma_proc)AudioComponentFindNext;
pContext->coreaudio.AudioComponentFindNext = (ma_proc)AudioComponentFindNext;
...
@@ -34675,6 +34834,7 @@ REVISION HISTORY
...
@@ -34675,6 +34834,7 @@ REVISION HISTORY
v0.9.8 - 2019-xx-xx
v0.9.8 - 2019-xx-xx
- WASAPI: Fix a potential deadlock when starting a full-duplex device.
- WASAPI: Fix a potential deadlock when starting a full-duplex device.
- WASAPI: Enable automatic resampling by default. Disable with config.wasapi.noAutoConvertSRC.
- WASAPI: Enable automatic resampling by default. Disable with config.wasapi.noAutoConvertSRC.
- Core Audio: Fix bugs with automatic stream routing.
- Fix some uncommon warnings emitted by GCC when `__inline__` is undefined or defined as nothing.
- Fix some uncommon warnings emitted by GCC when `__inline__` is undefined or defined as nothing.
v0.9.7 - 2019-08-28
v0.9.7 - 2019-08-28
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment