ao_coreaudio: set kAudioOutputUnitProperty_ChannelMap

This fixes #15584
This commit is contained in:
Misaki Kasumi authored and der richter committed 2025-01-03 13:44:00 +01:00
1 parent c9a99db26c
commit 06fe665b78
4 files changed
+42 -19

No files matched your search

+2 -16
View File
@@ -277,22 +277,8 @@ static int init(struct ao *ao)
AudioStreamBasicDescription asbd;
ca_fill_asbd(ao, &asbd);
size_t layout_size = sizeof(AudioChannelLayout)
+ (ao->channels.num - 1) * sizeof(AudioChannelDescription);
layout = talloc_size(ao, layout_size);
layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
layout->mNumberChannelDescriptions = ao->channels.num;
for (int i = 0; i < ao->channels.num; ++i) {
AudioChannelDescription *desc = layout->mChannelDescriptions + i;
desc->mChannelFlags = kAudioChannelFlags_AllOff;
desc->mChannelLabel = mp_speaker_id_to_ca_label(ao->channels.speaker[i]);
}
void *talloc_ctx = talloc_new(NULL);
AudioChannelLayout *std_layout = ca_find_standard_layout(talloc_ctx, layout);
memmove(layout, std_layout, sizeof(AudioChannelLayout));
talloc_free(talloc_ctx);
ca_log_layout(ao, MSGL_V, layout);
size_t layout_size;
layout = ca_get_acl(ao, &layout_size);
OSStatus err;
if ((err = CMAudioFormatDescriptionCreate(
+15 -3
View File
@@ -136,7 +136,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
return CONTROL_UNKNOWN;
}
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd);
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd, AudioChannelLayout *layout, size_t layout_size);
static void init_physical_format(struct ao *ao);
static void reinit_latency(struct ao *ao);
static bool register_hotplug_cb(struct ao *ao);
@@ -178,8 +178,13 @@ static int init(struct ao *ao)
AudioStreamBasicDescription asbd;
ca_fill_asbd(ao, &asbd);
size_t layout_size;
AudioChannelLayout *layout = ca_get_acl(ao, &layout_size);
if (!init_audiounit(ao, asbd))
bool r = init_audiounit(ao, asbd, layout, layout_size);
talloc_free(layout);
if (!r)
goto coreaudio_error;
reinit_latency(ao);
@@ -273,7 +278,7 @@ coreaudio_error:
return;
}
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd)
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd, AudioChannelLayout *layout, size_t layout_size)
{
OSStatus err;
uint32_t size;
@@ -317,6 +322,13 @@ static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd)
CHECK_CA_ERROR_L(coreaudio_error_audiounit,
"can't link audio unit to selected device");
err = AudioUnitSetProperty(p->audio_unit,
kAudioOutputUnitProperty_ChannelMap,
kAudioUnitScope_Global, 0, layout, layout_size);
CHECK_CA_ERROR_L(coreaudio_error_audiounit,
"unable to set the input channel layout on the audio unit");
AURenderCallbackStruct render_cb = (AURenderCallbackStruct) {
.inputProc = render_cb_lpcm,
.inputProcRefCon = ao,
+24
View File
@@ -314,6 +314,30 @@ mismatch:;
return s ? s : l;
}
AudioChannelLayout *ca_get_acl(struct ao *ao, size_t *out_layout_size)
{
size_t layout_size = sizeof(AudioChannelLayout)
+ (ao->channels.num - 1) * sizeof(AudioChannelDescription);
AudioChannelLayout *layout = talloc_size(ao, layout_size);
layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
layout->mNumberChannelDescriptions = ao->channels.num;
for (int i = 0; i < ao->channels.num; ++i) {
AudioChannelDescription *desc = layout->mChannelDescriptions + i;
desc->mChannelFlags = kAudioChannelFlags_AllOff;
desc->mChannelLabel = mp_speaker_id_to_ca_label(ao->channels.speaker[i]);
}
void *talloc_ctx = talloc_new(NULL);
AudioChannelLayout *std_layout = ca_find_standard_layout(talloc_ctx, layout);
memmove(layout, std_layout, sizeof(AudioChannelLayout));
talloc_free(talloc_ctx);
ca_log_layout(ao, MSGL_V, layout);
if (out_layout_size)
*out_layout_size = layout_size;
return layout;
}
#define CHMAP(n, ...) &(struct mp_chmap) MP_CONCAT(MP_CHMAP, n) (__VA_ARGS__)
+1
View File
@@ -28,6 +28,7 @@ AudioChannelLabel mp_speaker_id_to_ca_label(int speaker_id);
#if HAVE_COREAUDIO || HAVE_AVFOUNDATION
AudioChannelLayout *ca_find_standard_layout(void *talloc_ctx, AudioChannelLayout *l);
AudioChannelLayout *ca_get_acl(struct ao *ao, size_t *out_layout_size);
void ca_log_layout(struct ao *ao, int l, AudioChannelLayout *layout);
bool ca_init_chmap(struct ao *ao, AudioDeviceID device);
void ca_get_active_chmap(struct ao *ao, AudioDeviceID device, int channel_count,