summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-05-05 01:07:57 +0200
committerwm4 <wm4@nowhere>2015-05-05 01:11:16 +0200
commit8121529a6cc01a0d036c0a228e240c87994f1340 (patch)
tree856463a2649b80a47664de42eac80764fa90ac8d /audio
parent305a85cc9aa169a75317acb55e539f49d420f629 (diff)
downloadmpv-8121529a6cc01a0d036c0a228e240c87994f1340.tar.bz2
mpv-8121529a6cc01a0d036c0a228e240c87994f1340.tar.xz
ao_coreaudio: add an option for changing the physical format
ao_coreaudio uses AudioUnit - the OSX software mixer. In theory, it supports multichannel audio just fine. But in practice, this might be disabled by default, and the user is supposed to select a multichannel base format in the "Audio MIDI Setup" utility. This option attempts to change this setting automatically. Some possible disadvantages and caveats are listed in the manpage additions. It is off by default, since changing this might be rather bad behavior for a normal application.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_coreaudio.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index 65f7a070fd..85057bee67 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -33,6 +33,8 @@ struct priv {
AudioUnit audio_unit;
uint64_t hw_latency_us;
+
+ int change_physical_format;
};
bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
@@ -260,12 +262,61 @@ coreaudio_error:
return false;
}
+static void init_physical_format(struct ao *ao, AudioStreamBasicDescription asbd)
+{
+ struct priv *p = ao->priv;
+ OSErr err;
+
+ AudioStreamID *streams;
+ size_t n_streams;
+
+ err = CA_GET_ARY_O(p->device, kAudioDevicePropertyStreams,
+ &streams, &n_streams);
+ CHECK_CA_ERROR("could not get number of streams");
+
+ for (int i = 0; i < n_streams; i++) {
+ AudioStreamRangedDescription *formats;
+ size_t n_formats;
+
+ err = CA_GET_ARY(streams[i],
+ kAudioStreamPropertyAvailablePhysicalFormats,
+ &formats, &n_formats);
+
+ if (!CHECK_CA_WARN("could not get number of stream formats"))
+ continue; // try next one
+
+ AudioStreamBasicDescription best_asbd = {0};
+
+ for (int j = 0; j < n_formats; j++) {
+ AudioStreamBasicDescription *stream_asbd = &formats[j].mFormat;
+
+ if (!best_asbd.mFormatID || ca_asbd_is_better(&asbd, &best_asbd,
+ stream_asbd))
+ best_asbd = *stream_asbd;
+ }
+
+ if (best_asbd.mFormatID) {
+ ca_print_asbd(ao, "Trying to set physical format:", &best_asbd);
+ err = CA_SET(streams[i], kAudioStreamPropertyPhysicalFormat,
+ &best_asbd);
+ CHECK_CA_ERROR("could not set physical format");
+ break;
+ }
+ }
+
+coreaudio_error:
+ return;
+}
+
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd)
{
OSStatus err;
uint32_t size;
struct priv *p = ao->priv;
+ if (p->change_physical_format)
+ init_physical_format(ao, asbd);
+
AudioComponentDescription desc = (AudioComponentDescription) {
.componentType = kAudioUnitType_Output,
.componentSubType = (ao->device) ?
@@ -583,4 +634,8 @@ const struct ao_driver audio_out_coreaudio = {
.hotplug_uninit = hotplug_uninit,
.list_devs = ca_get_device_list,
.priv_size = sizeof(struct priv),
+ .options = (const struct m_option[]){
+ OPT_FLAG("change-physical-format", change_physical_format, 0),
+ {0}
+ },
};