ao_coreaudio: set kAudioOutputUnitProperty_ChannelMap
This fixes #15584
This commit is contained in:
1 parent
c9a99db26c
commit
06fe665b78
4 files changed
+42
-19
No files matched your search
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user