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
b9667f02
Commit
b9667f02
authored
Nov 06, 2020
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Core Audio: Improvements to sample rate selection on desktop.
parent
9d1aee1a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
67 additions
and
36 deletions
+67
-36
miniaudio.h
miniaudio.h
+67
-36
No files found.
miniaudio.h
View file @
b9667f02
...
...
@@ -3197,6 +3197,10 @@ typedef struct
const char* pStreamNamePlayback;
const char* pStreamNameCapture;
} pulse;
struct
{
ma_bool32 allowNominalSampleRateChange; /* Desktop only. When enabled, allows changing of the sample rate at the operating system level. */
} coreaudio;
} ma_device_config;
typedef struct
...
...
@@ -4601,6 +4605,13 @@ then be set directly on the structure. Below are the members of the `ma_device_c
pulse.pStreamNameCapture
PulseAudio only. Sets the stream name for capture.
coreaudio.allowNominalSampleRateChange
Core Audio only. Desktop only. When enabled, allows the sample rate of the device to be changed at the operating system level. This
is disabled by default in order to prevent intrusive changes to the user's system. This is useful if you want to use a sample rate
that is known to be natively supported by the hardware thereby avoiding the cost of resampling. When set to true, miniaudio will
find the closest match between the sample rate requested in the device config and the sample rates natively supported by the
hardware. When set to false, the sample rate currently set by the operating system will always be used.
Once initialized, the device's config is immutable. If you need to change the config you will need to initialize a new device.
...
...
@@ -24816,6 +24827,8 @@ static void ma_device_uninit__coreaudio(ma_device* pDevice)
typedef struct
{
ma_bool32 allowNominalSampleRateChange;
/* Input. */
ma_format formatIn;
ma_uint32 channelsIn;
...
...
@@ -24990,16 +25003,6 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
}
/*
Update 2020-10-10:
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
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
...
...
@@ -25016,11 +25019,34 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
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.
this just results in `ca_require: IsStreamFormatWritable(inScope, inElement) NotWritable` when trying to set the format.
Something that does seem to work, however, has been setting the nominal sample rate on the deivce object. The problem with
this, however, is that it actually changes the sample rate at the operating system level and not just the application. This
could be intrusive to the user, however, so I don't think it's wise to make this the default. Instead I'm making this a
configuration option. When the `coreaudio.allowNominalSampleRateChange` config option is set to true, changing the sample
rate will be allowed. Otherwise it'll be fixed to the current sample rate. To check the system-defined sample rate, run
the Audio MIDI Setup program that comes installed on macOS and observe how the sample rate changes as the sample rate is
changed by miniaudio.
*/
if (pData->allowNominalSampleRateChange) {
AudioValueRange sampleRateRange;
AudioObjectPropertyAddress propAddress;
sampleRateRange.mMinimum = bestFormat.mSampleRate;
sampleRateRange.mMaximum = bestFormat.mSampleRate;
propAddress.mSelector = kAudioDevicePropertyNominalSampleRate;
propAddress.mScope = (deviceType == ma_device_type_playback) ? kAudioObjectPropertyScopeOutput : kAudioObjectPropertyScopeInput;
propAddress.mElement = kAudioObjectPropertyElementMaster;
status = ((ma_AudioObjectSetPropertyData_proc)pContext->coreaudio.AudioObjectSetPropertyData)(deviceObjectID, &propAddress, 0, NULL, sizeof(sampleRateRange), &sampleRateRange);
if (status != noErr) {
bestFormat.mSampleRate = origFormat.mSampleRate;
}
} else {
bestFormat.mSampleRate = origFormat.mSampleRate;
}
status = ((ma_AudioUnitSetProperty_proc)pContext->coreaudio.AudioUnitSetProperty)(pData->audioUnit, kAudioUnitProperty_StreamFormat, formatScope, formatElement, &bestFormat, sizeof(bestFormat));
if (status != noErr) {
...
...
@@ -25265,6 +25291,8 @@ static ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_dev
return MA_INVALID_ARGS;
}
data.allowNominalSampleRateChange = MA_FALSE; /* Don't change the nominal sample rate when switching devices. */
if (deviceType == ma_device_type_capture) {
data.formatIn = pDevice->capture.format;
data.channelsIn = pDevice->capture.channels;
...
...
@@ -25368,6 +25396,7 @@ static ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device
/* Capture needs to be initialized first. */
if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
ma_device_init_internal_data__coreaudio data;
data.allowNominalSampleRateChange = pConfig->coreaudio.allowNominalSampleRateChange;
data.formatIn = pConfig->capture.format;
data.channelsIn = pConfig->capture.channels;
data.sampleRateIn = pConfig->sampleRate;
...
...
@@ -25421,6 +25450,7 @@ static ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device
/* Playback. */
if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
ma_device_init_internal_data__coreaudio data;
data.allowNominalSampleRateChange = pConfig->coreaudio.allowNominalSampleRateChange;
data.formatIn = pConfig->playback.format;
data.channelsIn = pConfig->playback.channels;
data.sampleRateIn = pConfig->sampleRate;
...
...
@@ -62960,6 +62990,7 @@ v0.10.22 - TBD
- Fix some compilation warnings on GCC and Clang relating to the Speex resampler.
- Fix a compilation error for the Linux build when the ALSA and JACK backends are both disabled.
- ALSA: Fix a bug in `ma_context_get_device_info()` where the PCM handle is left open in the event of an error.
- Core Audio: Further improvements to sample rate selection.
- Add support for detecting default devices during device enumeration and with `ma_context_get_device_info()`.
- Add documentation for `MA_NO_RUNTIME_LINKING`.
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