aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-11-03 19:42:08 -0700
committerChris Robinson <[email protected]>2022-11-03 19:42:08 -0700
commite9ad8571ba93dd6631a9c05a05a28ede95728d9e (patch)
tree391684e8c815ccbd72db91c19c630bcb4549bf29 /alc
parent551a18a15c66440e3a5478c8b3d6b973f36c33d3 (diff)
Add preliminary support for 7.1.4 output modes
I don't know how different sound APIs handle 7.1.4 ("Atmos" or "Auro3D") output, but currently it simply specifies the additional channels with the height channel labels. This isn't likely how it works for a virtualized channel bed, for playing over other with-height configurations (7.1.2, 5.1.4, etc), but this should be an okay start.
Diffstat (limited to 'alc')
-rw-r--r--alc/alc.cpp3
-rw-r--r--alc/backends/base.cpp28
-rw-r--r--alc/backends/coreaudio.cpp1
-rw-r--r--alc/backends/dsound.cpp3
-rw-r--r--alc/backends/oboe.cpp1
-rw-r--r--alc/backends/opensl.cpp5
-rw-r--r--alc/backends/pipewire.cpp9
-rw-r--r--alc/backends/pulseaudio.cpp18
-rw-r--r--alc/backends/wasapi.cpp22
-rw-r--r--alc/backends/wave.cpp4
-rw-r--r--alc/backends/winmm.cpp1
-rw-r--r--alc/context.cpp4
-rw-r--r--alc/device.cpp4
-rw-r--r--alc/panning.cpp31
14 files changed, 129 insertions, 5 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp
index f6385e27..5f9bfa9b 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -1482,6 +1482,7 @@ ALCenum EnumFromDevFmt(DevFmtChannels channels)
case DevFmtX71: return ALC_7POINT1_SOFT;
case DevFmtAmbi3D: return ALC_BFORMAT3D_SOFT;
/* FIXME: Shouldn't happen. */
+ case DevFmtX714:
case DevFmtX3D71: break;
}
throw std::runtime_error{"Invalid DevFmtChannels: "+std::to_string(int(channels))};
@@ -1953,6 +1954,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
{ "surround51", DevFmtX51, 0 },
{ "surround61", DevFmtX61, 0 },
{ "surround71", DevFmtX71, 0 },
+ { "surround714", DevFmtX714, 0 },
{ "surround3d71", DevFmtX3D71, 0 },
{ "surround51rear", DevFmtX51, 0 },
{ "ambi1", DevFmtAmbi3D, 1 },
@@ -2133,6 +2135,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
case DevFmtX51: device->RealOut.RemixMap = X51Downmix; break;
case DevFmtX61: device->RealOut.RemixMap = X61Downmix; break;
case DevFmtX71: device->RealOut.RemixMap = X71Downmix; break;
+ case DevFmtX714: device->RealOut.RemixMap = X71Downmix; break;
case DevFmtX3D71: device->RealOut.RemixMap = X51Downmix; break;
case DevFmtAmbi3D: break;
}
diff --git a/alc/backends/base.cpp b/alc/backends/base.cpp
index 4abd7c03..6838c7e3 100644
--- a/alc/backends/base.cpp
+++ b/alc/backends/base.cpp
@@ -98,6 +98,20 @@ void BackendBase::setDefaultWFXChannelOrder()
mDevice->RealOut.ChannelIndex[SideLeft] = 6;
mDevice->RealOut.ChannelIndex[SideRight] = 7;
break;
+ case DevFmtX714:
+ mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
+ mDevice->RealOut.ChannelIndex[FrontRight] = 1;
+ mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
+ mDevice->RealOut.ChannelIndex[LFE] = 3;
+ mDevice->RealOut.ChannelIndex[BackLeft] = 4;
+ mDevice->RealOut.ChannelIndex[BackRight] = 5;
+ mDevice->RealOut.ChannelIndex[SideLeft] = 6;
+ mDevice->RealOut.ChannelIndex[SideRight] = 7;
+ mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
+ mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
+ mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
+ mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
+ break;
case DevFmtX3D71:
mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
mDevice->RealOut.ChannelIndex[FrontRight] = 1;
@@ -137,6 +151,20 @@ void BackendBase::setDefaultChannelOrder()
mDevice->RealOut.ChannelIndex[SideLeft] = 6;
mDevice->RealOut.ChannelIndex[SideRight] = 7;
return;
+ case DevFmtX714:
+ mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
+ mDevice->RealOut.ChannelIndex[FrontRight] = 1;
+ mDevice->RealOut.ChannelIndex[BackLeft] = 2;
+ mDevice->RealOut.ChannelIndex[BackRight] = 3;
+ mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
+ mDevice->RealOut.ChannelIndex[LFE] = 5;
+ mDevice->RealOut.ChannelIndex[SideLeft] = 6;
+ mDevice->RealOut.ChannelIndex[SideRight] = 7;
+ mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
+ mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
+ mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
+ mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
+ break;
case DevFmtX3D71:
mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
mDevice->RealOut.ChannelIndex[FrontRight] = 1;
diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp
index 8b45fefe..d6392271 100644
--- a/alc/backends/coreaudio.cpp
+++ b/alc/backends/coreaudio.cpp
@@ -748,6 +748,7 @@ void CoreAudioCapture::open(const char *name)
case DevFmtX51:
case DevFmtX61:
case DevFmtX71:
+ case DevFmtX714:
case DevFmtX3D71:
case DevFmtAmbi3D:
throw al::backend_exception{al::backend_error::DeviceError, "%s not supported",
diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp
index 3f2bf8df..f549c0fe 100644
--- a/alc/backends/dsound.cpp
+++ b/alc/backends/dsound.cpp
@@ -115,6 +115,7 @@ HRESULT (WINAPI *pDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW pDSEnumCallbac
#define X5DOT1REAR (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)
#define X6DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)
#define X7DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)
+#define X7DOT1DOT4 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT|SPEAKER_TOP_FRONT_LEFT|SPEAKER_TOP_FRONT_RIGHT|SPEAKER_TOP_BACK_LEFT|SPEAKER_TOP_BACK_RIGHT)
#define MAX_UPDATES 128
@@ -424,6 +425,7 @@ bool DSoundPlayback::reset()
case DevFmtX51: OutputType.dwChannelMask = isRear51 ? X5DOT1REAR : X5DOT1; break;
case DevFmtX61: OutputType.dwChannelMask = X6DOT1; break;
case DevFmtX71: OutputType.dwChannelMask = X7DOT1; break;
+ case DevFmtX714: OutputType.dwChannelMask = X7DOT1DOT4; break;
case DevFmtX3D71: OutputType.dwChannelMask = X7DOT1; break;
}
@@ -638,6 +640,7 @@ void DSoundCapture::open(const char *name)
case DevFmtX51: InputType.dwChannelMask = X5DOT1; break;
case DevFmtX61: InputType.dwChannelMask = X6DOT1; break;
case DevFmtX71: InputType.dwChannelMask = X7DOT1; break;
+ case DevFmtX714: InputType.dwChannelMask = X7DOT1DOT4; break;
case DevFmtX3D71:
case DevFmtAmbi3D:
WARN("%s capture not supported\n", DevFmtChannelsString(mDevice->FmtChans));
diff --git a/alc/backends/oboe.cpp b/alc/backends/oboe.cpp
index 7b1dc966..32e4d4dd 100644
--- a/alc/backends/oboe.cpp
+++ b/alc/backends/oboe.cpp
@@ -245,6 +245,7 @@ void OboeCapture::open(const char *name)
case DevFmtX51:
case DevFmtX61:
case DevFmtX71:
+ case DevFmtX714:
case DevFmtX3D71:
case DevFmtAmbi3D:
throw al::backend_exception{al::backend_error::DeviceError, "%s capture not supported",
diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp
index 49e5c268..9ecde509 100644
--- a/alc/backends/opensl.cpp
+++ b/alc/backends/opensl.cpp
@@ -75,6 +75,11 @@ constexpr SLuint32 GetChannelMask(DevFmtChannels chans) noexcept
case DevFmtX3D71: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT |
SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
+ case DevFmtX714: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
+ SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT |
+ SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT |
+ SL_SPEAKER_TOP_FRONT_LEFT | SL_SPEAKER_TOP_FRONT_RIGHT | SL_SPEAKER_TOP_BACK_LEFT |
+ SL_SPEAKER_TOP_BACK_RIGHT;
case DevFmtAmbi3D:
break;
}
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index acb4616f..0b36aba1 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -644,6 +644,10 @@ const spa_audio_channel MonoMap[]{
}, X71Map[]{
SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR
+}, X714Map[]{
+ SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
+ SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR,
+ SPA_AUDIO_CHANNEL_TFL, SPA_AUDIO_CHANNEL_TFR, SPA_AUDIO_CHANNEL_TRL, SPA_AUDIO_CHANNEL_TRR
};
/**
@@ -747,7 +751,9 @@ void DeviceNode::parsePositions(const spa_pod *value) noexcept
mIs51Rear = false;
- if(MatchChannelMap(chanmap, X71Map))
+ if(MatchChannelMap(chanmap, X714Map))
+ mChannels = DevFmtX714;
+ else if(MatchChannelMap(chanmap, X71Map))
mChannels = DevFmtX71;
else if(MatchChannelMap(chanmap, X61Map))
mChannels = DevFmtX61;
@@ -1232,6 +1238,7 @@ spa_audio_info_raw make_spa_info(DeviceBase *device, bool is51rear, use_f32p_e u
break;
case DevFmtX61: map = X61Map; break;
case DevFmtX71: map = X71Map; break;
+ case DevFmtX714: map = X714Map; break;
case DevFmtX3D71: map = X71Map; break;
case DevFmtAmbi3D:
info.flags |= SPA_AUDIO_FLAG_UNPOSITIONED;
diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp
index f3fe856e..3862ec2e 100644
--- a/alc/backends/pulseaudio.cpp
+++ b/alc/backends/pulseaudio.cpp
@@ -234,6 +234,15 @@ constexpr pa_channel_map MonoChanMap{
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT
}
+}, X714ChanMap{
+ 12, {
+ PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
+ PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
+ PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
+ PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT,
+ PA_CHANNEL_POSITION_TOP_FRONT_LEFT, PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,
+ PA_CHANNEL_POSITION_TOP_REAR_LEFT, PA_CHANNEL_POSITION_TOP_REAR_RIGHT
+ }
};
@@ -704,7 +713,8 @@ void PulsePlayback::sinkInfoCallback(pa_context*, const pa_sink_info *info, int
pa_channel_map map;
bool is_51rear;
};
- static constexpr std::array<ChannelMap,7> chanmaps{{
+ static constexpr std::array<ChannelMap,8> chanmaps{{
+ { DevFmtX714, X714ChanMap, false },
{ DevFmtX71, X71ChanMap, false },
{ DevFmtX61, X61ChanMap, false },
{ DevFmtX51, X51ChanMap, false },
@@ -895,6 +905,9 @@ bool PulsePlayback::reset()
case DevFmtX3D71:
chanmap = X71ChanMap;
break;
+ case DevFmtX714:
+ chanmap = X714ChanMap;
+ break;
}
setDefaultWFXChannelOrder();
@@ -1179,6 +1192,9 @@ void PulseCapture::open(const char *name)
case DevFmtX71:
chanmap = X71ChanMap;
break;
+ case DevFmtX714:
+ chanmap = X714ChanMap;
+ break;
case DevFmtX3D71:
case DevFmtAmbi3D:
throw al::backend_exception{al::backend_error::DeviceError, "%s capture not supported",
diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp
index 9007da1b..0a5294ac 100644
--- a/alc/backends/wasapi.cpp
+++ b/alc/backends/wasapi.cpp
@@ -102,6 +102,7 @@ inline constexpr ReferenceTime operator "" _reftime(unsigned long long int n) no
#define X5DOT1REAR (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)
#define X6DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)
#define X7DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)
+#define X7DOT1DOT4 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT|SPEAKER_TOP_FRONT_LEFT|SPEAKER_TOP_FRONT_RIGHT|SPEAKER_TOP_BACK_LEFT|SPEAKER_TOP_BACK_RIGHT)
constexpr inline DWORD MaskFromTopBits(DWORD b) noexcept
{
@@ -119,6 +120,7 @@ constexpr DWORD X51Mask{MaskFromTopBits(X5DOT1)};
constexpr DWORD X51RearMask{MaskFromTopBits(X5DOT1REAR)};
constexpr DWORD X61Mask{MaskFromTopBits(X6DOT1)};
constexpr DWORD X71Mask{MaskFromTopBits(X7DOT1)};
+constexpr DWORD X714Mask{MaskFromTopBits(X7DOT1DOT4)};
constexpr char DevNameHead[] = "OpenAL Soft on ";
constexpr size_t DevNameHeadLen{al::size(DevNameHead) - 1};
@@ -888,7 +890,9 @@ HRESULT WasapiPlayback::resetProxy()
*/
const uint32_t chancount{OutputType.Format.nChannels};
const DWORD chanmask{OutputType.dwChannelMask};
- if(chancount >= 8 && (chanmask&X71Mask) == X7DOT1)
+ if(chancount >= 12 && (chanmask&X714Mask) == X7DOT1DOT4)
+ mDevice->FmtChans = DevFmtX71;
+ else if(chancount >= 8 && (chanmask&X71Mask) == X7DOT1)
mDevice->FmtChans = DevFmtX71;
else if(chancount >= 7 && (chanmask&X61Mask) == X6DOT1)
mDevice->FmtChans = DevFmtX61;
@@ -946,6 +950,10 @@ HRESULT WasapiPlayback::resetProxy()
OutputType.Format.nChannels = 8;
OutputType.dwChannelMask = X7DOT1;
break;
+ case DevFmtX714:
+ OutputType.Format.nChannels = 12;
+ OutputType.dwChannelMask = X7DOT1DOT4;
+ break;
}
switch(mDevice->FmtType)
{
@@ -1045,13 +1053,17 @@ HRESULT WasapiPlayback::resetProxy()
case DevFmtX3D71:
chansok = (chancount >= 8 && ((chanmask&X71Mask) == X7DOT1 || !chanmask));
break;
+ case DevFmtX714:
+ chansok = (chancount >= 12 && ((chanmask&X714Mask) == X7DOT1DOT4 || !chanmask));
case DevFmtAmbi3D:
break;
}
}
if(!chansok)
{
- if(chancount >= 8 && (chanmask&X71Mask) == X7DOT1)
+ if(chancount >= 12 && (chanmask&X714Mask) == X7DOT1DOT4)
+ mDevice->FmtChans = DevFmtX714;
+ else if(chancount >= 8 && (chanmask&X71Mask) == X7DOT1)
mDevice->FmtChans = DevFmtX71;
else if(chancount >= 7 && (chanmask&X61Mask) == X6DOT1)
mDevice->FmtChans = DevFmtX61;
@@ -1518,6 +1530,10 @@ HRESULT WasapiCapture::resetProxy()
InputType.Format.nChannels = 8;
InputType.dwChannelMask = X7DOT1;
break;
+ case DevFmtX714:
+ InputType.Format.nChannels = 12;
+ InputType.dwChannelMask = X7DOT1DOT4;
+ break;
case DevFmtX3D71:
case DevFmtAmbi3D:
@@ -1606,6 +1622,8 @@ HRESULT WasapiCapture::resetProxy()
case DevFmtX71:
case DevFmtX3D71:
return (chancount == 8 && (chanmask == 0 || (chanmask&X71Mask) == X7DOT1));
+ case DevFmtX714:
+ return (chancount == 12 && (chanmask == 0 || (chanmask&X714Mask) == X7DOT1DOT4));
case DevFmtAmbi3D:
return (chanmask == 0 && chancount == device->channelsFromFmt());
}
diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp
index 80e93f69..f97f42f5 100644
--- a/alc/backends/wave.cpp
+++ b/alc/backends/wave.cpp
@@ -265,6 +265,10 @@ bool WaveBackend::reset()
case DevFmtX51: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x200 | 0x400; break;
case DevFmtX61: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x100 | 0x200 | 0x400; break;
case DevFmtX71: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x200 | 0x400; break;
+ case DevFmtX714:
+ chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x200 | 0x400 | 0x1000 | 0x4000
+ | 0x8000 | 0x20000;
+ break;
/* NOTE: Same as 7.1. */
case DevFmtX3D71: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x200 | 0x400; break;
case DevFmtAmbi3D:
diff --git a/alc/backends/winmm.cpp b/alc/backends/winmm.cpp
index 14cc4f9e..38e1193f 100644
--- a/alc/backends/winmm.cpp
+++ b/alc/backends/winmm.cpp
@@ -469,6 +469,7 @@ void WinMMCapture::open(const char *name)
case DevFmtX51:
case DevFmtX61:
case DevFmtX71:
+ case DevFmtX714:
case DevFmtX3D71:
case DevFmtAmbi3D:
throw al::backend_exception{al::backend_error::DeviceError, "%s capture not supported",
diff --git a/alc/context.cpp b/alc/context.cpp
index a892bb6d..07ae6434 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -535,6 +535,10 @@ unsigned long ALCcontext::eax_detect_speaker_configuration() const
case DevFmtX51: return SPEAKERS_5;
case DevFmtX61: return SPEAKERS_6;
case DevFmtX71: return SPEAKERS_7;
+ /* 7.1.4 is compatible with 7.1. This could instead be HEADPHONES to
+ * suggest with-height surround sound (like HRTF).
+ */
+ case DevFmtX714: return SPEAKERS_7;
/* 3D7.1 is only compatible with 5.1. This could instead be HEADPHONES to
* suggest full-sphere surround sound (like HRTF).
*/
diff --git a/alc/device.cpp b/alc/device.cpp
index 6eeb907e..66b13c5e 100644
--- a/alc/device.cpp
+++ b/alc/device.cpp
@@ -84,8 +84,10 @@ auto ALCdevice::getOutputMode1() const noexcept -> OutputMode1
case DevFmtX51: return OutputMode1::X51;
case DevFmtX61: return OutputMode1::X61;
case DevFmtX71: return OutputMode1::X71;
+ case DevFmtX714:
case DevFmtX3D71:
- case DevFmtAmbi3D: break;
+ case DevFmtAmbi3D:
+ break;
}
return OutputMode1::Any;
}
diff --git a/alc/panning.cpp b/alc/panning.cpp
index 45daa5cf..1210b318 100644
--- a/alc/panning.cpp
+++ b/alc/panning.cpp
@@ -376,6 +376,10 @@ DecoderView MakeDecoderView(ALCdevice *device, const AmbDecConf *conf,
* RB = Back right
* CE = Front center
* CB = Back center
+ * LFT = Top front left
+ * RFT = Top front right
+ * LBT = Top back left
+ * RBT = Top back right
*
* Additionally, surround51 will acknowledge back speakers for side
* channels, to avoid issues with an ambdec expecting 5.1 to use the
@@ -398,6 +402,14 @@ DecoderView MakeDecoderView(ALCdevice *device, const AmbDecConf *conf,
ch = (device->FmtChans == DevFmtX51) ? SideRight : BackRight;
else if(speaker.Name == "CB")
ch = BackCenter;
+ else if(speaker.Name == "LFT")
+ ch = TopFrontLeft;
+ else if(speaker.Name == "RFT")
+ ch = TopFrontRight;
+ else if(speaker.Name == "LBT")
+ ch = TopBackLeft;
+ else if(speaker.Name == "RBT")
+ ch = TopBackRight;
else
{
int idx{};
@@ -554,6 +566,23 @@ constexpr DecoderConfig<DualBand, 6> X3D71Config{
{{1.666666667e-01f, 0.000000000e+00f, -2.356640879e-01f, 1.667265410e-01f}},
}}
};
+constexpr DecoderConfig<SingleBand, 10> X714Config{
+ 1, true, {{FrontLeft, FrontRight, SideLeft, SideRight, BackLeft, BackRight, TopFrontLeft, TopFrontRight, TopBackLeft, TopBackRight }},
+ DevAmbiScaling::N3D,
+ {{1.00000000e+0f, 1.00000000e+0f, 1.00000000e+0f}},
+ {{
+ {{1.27149251e-01f, 7.63047539e-02f, -3.64373750e-02f, 1.59700680e-01f}},
+ {{1.07005418e-01f, -7.67638760e-02f, -4.92129762e-02f, 1.29012797e-01f}},
+ {{1.26400196e-01f, 1.77494694e-01f, -3.71203389e-02f, 0.00000000e+00f}},
+ {{1.26396516e-01f, -1.77488059e-01f, -3.71297878e-02f, 0.00000000e+00f}},
+ {{1.06996956e-01f, 7.67615256e-02f, -4.92166307e-02f, -1.29001640e-01f}},
+ {{1.27145671e-01f, -7.63003471e-02f, -3.64353304e-02f, -1.59697510e-01f}},
+ {{8.80919747e-02f, 7.48940670e-02f, 9.08786244e-02f, 6.22527183e-02f}},
+ {{1.57880745e-01f, -7.28755272e-02f, 1.82364187e-01f, 8.74240284e-02f}},
+ {{1.57892225e-01f, 7.28944768e-02f, 1.82363474e-01f, -8.74301086e-02f}},
+ {{8.80892603e-02f, -7.48948724e-02f, 9.08779842e-02f, -6.22480443e-02f}},
+ }}
+};
void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize=false,
DecoderView decoder={})
@@ -568,6 +597,7 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize=
case DevFmtX51: decoder = X51Config; break;
case DevFmtX61: decoder = X61Config; break;
case DevFmtX71: decoder = X71Config; break;
+ case DevFmtX714: decoder = X714Config; break;
case DevFmtX3D71: decoder = X3D71Config; break;
case DevFmtAmbi3D:
auto&& acnmap = GetAmbiLayout(device->mAmbiLayout);
@@ -929,6 +959,7 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, al::optional<StereoEncoding
case DevFmtX51: layout = "surround51"; break;
case DevFmtX61: layout = "surround61"; break;
case DevFmtX71: layout = "surround71"; break;
+ case DevFmtX714: layout = "surround714"; break;
case DevFmtX3D71: layout = "surround3d71"; break;
/* Mono, Stereo, and Ambisonics output don't use custom decoders. */
case DevFmtMono: