Allow distance compensation for non-HQ rendering as well
It still requires a custom configuration to specify appropriate speaker distances.
This commit is contained in:
parent
b23f81b686
commit
5a2ef2590f
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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()
|
||||
|
@ -35,8 +35,6 @@ private slots:
|
||||
void updatePeriodCountEdit(int size);
|
||||
void updatePeriodCountSlider();
|
||||
|
||||
void toggleHqState(int state);
|
||||
|
||||
void selectQuadDecoderFile();
|
||||
void select51DecoderFile();
|
||||
void select61DecoderFile();
|
||||
|
@ -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">
|
||||
|
Loading…
Reference in New Issue
Block a user