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
96e8b37d
Commit
96e8b37d
authored
Nov 06, 2020
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Core Audio: Fix some issues with capture mode.
parent
a9ee8cf8
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
47 additions
and
23 deletions
+47
-23
miniaudio.h
miniaudio.h
+47
-23
No files found.
miniaudio.h
View file @
96e8b37d
...
@@ -22674,6 +22674,11 @@ static ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_cont
...
@@ -22674,6 +22674,11 @@ static ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_cont
Core Audio Backend
Core Audio Backend
References
==========
- Technical Note TN2091: Device input using the HAL Output Audio Unit
https://developer.apple.com/library/archive/technotes/tn2091/_index.html
******************************************************************************/
******************************************************************************/
#ifdef MA_HAS_COREAUDIO
#ifdef MA_HAS_COREAUDIO
#include <TargetConditionals.h>
#include <TargetConditionals.h>
...
@@ -23822,10 +23827,10 @@ static ma_result ma_get_AudioUnit_channel_map(ma_context* pContext, AudioUnit au
...
@@ -23822,10 +23827,10 @@ static ma_result ma_get_AudioUnit_channel_map(ma_context* pContext, AudioUnit au
MA_ASSERT(pContext != NULL);
MA_ASSERT(pContext != NULL);
if (deviceType == ma_device_type_playback) {
if (deviceType == ma_device_type_playback) {
deviceScope = kAudioUnitScope_
Out
put;
deviceScope = kAudioUnitScope_
In
put;
deviceBus = MA_COREAUDIO_OUTPUT_BUS;
deviceBus = MA_COREAUDIO_OUTPUT_BUS;
} else {
} else {
deviceScope = kAudioUnitScope_
In
put;
deviceScope = kAudioUnitScope_
Out
put;
deviceBus = MA_COREAUDIO_INPUT_BUS;
deviceBus = MA_COREAUDIO_INPUT_BUS;
}
}
...
@@ -24850,10 +24855,11 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
...
@@ -24850,10 +24855,11 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
UInt32 enableIOFlag;
UInt32 enableIOFlag;
AudioStreamBasicDescription bestFormat;
AudioStreamBasicDescription bestFormat;
ma_uint32 actualPeriodSizeInFrames;
ma_uint32 actualPeriodSizeInFrames;
ma_uint32 actualPeriodSizeInFramesSize = sizeof(actualPeriodSizeInFrames);
AURenderCallbackStruct callbackInfo;
AURenderCallbackStruct callbackInfo;
#if defined(MA_APPLE_DESKTOP)
#if defined(MA_APPLE_DESKTOP)
AudioObjectID deviceObjectID;
AudioObjectID deviceObjectID;
#else
ma_uint32 actualPeriodSizeInFramesSize = sizeof(actualPeriodSizeInFrames);
#endif
#endif
/* This API should only be used for a single device type: playback or capture. No full-duplex mode. */
/* This API should only be used for a single device type: playback or capture. No full-duplex mode. */
...
@@ -24919,7 +24925,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
...
@@ -24919,7 +24925,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
/* Set the device to use with this audio unit. This is only used on desktop since we are using defaults on mobile. */
/* Set the device to use with this audio unit. This is only used on desktop since we are using defaults on mobile. */
#if defined(MA_APPLE_DESKTOP)
#if defined(MA_APPLE_DESKTOP)
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global,
(deviceType == ma_device_type_playback) ? MA_COREAUDIO_OUTPUT_BUS : MA_COREAUDIO_INPUT_BUS, &deviceObjectID, sizeof(AudioDevice
ID));
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global,
0, &deviceObjectID, sizeof(deviceObject
ID));
if (status != noErr) {
if (status != noErr) {
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
return ma_result_from_OSStatus(result);
return ma_result_from_OSStatus(result);
...
@@ -24961,20 +24967,22 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
...
@@ -24961,20 +24967,22 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
On mobile platforms this is a bit different. We just force the use of whatever the audio unit's current format is set to.
On mobile platforms this is a bit different. We just force the use of whatever the audio unit's current format is set to.
*/
*/
{
{
AudioStreamBasicDescription origFormat;
UInt32 origFormatSize = sizeof(origFormat);
AudioUnitScope formatScope = (deviceType == ma_device_type_playback) ? kAudioUnitScope_Input : kAudioUnitScope_Output;
AudioUnitScope formatScope = (deviceType == ma_device_type_playback) ? kAudioUnitScope_Input : kAudioUnitScope_Output;
AudioUnitElement formatElement = (deviceType == ma_device_type_playback) ? MA_COREAUDIO_OUTPUT_BUS : MA_COREAUDIO_INPUT_BUS;
AudioUnitElement formatElement = (deviceType == ma_device_type_playback) ? MA_COREAUDIO_OUTPUT_BUS : MA_COREAUDIO_INPUT_BUS;
#if defined(MA_APPLE_DESKTOP)
if (deviceType == ma_device_type_playback) {
AudioStreamBasicDescription origFormat;
status = ((ma_AudioUnitGetProperty_proc)pContext->coreaudio.AudioUnitGetProperty)(pData->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, MA_COREAUDIO_OUTPUT_BUS, &origFormat, &origFormatSize);
UInt32 origFormatSize;
} else {
status = ((ma_AudioUnitGetProperty_proc)pContext->coreaudio.AudioUnitGetProperty)(pData->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, MA_COREAUDIO_INPUT_BUS, &origFormat, &origFormatSize);
origFormatSize = sizeof(origFormat);
}
status = ((ma_AudioUnitGetProperty_proc)pContext->coreaudio.AudioUnitGetProperty)(pData->audioUnit, kAudioUnitProperty_StreamFormat, formatScope, formatElement, &origFormat, &origFormatSize);
if (status != noErr) {
if (status != noErr) {
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
return result;
return result;
}
}
#if defined(MA_APPLE_DESKTOP)
result = ma_find_best_format__coreaudio(pContext, deviceObjectID, deviceType, pData->formatIn, pData->channelsIn, pData->sampleRateIn, pData->usingDefaultFormat, pData->usingDefaultChannels, pData->usingDefaultSampleRate, &origFormat, &bestFormat);
result = ma_find_best_format__coreaudio(pContext, deviceObjectID, deviceType, pData->formatIn, pData->channelsIn, pData->sampleRateIn, pData->usingDefaultFormat, pData->usingDefaultChannels, pData->usingDefaultSampleRate, &origFormat, &bestFormat);
if (result != MA_SUCCESS) {
if (result != MA_SUCCESS) {
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
...
@@ -24987,11 +24995,32 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
...
@@ -24987,11 +24995,32 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
I cannot remember where I read this in the documentation and I cannot find it again. For now I'm going to remove this
I cannot remember where I read this in the documentation and I cannot find it again. For now I'm going to remove this
and see what the feedback from the community is like. If this results in issues we can add it back in again. The idea
and see what the feedback from the community is like. If this results in issues we can add it back in again. The idea
is that the closest sample rate natively supported by the backend to the requested sample rate should be used if possible.
is that the closest sample rate natively supported by the backend to the requested sample rate should be used if possible.
Update 2020-11-06:
I have found the documentation that talks about keeping the sample rate consistent:
Technical Note TN2091: Device input using the HAL Output Audio Unit
https://developer.apple.com/library/archive/technotes/tn2091/_index.html
This documentation says the following:
The internal AudioConverter can handle any *simple* conversion. Typically, this means that a client can specify ANY
variant of the PCM formats. Consequently, the device's sample rate should match the desired sample rate. If sample rate
conversion is needed, it can be accomplished by buffering the input and converting the data on a separate thread with
another AudioConverter.
The important part here is the mention that it can handle *simple* conversions, which does *not* include sample rate. We
therefore want to ensure the sample rate stays consistent. This document is specifically for input, but I'm going to play it
safe and apply the same rule to output as well.
I have tried going against the documentation by setting the sample rate anyway, but this just results in AudioUnitRender()
returning a result code of -10863. I have also tried changing the format directly on the input scope on the input bus, but
this just results in `ca_require: IsStreamFormatWritable(inScope, inElement) NotWritable` when trying to set the format. At
this point I'm not sure how to change the sample rate on the device even if the device reports native support for it. If
anybody has any suggestions on this please let me know.
*/
*/
#if 0
/* From what I can see, Apple's documentation implies that we should keep the sample rate consistent. */
bestFormat.mSampleRate = origFormat.mSampleRate;
bestFormat.mSampleRate = origFormat.mSampleRate;
#endif
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioUnitProperty_StreamFormat, formatScope, formatElement, &bestFormat, sizeof(bestFormat));
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioUnitProperty_StreamFormat, formatScope, formatElement, &bestFormat, sizeof(bestFormat));
if (status != noErr) {
if (status != noErr) {
...
@@ -24999,12 +25028,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
...
@@ -24999,12 +25028,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
bestFormat = origFormat;
bestFormat = origFormat;
}
}
#else
#else
UInt32 propSize = sizeof(bestFormat);
bestFormat = origFormat;
status = ((ma_AudioUnitGetProperty_proc)pContext->coreaudio.AudioUnitGetProperty)(pData->audioUnit, kAudioUnitProperty_StreamFormat, formatScope, formatElement, &bestFormat, &propSize);
if (status != noErr) {
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
return ma_result_from_OSStatus(status);
}
/*
/*
Sample rate is a little different here because for some reason kAudioUnitProperty_StreamFormat returns 0... Oh well. We need to instead try
Sample rate is a little different here because for some reason kAudioUnitProperty_StreamFormat returns 0... Oh well. We need to instead try
...
@@ -25119,7 +25143,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
...
@@ -25119,7 +25143,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
of the size of our buffer, or do it the other way around and set our buffer size to the kAudioUnitProperty_MaximumFramesPerSlice.
of the size of our buffer, or do it the other way around and set our buffer size to the kAudioUnitProperty_MaximumFramesPerSlice.
*/
*/
{
{
/*AudioUnitScope propScope = (deviceType == ma_device_type_playback) ? kAudioUnitScope_
Input : kAudioUnitScope_Out
put;
/*AudioUnitScope propScope = (deviceType == ma_device_type_playback) ? kAudioUnitScope_
Output : kAudioUnitScope_In
put;
AudioUnitElement propBus = (deviceType == ma_device_type_playback) ? MA_COREAUDIO_OUTPUT_BUS : MA_COREAUDIO_INPUT_BUS;
AudioUnitElement propBus = (deviceType == ma_device_type_playback) ? MA_COREAUDIO_OUTPUT_BUS : MA_COREAUDIO_INPUT_BUS;
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, propScope, propBus, &actualBufferSizeInFrames, sizeof(actualBufferSizeInFrames));
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, propScope, propBus, &actualBufferSizeInFrames, sizeof(actualBufferSizeInFrames));
...
@@ -25184,14 +25208,14 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
...
@@ -25184,14 +25208,14 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
callbackInfo.inputProcRefCon = pDevice_DoNotReference;
callbackInfo.inputProcRefCon = pDevice_DoNotReference;
if (deviceType == ma_device_type_playback) {
if (deviceType == ma_device_type_playback) {
callbackInfo.inputProc = ma_on_output__coreaudio;
callbackInfo.inputProc = ma_on_output__coreaudio;
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global,
MA_COREAUDIO_OUTPUT_BUS
, &callbackInfo, sizeof(callbackInfo));
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global,
0
, &callbackInfo, sizeof(callbackInfo));
if (status != noErr) {
if (status != noErr) {
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
return ma_result_from_OSStatus(status);
return ma_result_from_OSStatus(status);
}
}
} else {
} else {
callbackInfo.inputProc = ma_on_input__coreaudio;
callbackInfo.inputProc = ma_on_input__coreaudio;
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global,
MA_COREAUDIO_INPUT_BUS
, &callbackInfo, sizeof(callbackInfo));
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global,
0
, &callbackInfo, sizeof(callbackInfo));
if (status != noErr) {
if (status != noErr) {
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
return ma_result_from_OSStatus(status);
return ma_result_from_OSStatus(status);
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