Skip to content

Commit

Permalink
ao_coreaudio: set kAudioOutputUnitProperty_ChannelMap
Browse files Browse the repository at this point in the history
This fixes #15584
  • Loading branch information
ruihe774 authored and Akemi committed Jan 3, 2025
1 parent c9a99db commit 06fe665
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 19 deletions.
18 changes: 2 additions & 16 deletions audio/out/ao_avfoundation.m
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
18 changes: 15 additions & 3 deletions audio/out/ao_coreaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -273,7 +278,7 @@ static void init_physical_format(struct ao *ao)
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;
Expand Down Expand Up @@ -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,
Expand Down
24 changes: 24 additions & 0 deletions audio/out/ao_coreaudio_chmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__)

Expand Down
1 change: 1 addition & 0 deletions audio/out/ao_coreaudio_chmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 06fe665

Please sign in to comment.