зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1469152: Fix playback on older macOS systems and some 3rd party audio cards. r=kinetik
We were using an audio API not available prior 10.12. Also add a workaround for 3rd party audio cards with unusually high channels count. This cherry-pick cubeb commits 59f5cb4ba01f21c4ad87e9404d1e470408e18505 and dbd61924736fbe1a1caf1cbd544f7d197f1836f7 Differential Revision: https://phabricator.services.mozilla.com/D2041 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
96465b5cd1
Коммит
5041ae2d32
|
@ -0,0 +1,68 @@
|
|||
From 59f5cb4ba01f21c4ad87e9404d1e470408e18505 Mon Sep 17 00:00:00 2001
|
||||
From: Jean-Yves Avenard <jyavenard@mozilla.com>
|
||||
Date: Mon, 9 Jul 2018 17:37:16 +0200
|
||||
Subject: [PATCH 1/2] Correctly retrieve the output layout on macOS < 10.12.
|
||||
|
||||
The method kAudioUnitProperty_AudioChannelLayout used to retrieve the channel layout wasn't introduced until 10.12. So we use kAudioDevicePropertyPreferredChannelLayout instead should it fails.
|
||||
|
||||
Fixes #448
|
||||
---
|
||||
src/cubeb_audiounit.cpp | 35 ++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 34 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/cubeb_audiounit.cpp b/src/cubeb_audiounit.cpp
|
||||
index 6163ed7..43120b3 100644
|
||||
--- a/src/cubeb_audiounit.cpp
|
||||
+++ b/src/cubeb_audiounit.cpp
|
||||
@@ -1239,6 +1239,38 @@ audiounit_convert_channel_layout(AudioChannelLayout * layout)
|
||||
return cl;
|
||||
}
|
||||
|
||||
+static cubeb_channel_layout
|
||||
+audiounit_get_preferred_channel_layout(AudioUnit output_unit)
|
||||
+{
|
||||
+ OSStatus rv = noErr;
|
||||
+ UInt32 size = 0;
|
||||
+ rv = AudioUnitGetPropertyInfo(output_unit,
|
||||
+ kAudioDevicePropertyPreferredChannelLayout,
|
||||
+ kAudioUnitScope_Output,
|
||||
+ AU_OUT_BUS,
|
||||
+ &size,
|
||||
+ nullptr);
|
||||
+ if (rv != noErr) {
|
||||
+ LOG("AudioUnitGetPropertyInfo/kAudioDevicePropertyPreferredChannelLayout rv=%d", rv);
|
||||
+ return CUBEB_LAYOUT_UNDEFINED;
|
||||
+ }
|
||||
+ assert(size > 0);
|
||||
+
|
||||
+ auto layout = make_sized_audio_channel_layout(size);
|
||||
+ rv = AudioUnitGetProperty(output_unit,
|
||||
+ kAudioDevicePropertyPreferredChannelLayout,
|
||||
+ kAudioUnitScope_Output,
|
||||
+ AU_OUT_BUS,
|
||||
+ layout.get(),
|
||||
+ &size);
|
||||
+ if (rv != noErr) {
|
||||
+ LOG("AudioUnitGetProperty/kAudioDevicePropertyPreferredChannelLayout rv=%d", rv);
|
||||
+ return CUBEB_LAYOUT_UNDEFINED;
|
||||
+ }
|
||||
+
|
||||
+ return audiounit_convert_channel_layout(layout.get());
|
||||
+}
|
||||
+
|
||||
static cubeb_channel_layout
|
||||
audiounit_get_current_channel_layout(AudioUnit output_unit)
|
||||
{
|
||||
@@ -1252,7 +1284,8 @@ audiounit_get_current_channel_layout(AudioUnit output_unit)
|
||||
nullptr);
|
||||
if (rv != noErr) {
|
||||
LOG("AudioUnitGetPropertyInfo/kAudioUnitProperty_AudioChannelLayout rv=%d", rv);
|
||||
- return CUBEB_LAYOUT_UNDEFINED;
|
||||
+ // This property isn't known before macOS 10.12, attempt another method.
|
||||
+ return audiounit_get_preferred_channel_layout(output_unit);
|
||||
}
|
||||
assert(size > 0);
|
||||
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
From dbd61924736fbe1a1caf1cbd544f7d197f1836f7 Mon Sep 17 00:00:00 2001
|
||||
From: Jean-Yves Avenard <jyavenard@mozilla.com>
|
||||
Date: Mon, 9 Jul 2018 20:10:13 +0200
|
||||
Subject: [PATCH 2/2] Always upmix mono to the first two channels if enough
|
||||
output channels are available
|
||||
|
||||
This allows to output what people typically expect when playing mono audio: sound coming from both left and right channels.
|
||||
|
||||
To force this conversion for happening on mac, we tag that layout are unknown as soon as a channel type is unknown
|
||||
---
|
||||
src/cubeb_audiounit.cpp | 8 ++++++--
|
||||
src/cubeb_mixer.cpp | 12 ++++++++++++
|
||||
2 files changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/cubeb_audiounit.cpp b/src/cubeb_audiounit.cpp
|
||||
index 43120b3..5a83098 100644
|
||||
--- a/src/cubeb_audiounit.cpp
|
||||
+++ b/src/cubeb_audiounit.cpp
|
||||
@@ -291,7 +291,7 @@ cubeb_channel_to_channel_label(cubeb_channel channel)
|
||||
case CHANNEL_TOP_BACK_RIGHT:
|
||||
return kAudioChannelLabel_TopBackRight;
|
||||
default:
|
||||
- return CHANNEL_UNKNOWN;
|
||||
+ return kAudioChannelLabel_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1232,8 +1232,12 @@ audiounit_convert_channel_layout(AudioChannelLayout * layout)
|
||||
|
||||
cubeb_channel_layout cl = 0;
|
||||
for (UInt32 i = 0; i < layout->mNumberChannelDescriptions; ++i) {
|
||||
- cl |= channel_label_to_cubeb_channel(
|
||||
+ cubeb_channel cc = channel_label_to_cubeb_channel(
|
||||
layout->mChannelDescriptions[i].mChannelLabel);
|
||||
+ if (cc == CHANNEL_UNKNOWN) {
|
||||
+ return CUBEB_LAYOUT_UNDEFINED;
|
||||
+ }
|
||||
+ cl |= cc;
|
||||
}
|
||||
|
||||
return cl;
|
||||
diff --git a/src/cubeb_mixer.cpp b/src/cubeb_mixer.cpp
|
||||
index 8995c55..9aa141d 100644
|
||||
--- a/src/cubeb_mixer.cpp
|
||||
+++ b/src/cubeb_mixer.cpp
|
||||
@@ -533,6 +533,18 @@ struct cubeb_mixer
|
||||
output_buffer += _context._out_ch_count - _context._in_ch_count;
|
||||
}
|
||||
} else {
|
||||
+ if (_context._in_ch_count == 1 && _context._out_ch_count >= 2) {
|
||||
+ // Special case for upmixing mono input to stereo and more. We will
|
||||
+ // duplicate the mono channel to the first two channels. On most system,
|
||||
+ // the first two channels are for left and right. It is commonly
|
||||
+ // expected that mono will on both left+right channels
|
||||
+ for (uint32_t i = 0; i < frames; i++) {
|
||||
+ output_buffer[0] = output_buffer[1] = *input_buffer;
|
||||
+ output_buffer += _context._out_ch_count ;
|
||||
+ input_buffer++;
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
PodCopy(output_buffer, input_buffer, _context._out_ch_count);
|
||||
output_buffer += _context._out_ch_count;
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -291,7 +291,7 @@ cubeb_channel_to_channel_label(cubeb_channel channel)
|
|||
case CHANNEL_TOP_BACK_RIGHT:
|
||||
return kAudioChannelLabel_TopBackRight;
|
||||
default:
|
||||
return CHANNEL_UNKNOWN;
|
||||
return kAudioChannelLabel_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1232,13 +1232,49 @@ audiounit_convert_channel_layout(AudioChannelLayout * layout)
|
|||
|
||||
cubeb_channel_layout cl = 0;
|
||||
for (UInt32 i = 0; i < layout->mNumberChannelDescriptions; ++i) {
|
||||
cl |= channel_label_to_cubeb_channel(
|
||||
cubeb_channel cc = channel_label_to_cubeb_channel(
|
||||
layout->mChannelDescriptions[i].mChannelLabel);
|
||||
if (cc == CHANNEL_UNKNOWN) {
|
||||
return CUBEB_LAYOUT_UNDEFINED;
|
||||
}
|
||||
cl |= cc;
|
||||
}
|
||||
|
||||
return cl;
|
||||
}
|
||||
|
||||
static cubeb_channel_layout
|
||||
audiounit_get_preferred_channel_layout(AudioUnit output_unit)
|
||||
{
|
||||
OSStatus rv = noErr;
|
||||
UInt32 size = 0;
|
||||
rv = AudioUnitGetPropertyInfo(output_unit,
|
||||
kAudioDevicePropertyPreferredChannelLayout,
|
||||
kAudioUnitScope_Output,
|
||||
AU_OUT_BUS,
|
||||
&size,
|
||||
nullptr);
|
||||
if (rv != noErr) {
|
||||
LOG("AudioUnitGetPropertyInfo/kAudioDevicePropertyPreferredChannelLayout rv=%d", rv);
|
||||
return CUBEB_LAYOUT_UNDEFINED;
|
||||
}
|
||||
assert(size > 0);
|
||||
|
||||
auto layout = make_sized_audio_channel_layout(size);
|
||||
rv = AudioUnitGetProperty(output_unit,
|
||||
kAudioDevicePropertyPreferredChannelLayout,
|
||||
kAudioUnitScope_Output,
|
||||
AU_OUT_BUS,
|
||||
layout.get(),
|
||||
&size);
|
||||
if (rv != noErr) {
|
||||
LOG("AudioUnitGetProperty/kAudioDevicePropertyPreferredChannelLayout rv=%d", rv);
|
||||
return CUBEB_LAYOUT_UNDEFINED;
|
||||
}
|
||||
|
||||
return audiounit_convert_channel_layout(layout.get());
|
||||
}
|
||||
|
||||
static cubeb_channel_layout
|
||||
audiounit_get_current_channel_layout(AudioUnit output_unit)
|
||||
{
|
||||
|
@ -1252,7 +1288,8 @@ audiounit_get_current_channel_layout(AudioUnit output_unit)
|
|||
nullptr);
|
||||
if (rv != noErr) {
|
||||
LOG("AudioUnitGetPropertyInfo/kAudioUnitProperty_AudioChannelLayout rv=%d", rv);
|
||||
return CUBEB_LAYOUT_UNDEFINED;
|
||||
// This property isn't known before macOS 10.12, attempt another method.
|
||||
return audiounit_get_preferred_channel_layout(output_unit);
|
||||
}
|
||||
assert(size > 0);
|
||||
|
||||
|
|
|
@ -533,6 +533,18 @@ struct cubeb_mixer
|
|||
output_buffer += _context._out_ch_count - _context._in_ch_count;
|
||||
}
|
||||
} else {
|
||||
if (_context._in_ch_count == 1 && _context._out_ch_count >= 2) {
|
||||
// Special case for upmixing mono input to stereo and more. We will
|
||||
// duplicate the mono channel to the first two channels. On most system,
|
||||
// the first two channels are for left and right. It is commonly
|
||||
// expected that mono will on both left+right channels
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
output_buffer[0] = output_buffer[1] = *input_buffer;
|
||||
output_buffer += _context._out_ch_count ;
|
||||
input_buffer++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
PodCopy(output_buffer, input_buffer, _context._out_ch_count);
|
||||
output_buffer += _context._out_ch_count;
|
||||
|
|
|
@ -83,3 +83,8 @@ patch -p3 < prefer-pulse-rust.patch
|
|||
echo "Applying disable-device-switching.patch on top of $rev"
|
||||
patch -p3 < disable-device-switching.patch
|
||||
|
||||
echo "Applying Correctly-retrieve-the-output-layout-on-macOS-10.12.patch on top of $rev"
|
||||
patch -p1 < 0001-Correctly-retrieve-the-output-layout-on-macOS-10.12.patch
|
||||
|
||||
echo "Applying Always-upmix-mono-to-the-first-two-channels-if-enoug.patch on top of $rev"
|
||||
patch -p1 < 0002-Always-upmix-mono-to-the-first-two-channels-if-enoug.patch
|
||||
|
|
Загрузка…
Ссылка в новой задаче