aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--core/devformat.cpp2
-rw-r--r--core/devformat.h1
-rw-r--r--docs/ambdec.txt6
-rw-r--r--presets/hex-quad.ambdec53
-rw-r--r--presets/presets.txt11
19 files changed, 201 insertions, 6 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:
diff --git a/core/devformat.cpp b/core/devformat.cpp
index cbe8eaf3..acdabc4f 100644
--- a/core/devformat.cpp
+++ b/core/devformat.cpp
@@ -28,6 +28,7 @@ uint ChannelsFromDevFmt(DevFmtChannels chans, uint ambiorder) noexcept
case DevFmtX51: return 6;
case DevFmtX61: return 7;
case DevFmtX71: return 8;
+ case DevFmtX714: return 12;
case DevFmtX3D71: return 8;
case DevFmtAmbi3D: return (ambiorder+1) * (ambiorder+1);
}
@@ -58,6 +59,7 @@ const char *DevFmtChannelsString(DevFmtChannels chans) noexcept
case DevFmtX51: return "5.1 Surround";
case DevFmtX61: return "6.1 Surround";
case DevFmtX71: return "7.1 Surround";
+ case DevFmtX714: return "7.1.4 Surround";
case DevFmtX3D71: return "3D7.1 Surround";
case DevFmtAmbi3D: return "Ambisonic 3D";
}
diff --git a/core/devformat.h b/core/devformat.h
index f2a372c1..485826a3 100644
--- a/core/devformat.h
+++ b/core/devformat.h
@@ -65,6 +65,7 @@ enum DevFmtChannels : unsigned char {
DevFmtX51,
DevFmtX61,
DevFmtX71,
+ DevFmtX714,
DevFmtX3D71,
DevFmtAmbi3D,
diff --git a/docs/ambdec.txt b/docs/ambdec.txt
index 5565ae06..a301004c 100644
--- a/docs/ambdec.txt
+++ b/docs/ambdec.txt
@@ -13,7 +13,7 @@ about ambisonics.
Starting with OpenAL Soft 1.18, version 3 of the file format is supported as a
means of specifying custom surround sound speaker layouts. These configuration
-files are also used to enable the high-quality ambisonic decoder.
+files are also used to enable per-speaker distance compensation.
File Format
@@ -155,6 +155,10 @@ LB = Back left
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, configuration files for surround51 will acknowledge back speakers
for side channels, to avoid issues with a configuration expecting 5.1 to use
diff --git a/presets/hex-quad.ambdec b/presets/hex-quad.ambdec
new file mode 100644
index 00000000..ce6cf8bf
--- /dev/null
+++ b/presets/hex-quad.ambdec
@@ -0,0 +1,53 @@
+# AmbDec configuration
+# Written by Ambisonic Decoder Toolbox, version 8.0
+
+# input channel order: W Y Z X
+
+/description 11_1_1h1v_allrad_5200_rE_max_1_band
+
+/version 3
+
+/dec/chan_mask f
+/dec/freq_bands 1
+/dec/speakers 11
+/dec/coeff_scale n3d
+
+/opt/input_scale n3d
+/opt/nfeff_comp output
+/opt/delay_comp on
+/opt/level_comp on
+/opt/xover_freq 400.000000
+/opt/xover_ratio 0.000000
+
+/speakers/{
+# id dist azim elev conn
+#-----------------------------------------------------------------------
+add_spkr LF 1.000000 30.000000 0.000000
+add_spkr RF 1.000000 -30.000000 0.000000
+add_spkr CE 1.000000 0.000000 0.000000
+add_spkr LS 1.000000 90.000000 0.000000
+add_spkr RS 1.000000 -90.000000 0.000000
+add_spkr LB 1.000000 150.000000 0.000000
+add_spkr RB 1.000000 -150.000000 0.000000
+add_spkr LFT 1.000000 45.000000 35.000000
+add_spkr RFT 1.000000 -45.000000 35.000000
+add_spkr LBT 1.000000 135.000000 35.000000
+add_spkr RBT 1.000000 -135.000000 35.000000
+/}
+
+/matrix/{
+order_gain 1.00000000e+00 1.00000000e+00 0.000000 0.000000
+add_row 1.27149251e-01 7.63047539e-02 -3.64373750e-02 1.59700680e-01
+add_row 1.07005418e-01 -7.67638760e-02 -4.92129762e-02 1.29012797e-01
+add_row 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
+add_row 1.26400196e-01 1.77494694e-01 -3.71203389e-02 0.00000000e+00
+add_row 1.26396516e-01 -1.77488059e-01 -3.71297878e-02 0.00000000e+00
+add_row 1.06996956e-01 7.67615256e-02 -4.92166307e-02 -1.29001640e-01
+add_row 1.27145671e-01 -7.63003471e-02 -3.64353304e-02 -1.59697510e-01
+add_row 8.80919747e-02 7.48940670e-02 9.08786244e-02 6.22527183e-02
+add_row 1.57880745e-01 -7.28755272e-02 1.82364187e-01 8.74240284e-02
+add_row 1.57892225e-01 7.28944768e-02 1.82363474e-01 -8.74301086e-02
+add_row 8.80892603e-02 -7.48948724e-02 9.08779842e-02 -6.22480443e-02
+/}
+
+/end
diff --git a/presets/presets.txt b/presets/presets.txt
index 445d75a4..f75a53e9 100644
--- a/presets/presets.txt
+++ b/presets/presets.txt
@@ -36,6 +36,17 @@ is defined for the decoder, meaning that speaker will be silent for 3D sound
output). A "proper" 7.1 decoder may be provided in the future, but due to the
nature of the speaker configuration will have trade-offs.
+hex-quad.ambdec
+Specifies a flat-front hexagonal speaker setup, plus an elevated quad speaker
+setup, for 7.1.4 Surround output. The front left and right speakers are placed
+at +30 and -30 degrees, the side speakers are placed at +90 and -90 degrees,
+and the back speakers are placed at +150 and -150 degrees. The elevated
+speakers are placed at an elevation of +35 degrees, with the top front left and
+right speakers placed at +45 and -45 degrees, and the top back left and right
+speakers placed at +135 and -135 degrees. Similar to 7.1, the front-center
+speaker is not used for 3D sound, but will be used as appropriate with
+AL_SOFT_direct_channels or ALC_EXT_DEDICATED.
+
3D7.1.ambdec
Specifies a 3D7.1 speaker setup for 3D7.1 Surround output. Please see
docs/3D7.1.txt for information about speaker placement. Similar to 7.1, the