aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-02-20 09:08:57 -0800
committerChris Robinson <[email protected]>2017-02-20 09:08:57 -0800
commit5a2ef2590f38c72883f9ee2e18cc9980634df7be (patch)
treeb26c987fd5bbaa0a4123e45db7232299a2a7e133
parentb23f81b686f4c72044d0d6f85b5049822f3c6a78 (diff)
Allow distance compensation for non-HQ rendering as well
It still requires a custom configuration to specify appropriate speaker distances.
-rw-r--r--Alc/panning.c81
-rw-r--r--alsoftrc.sample5
-rw-r--r--utils/alsoft-config/mainwindow.cpp9
-rw-r--r--utils/alsoft-config/mainwindow.h2
-rw-r--r--utils/alsoft-config/mainwindow.ui5
5 files changed, 49 insertions, 53 deletions
diff --git a/Alc/panning.c b/Alc/panning.c
index 00cf9e0b..52618a5e 100644
--- a/Alc/panning.c
+++ b/Alc/panning.c
@@ -610,6 +610,47 @@ static void InitPanning(ALCdevice *device)
}
}
+static void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const ALsizei speakermap[MAX_OUTPUT_CHANNELS])
+{
+ const char *devname = al_string_get_cstr(device->DeviceName);
+ ALfloat maxdist = 0.0f;
+ ALsizei i;
+
+ for(i = 0;i < conf->NumSpeakers;i++)
+ maxdist = maxf(maxdist, conf->Speakers[i].Distance);
+
+ if(GetConfigValueBool(devname, "decoder", "distance-comp", 1) && maxdist > 0.0f)
+ {
+ ALfloat srate = (ALfloat)device->Frequency;
+ for(i = 0;i < conf->NumSpeakers;i++)
+ {
+ ALsizei chan = speakermap[i];
+ ALfloat delay;
+
+ /* Distance compensation only delays in steps of the sample rate.
+ * This is a bit less accurate since the delay time falls to the
+ * nearest sample time, but it's far simpler as it doesn't have to
+ * deal with phase offsets. This means at 48khz, for instance, the
+ * distance delay will be in steps of about 7 millimeters.
+ */
+ delay = floorf((maxdist-conf->Speakers[i].Distance) / SPEEDOFSOUNDMETRESPERSEC *
+ srate + 0.5f);
+ if(delay >= (ALfloat)MAX_DELAY_LENGTH)
+ ERR("Delay for speaker \"%s\" exceeds buffer length (%f >= %u)\n",
+ al_string_get_cstr(conf->Speakers[i].Name), delay, MAX_DELAY_LENGTH);
+
+ device->ChannelDelay[chan].Length = (ALsizei)clampf(
+ delay, 0.0f, (ALfloat)(MAX_DELAY_LENGTH-1)
+ );
+ device->ChannelDelay[chan].Gain = conf->Speakers[i].Distance / maxdist;
+ TRACE("Channel %u \"%s\" distance compensation: %d samples, %f gain\n", chan,
+ al_string_get_cstr(conf->Speakers[i].Name), device->ChannelDelay[chan].Length,
+ device->ChannelDelay[chan].Gain
+ );
+ }
+ }
+}
+
static void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei speakermap[MAX_OUTPUT_CHANNELS])
{
ChannelMap chanmap[MAX_OUTPUT_CHANNELS];
@@ -688,16 +729,15 @@ static void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const A
device->FOAOut.Ambi.Coeffs[i][j] = device->Dry.Ambi.Coeffs[i][j] * xyz_scale;
}
device->FOAOut.CoeffCount = 4;
+
+ InitDistanceComp(device, conf, speakermap);
}
static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALsizei speakermap[MAX_OUTPUT_CHANNELS])
{
- const char *devname;
size_t count;
size_t i;
- devname = al_string_get_cstr(device->DeviceName);
-
if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
{
count = (conf->ChanMask > 0x1ff) ? 16 :
@@ -756,40 +796,7 @@ static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALsiz
device->FOAOut.CoeffCount = 0;
}
- ALfloat maxdist = 0.0f;
- for(i = 0;i < (size_t)conf->NumSpeakers;i++)
- maxdist = maxf(maxdist, conf->Speakers[i].Distance);
-
- if(GetConfigValueBool(devname, "decoder", "distance-comp", 1) && maxdist > 0.0f)
- {
- ALfloat srate = (ALfloat)device->Frequency;
- for(i = 0;i < (size_t)conf->NumSpeakers;i++)
- {
- ALsizei chan = speakermap[i];
- ALfloat delay;
-
- /* Distance compensation only delays in steps of the sample rate.
- * This is a bit less accurate since the delay time falls to the
- * nearest sample time, but it's far simpler as it doesn't have to
- * deal with phase offsets. This means at 48khz, for instance, the
- * distance delay will be in steps of about 7 millimeters.
- */
- delay = floorf((maxdist-conf->Speakers[i].Distance) / SPEEDOFSOUNDMETRESPERSEC *
- srate + 0.5f);
- if(delay >= (ALfloat)MAX_DELAY_LENGTH)
- ERR("Delay for speaker \"%s\" exceeds buffer length (%f >= %u)\n",
- al_string_get_cstr(conf->Speakers[i].Name), delay, MAX_DELAY_LENGTH);
-
- device->ChannelDelay[chan].Length = (ALsizei)clampf(
- delay, 0.0f, (ALfloat)(MAX_DELAY_LENGTH-1)
- );
- device->ChannelDelay[chan].Gain = conf->Speakers[i].Distance / maxdist;
- TRACE("Channel %u \"%s\" distance compensation: %d samples, %f gain\n", chan,
- al_string_get_cstr(conf->Speakers[i].Name), device->ChannelDelay[chan].Length,
- device->ChannelDelay[chan].Gain
- );
- }
- }
+ InitDistanceComp(device, conf, speakermap);
}
static void InitHrtfPanning(ALCdevice *device, bool hoa_mode)
diff --git a/alsoftrc.sample b/alsoftrc.sample
index 256a4d06..36d930bf 100644
--- a/alsoftrc.sample
+++ b/alsoftrc.sample
@@ -235,9 +235,8 @@ hq-mode = false
# Enables compensation for the speakers' relative distances to the listener.
# This applies the necessary delays and attenuation to make the speakers
# behave as though they are all equidistant, which is important for proper
-# playback of 3D sound rendering. Requires the high-quality ambisonic decoder,
-# as well as the proper distances to be specified in the decoder configuration
-# file.
+# playback of 3D sound rendering. Requires the proper distances to be
+# specified in the decoder configuration file.
distance-comp = true
## quad:
diff --git a/utils/alsoft-config/mainwindow.cpp b/utils/alsoft-config/mainwindow.cpp
index ab992843..e4dc10fc 100644
--- a/utils/alsoft-config/mainwindow.cpp
+++ b/utils/alsoft-config/mainwindow.cpp
@@ -329,7 +329,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->stereoPanningComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(enableApplyButton()));
connect(ui->ambiFormatComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(enableApplyButton()));
- connect(ui->decoderHQModeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(toggleHqState(int)));
+ connect(ui->decoderHQModeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(enableApplyButton()));
connect(ui->decoderDistCompCheckBox, SIGNAL(stateChanged(int)), this, SLOT(enableApplyButton()));
connect(ui->decoderQuadLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton()));
connect(ui->decoderQuadButton, SIGNAL(clicked()), this, SLOT(selectQuadDecoderFile()));
@@ -665,7 +665,6 @@ void MainWindow::loadConfig(const QString &fname)
ui->decoderHQModeCheckBox->setChecked(hqmode);
bool distcomp = settings.value("decoder/distance-comp", true).toBool();
ui->decoderDistCompCheckBox->setChecked(distcomp);
- ui->decoderDistCompCheckBox->setEnabled(hqmode);
ui->decoderQuadLineEdit->setText(settings.value("decoder/quad").toString());
ui->decoder51LineEdit->setText(settings.value("decoder/surround51").toString());
@@ -1110,12 +1109,6 @@ void MainWindow::updatePeriodCountSlider()
}
-void MainWindow::toggleHqState(int state)
-{
- ui->decoderDistCompCheckBox->setEnabled(state);
- enableApplyButton();
-}
-
void MainWindow::selectQuadDecoderFile()
{ selectDecoderFile(ui->decoderQuadLineEdit, "Select Quadrophonic Decoder");}
void MainWindow::select51DecoderFile()
diff --git a/utils/alsoft-config/mainwindow.h b/utils/alsoft-config/mainwindow.h
index 6d572df6..8b763845 100644
--- a/utils/alsoft-config/mainwindow.h
+++ b/utils/alsoft-config/mainwindow.h
@@ -35,8 +35,6 @@ private slots:
void updatePeriodCountEdit(int size);
void updatePeriodCountSlider();
- void toggleHqState(int state);
-
void selectQuadDecoderFile();
void select51DecoderFile();
void select61DecoderFile();
diff --git a/utils/alsoft-config/mainwindow.ui b/utils/alsoft-config/mainwindow.ui
index f14554e6..afb91996 100644
--- a/utils/alsoft-config/mainwindow.ui
+++ b/utils/alsoft-config/mainwindow.ui
@@ -601,9 +601,8 @@ appropriate speaker configuration you intend to use.</string>
<string>This applies the necessary delays and attenuation
to make the speakers behave as though they are
all equidistant, which is important for proper
-playback of 3D sound rendering. Requires the high
-quality ambisonic renderer, as well as the proper
-distances to be specified in the decoder
+playback of 3D sound rendering. Requires the
+proper distances to be specified in the decoder
configuration file.</string>
</property>
<property name="layoutDirection">