aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/alsoft-config/CMakeLists.txt2
-rw-r--r--utils/alsoft-config/mainwindow.cpp318
-rw-r--r--utils/alsoft-config/mainwindow.h29
-rw-r--r--utils/makemhr/loaddef.cpp574
-rw-r--r--utils/makemhr/loadsofa.cpp43
-rw-r--r--utils/makemhr/makemhr.cpp300
-rw-r--r--utils/makemhr/makemhr.h36
-rw-r--r--utils/openal-info.c25
-rw-r--r--utils/sofa-info.cpp3
-rw-r--r--utils/sofa-support.cpp8
-rw-r--r--utils/uhjdecoder.cpp36
-rw-r--r--utils/uhjencoder.cpp108
12 files changed, 745 insertions, 737 deletions
diff --git a/utils/alsoft-config/CMakeLists.txt b/utils/alsoft-config/CMakeLists.txt
index c6a46075..d9e6ca9a 100644
--- a/utils/alsoft-config/CMakeLists.txt
+++ b/utils/alsoft-config/CMakeLists.txt
@@ -12,7 +12,7 @@ if(Qt5Widgets_FOUND)
verstr.cpp
verstr.h
${UIS} ${RSCS} ${TRS} ${MOCS})
- target_link_libraries(alsoft-config Qt5::Widgets)
+ target_link_libraries(alsoft-config PUBLIC Qt5::Widgets PRIVATE alcommon)
target_include_directories(alsoft-config PRIVATE "${alsoft-config_BINARY_DIR}"
"${OpenAL_BINARY_DIR}")
set_target_properties(alsoft-config PROPERTIES ${DEFAULT_TARGET_PROPS}
diff --git a/utils/alsoft-config/mainwindow.cpp b/utils/alsoft-config/mainwindow.cpp
index bee7022f..9a65f79c 100644
--- a/utils/alsoft-config/mainwindow.cpp
+++ b/utils/alsoft-config/mainwindow.cpp
@@ -3,8 +3,9 @@
#include "mainwindow.h"
-#include <iostream>
+#include <array>
#include <cmath>
+#include <iostream>
#include <QFileDialog>
#include <QMessageBox>
@@ -19,137 +20,134 @@
#include <shlobj.h>
#endif
+#include "almalloc.h"
+#include "alspan.h"
+
namespace {
-const struct {
+struct BackendNamePair {
+ /* NOLINTBEGIN(*-avoid-c-arrays) */
char backend_name[16];
char full_string[32];
-} backendList[] = {
-#ifdef HAVE_JACK
- { "jack", "JACK" },
-#endif
+ /* NOLINTEND(*-avoid-c-arrays) */
+};
+constexpr std::array backendList{
#ifdef HAVE_PIPEWIRE
- { "pipewire", "PipeWire" },
+ BackendNamePair{ "pipewire", "PipeWire" },
#endif
#ifdef HAVE_PULSEAUDIO
- { "pulse", "PulseAudio" },
+ BackendNamePair{ "pulse", "PulseAudio" },
#endif
#ifdef HAVE_ALSA
- { "alsa", "ALSA" },
+ BackendNamePair{ "alsa", "ALSA" },
+#endif
+#ifdef HAVE_JACK
+ BackendNamePair{ "jack", "JACK" },
#endif
#ifdef HAVE_COREAUDIO
- { "core", "CoreAudio" },
+ BackendNamePair{ "core", "CoreAudio" },
#endif
#ifdef HAVE_OSS
- { "oss", "OSS" },
+ BackendNamePair{ "oss", "OSS" },
#endif
#ifdef HAVE_SOLARIS
- { "solaris", "Solaris" },
+ BackendNamePair{ "solaris", "Solaris" },
#endif
#ifdef HAVE_SNDIO
- { "sndio", "SoundIO" },
-#endif
-#ifdef HAVE_QSA
- { "qsa", "QSA" },
+ BackendNamePair{ "sndio", "SoundIO" },
#endif
#ifdef HAVE_WASAPI
- { "wasapi", "WASAPI" },
+ BackendNamePair{ "wasapi", "WASAPI" },
#endif
#ifdef HAVE_DSOUND
- { "dsound", "DirectSound" },
+ BackendNamePair{ "dsound", "DirectSound" },
#endif
#ifdef HAVE_WINMM
- { "winmm", "Windows Multimedia" },
+ BackendNamePair{ "winmm", "Windows Multimedia" },
#endif
#ifdef HAVE_PORTAUDIO
- { "port", "PortAudio" },
+ BackendNamePair{ "port", "PortAudio" },
#endif
#ifdef HAVE_OPENSL
- { "opensl", "OpenSL" },
+ BackendNamePair{ "opensl", "OpenSL" },
#endif
- { "null", "Null Output" },
+ BackendNamePair{ "null", "Null Output" },
#ifdef HAVE_WAVE
- { "wave", "Wave Writer" },
+ BackendNamePair{ "wave", "Wave Writer" },
#endif
- { "", "" }
};
-const struct NameValuePair {
+struct NameValuePair {
+ /* NOLINTBEGIN(*-avoid-c-arrays) */
const char name[64];
const char value[16];
-} speakerModeList[] = {
- { "Autodetect", "" },
- { "Mono", "mono" },
- { "Stereo", "stereo" },
- { "Quadraphonic", "quad" },
- { "5.1 Surround", "surround51" },
- { "6.1 Surround", "surround61" },
- { "7.1 Surround", "surround71" },
- { "3D7.1 Surround", "surround3d71" },
-
- { "Ambisonic, 1st Order", "ambi1" },
- { "Ambisonic, 2nd Order", "ambi2" },
- { "Ambisonic, 3rd Order", "ambi3" },
-
- { "", "" }
-}, sampleTypeList[] = {
- { "Autodetect", "" },
- { "8-bit int", "int8" },
- { "8-bit uint", "uint8" },
- { "16-bit int", "int16" },
- { "16-bit uint", "uint16" },
- { "32-bit int", "int32" },
- { "32-bit uint", "uint32" },
- { "32-bit float", "float32" },
-
- { "", "" }
-}, resamplerList[] = {
- { "Point", "point" },
- { "Linear", "linear" },
- { "Cubic Spline", "cubic" },
- { "Default (Cubic Spline)", "" },
- { "11th order Sinc (fast)", "fast_bsinc12" },
- { "11th order Sinc", "bsinc12" },
- { "23rd order Sinc (fast)", "fast_bsinc24" },
- { "23rd order Sinc", "bsinc24" },
-
- { "", "" }
-}, stereoModeList[] = {
- { "Autodetect", "" },
- { "Speakers", "speakers" },
- { "Headphones", "headphones" },
-
- { "", "" }
-}, stereoEncList[] = {
- { "Default", "" },
- { "Basic", "panpot" },
- { "UHJ", "uhj" },
- { "Binaural", "hrtf" },
-
- { "", "" }
-}, ambiFormatList[] = {
- { "Default", "" },
- { "AmbiX (ACN, SN3D)", "ambix" },
- { "Furse-Malham", "fuma" },
- { "ACN, N3D", "acn+n3d" },
- { "ACN, FuMa", "acn+fuma" },
-
- { "", "" }
-}, hrtfModeList[] = {
- { "1st Order Ambisonic", "ambi1" },
- { "2nd Order Ambisonic", "ambi2" },
- { "3rd Order Ambisonic", "ambi3" },
- { "Default (Full)", "" },
- { "Full", "full" },
-
- { "", "" }
+ /* NOLINTEND(*-avoid-c-arrays) */
+};
+constexpr std::array speakerModeList{
+ NameValuePair{ "Autodetect", "" },
+ NameValuePair{ "Mono", "mono" },
+ NameValuePair{ "Stereo", "stereo" },
+ NameValuePair{ "Quadraphonic", "quad" },
+ NameValuePair{ "5.1 Surround", "surround51" },
+ NameValuePair{ "6.1 Surround", "surround61" },
+ NameValuePair{ "7.1 Surround", "surround71" },
+ NameValuePair{ "3D7.1 Surround", "surround3d71" },
+
+ NameValuePair{ "Ambisonic, 1st Order", "ambi1" },
+ NameValuePair{ "Ambisonic, 2nd Order", "ambi2" },
+ NameValuePair{ "Ambisonic, 3rd Order", "ambi3" },
+};
+constexpr std::array sampleTypeList{
+ NameValuePair{ "Autodetect", "" },
+ NameValuePair{ "8-bit int", "int8" },
+ NameValuePair{ "8-bit uint", "uint8" },
+ NameValuePair{ "16-bit int", "int16" },
+ NameValuePair{ "16-bit uint", "uint16" },
+ NameValuePair{ "32-bit int", "int32" },
+ NameValuePair{ "32-bit uint", "uint32" },
+ NameValuePair{ "32-bit float", "float32" },
+};
+constexpr std::array resamplerList{
+ NameValuePair{ "Point", "point" },
+ NameValuePair{ "Linear", "linear" },
+ NameValuePair{ "Cubic Spline", "cubic" },
+ NameValuePair{ "Default (Cubic Spline)", "" },
+ NameValuePair{ "11th order Sinc (fast)", "fast_bsinc12" },
+ NameValuePair{ "11th order Sinc", "bsinc12" },
+ NameValuePair{ "23rd order Sinc (fast)", "fast_bsinc24" },
+ NameValuePair{ "23rd order Sinc", "bsinc24" },
+};
+constexpr std::array stereoModeList{
+ NameValuePair{ "Autodetect", "" },
+ NameValuePair{ "Speakers", "speakers" },
+ NameValuePair{ "Headphones", "headphones" },
+};
+constexpr std::array stereoEncList{
+ NameValuePair{ "Default", "" },
+ NameValuePair{ "Basic", "panpot" },
+ NameValuePair{ "UHJ", "uhj" },
+ NameValuePair{ "Binaural", "hrtf" },
+};
+constexpr std::array ambiFormatList{
+ NameValuePair{ "Default", "" },
+ NameValuePair{ "AmbiX (ACN, SN3D)", "ambix" },
+ NameValuePair{ "Furse-Malham", "fuma" },
+ NameValuePair{ "ACN, N3D", "acn+n3d" },
+ NameValuePair{ "ACN, FuMa", "acn+fuma" },
+};
+constexpr std::array hrtfModeList{
+ NameValuePair{ "1st Order Ambisonic", "ambi1" },
+ NameValuePair{ "2nd Order Ambisonic", "ambi2" },
+ NameValuePair{ "3rd Order Ambisonic", "ambi3" },
+ NameValuePair{ "Default (Full)", "" },
+ NameValuePair{ "Full", "full" },
};
QString getDefaultConfigName()
{
#ifdef Q_OS_WIN32
- static const char fname[] = "alsoft.ini";
+ static constexpr char fname[] = "alsoft.ini"; /* NOLINT(*-avoid-c-arrays) */
auto get_appdata_path = []() noexcept -> QString
{
WCHAR buffer[MAX_PATH];
@@ -159,7 +157,7 @@ QString getDefaultConfigName()
};
QString base = get_appdata_path();
#else
- static const char fname[] = "alsoft.conf";
+ static constexpr char fname[] = "alsoft.conf"; /* NOLINT(*-avoid-c-arrays) */
QByteArray base = qgetenv("XDG_CONFIG_HOME");
if(base.isEmpty())
{
@@ -226,10 +224,9 @@ QStringList getAllDataPaths(const QString &append)
return list;
}
-template<size_t N>
-QString getValueFromName(const NameValuePair (&list)[N], const QString &str)
+QString getValueFromName(const al::span<const NameValuePair> list, const QString &str)
{
- for(size_t i = 0;i < N-1;i++)
+ for(size_t i{0};i < list.size();++i)
{
if(str == list[i].name)
return list[i].value;
@@ -237,10 +234,9 @@ QString getValueFromName(const NameValuePair (&list)[N], const QString &str)
return QString{};
}
-template<size_t N>
-QString getNameFromValue(const NameValuePair (&list)[N], const QString &str)
+QString getNameFromValue(const al::span<const NameValuePair> list, const QString &str)
{
- for(size_t i = 0;i < N-1;i++)
+ for(size_t i{0};i < list.size();++i)
{
if(str == list[i].value)
return list[i].name;
@@ -270,44 +266,29 @@ QString getCheckValue(const QCheckBox *checkbox)
}
-MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow),
- mPeriodSizeValidator(nullptr),
- mPeriodCountValidator(nullptr),
- mSourceCountValidator(nullptr),
- mEffectSlotValidator(nullptr),
- mSourceSendValidator(nullptr),
- mSampleRateValidator(nullptr),
- mJackBufferValidator(nullptr),
- mNeedsSave(false)
+MainWindow::MainWindow(QWidget *parent) : QMainWindow{parent}
+ , ui{std::make_unique<Ui::MainWindow>()}
{
ui->setupUi(this);
- for(int i = 0;speakerModeList[i].name[0];i++)
- ui->channelConfigCombo->addItem(speakerModeList[i].name);
+ for(auto &item : speakerModeList)
+ ui->channelConfigCombo->addItem(item.name);
ui->channelConfigCombo->adjustSize();
- for(int i = 0;sampleTypeList[i].name[0];i++)
- ui->sampleFormatCombo->addItem(sampleTypeList[i].name);
+ for(auto &item : sampleTypeList)
+ ui->sampleFormatCombo->addItem(item.name);
ui->sampleFormatCombo->adjustSize();
- for(int i = 0;stereoModeList[i].name[0];i++)
- ui->stereoModeCombo->addItem(stereoModeList[i].name);
+ for(auto &item : stereoModeList)
+ ui->stereoModeCombo->addItem(item.name);
ui->stereoModeCombo->adjustSize();
- for(int i = 0;stereoEncList[i].name[0];i++)
- ui->stereoEncodingComboBox->addItem(stereoEncList[i].name);
+ for(auto &item : stereoEncList)
+ ui->stereoEncodingComboBox->addItem(item.name);
ui->stereoEncodingComboBox->adjustSize();
- for(int i = 0;ambiFormatList[i].name[0];i++)
- ui->ambiFormatComboBox->addItem(ambiFormatList[i].name);
+ for(auto &item : ambiFormatList)
+ ui->ambiFormatComboBox->addItem(item.name);
ui->ambiFormatComboBox->adjustSize();
- int count;
- for(count = 0;resamplerList[count].name[0];count++) {
- }
- ui->resamplerSlider->setRange(0, count-1);
-
- for(count = 0;hrtfModeList[count].name[0];count++) {
- }
- ui->hrtfmodeSlider->setRange(0, count-1);
+ ui->resamplerSlider->setRange(0, resamplerList.size()-1);
+ ui->hrtfmodeSlider->setRange(0, hrtfModeList.size()-1);
#if !defined(HAVE_NEON) && !defined(HAVE_SSE)
ui->cpuExtDisabledLabel->move(ui->cpuExtDisabledLabel->x(), ui->cpuExtDisabledLabel->y() - 60);
@@ -355,22 +336,22 @@ MainWindow::MainWindow(QWidget *parent) :
ui->enableEaxCheck->setVisible(false);
#endif
- mPeriodSizeValidator = new QIntValidator{64, 8192, this};
- ui->periodSizeEdit->setValidator(mPeriodSizeValidator);
- mPeriodCountValidator = new QIntValidator{2, 16, this};
- ui->periodCountEdit->setValidator(mPeriodCountValidator);
+ mPeriodSizeValidator = std::make_unique<QIntValidator>(64, 8192, this);
+ ui->periodSizeEdit->setValidator(mPeriodSizeValidator.get());
+ mPeriodCountValidator = std::make_unique<QIntValidator>(2, 16, this);
+ ui->periodCountEdit->setValidator(mPeriodCountValidator.get());
- mSourceCountValidator = new QIntValidator{0, 4096, this};
- ui->srcCountLineEdit->setValidator(mSourceCountValidator);
- mEffectSlotValidator = new QIntValidator{0, 64, this};
- ui->effectSlotLineEdit->setValidator(mEffectSlotValidator);
- mSourceSendValidator = new QIntValidator{0, 16, this};
- ui->srcSendLineEdit->setValidator(mSourceSendValidator);
- mSampleRateValidator = new QIntValidator{8000, 192000, this};
- ui->sampleRateCombo->lineEdit()->setValidator(mSampleRateValidator);
+ mSourceCountValidator = std::make_unique<QIntValidator>(0, 4096, this);
+ ui->srcCountLineEdit->setValidator(mSourceCountValidator.get());
+ mEffectSlotValidator = std::make_unique<QIntValidator>(0, 64, this);
+ ui->effectSlotLineEdit->setValidator(mEffectSlotValidator.get());
+ mSourceSendValidator = std::make_unique<QIntValidator>(0, 16, this);
+ ui->srcSendLineEdit->setValidator(mSourceSendValidator.get());
+ mSampleRateValidator = std::make_unique<QIntValidator>(8000, 192000, this);
+ ui->sampleRateCombo->lineEdit()->setValidator(mSampleRateValidator.get());
- mJackBufferValidator = new QIntValidator{0, 8192, this};
- ui->jackBufferSizeLine->setValidator(mJackBufferValidator);
+ mJackBufferValidator = std::make_unique<QIntValidator>(0, 8192, this);
+ ui->jackBufferSizeLine->setValidator(mJackBufferValidator.get());
connect(ui->actionLoad, &QAction::triggered, this, &MainWindow::loadConfigFromFile);
connect(ui->actionSave_As, &QAction::triggered, this, &MainWindow::saveConfigAsFile);
@@ -495,7 +476,7 @@ MainWindow::MainWindow(QWidget *parent) :
for(int i = 1;i < ui->backendListWidget->count();i++)
ui->backendListWidget->setRowHidden(i, true);
- for(int i = 0;backendList[i].backend_name[0];i++)
+ for(size_t i{0};i < backendList.size();++i)
{
QList<QListWidgetItem*> items = ui->backendListWidget->findItems(
backendList[i].full_string, Qt::MatchFixedString);
@@ -506,17 +487,7 @@ MainWindow::MainWindow(QWidget *parent) :
loadConfig(getDefaultConfigName());
}
-MainWindow::~MainWindow()
-{
- delete ui;
- delete mPeriodSizeValidator;
- delete mPeriodCountValidator;
- delete mSourceCountValidator;
- delete mEffectSlotValidator;
- delete mSourceSendValidator;
- delete mSampleRateValidator;
- delete mJackBufferValidator;
-}
+MainWindow::~MainWindow() = default;
void MainWindow::closeEvent(QCloseEvent *event)
{
@@ -583,7 +554,7 @@ QStringList MainWindow::collectHrtfs()
break;
}
++i;
- } while(1);
+ } while(true);
}
}
}
@@ -618,7 +589,7 @@ QStringList MainWindow::collectHrtfs()
break;
}
++i;
- } while(1);
+ } while(true);
}
}
}
@@ -789,11 +760,11 @@ void MainWindow::loadConfig(const QString &fname)
/* The "basic" mode name is no longer supported. Use "ambi2" instead. */
if(hrtfmode == "basic")
hrtfmode = "ambi2";
- for(int i = 0;hrtfModeList[i].name[0];i++)
+ for(size_t i{0};i < hrtfModeList.size();++i)
{
if(hrtfmode == hrtfModeList[i].value)
{
- ui->hrtfmodeSlider->setValue(i);
+ ui->hrtfmodeSlider->setValue(static_cast<int>(i));
ui->hrtfmodeLabel->setText(hrtfModeList[i].name);
break;
}
@@ -869,7 +840,8 @@ void MainWindow::loadConfig(const QString &fname)
if(lastWasEmpty) continue;
if(!backend.startsWith(QChar('-')))
- for(int j = 0;backendList[j].backend_name[0];j++)
+ {
+ for(size_t j{0};j < backendList.size();++j)
{
if(backend == backendList[j].backend_name)
{
@@ -877,10 +849,11 @@ void MainWindow::loadConfig(const QString &fname)
break;
}
}
+ }
else if(backend.size() > 1)
{
QStringRef backendref{backend.rightRef(backend.size()-1)};
- for(int j = 0;backendList[j].backend_name[0];j++)
+ for(size_t j{0};j < backendList.size();++j)
{
if(backendref == backendList[j].backend_name)
{
@@ -1070,7 +1043,7 @@ void MainWindow::saveConfig(const QString &fname) const
for(int i = 0;i < ui->enabledBackendList->count();i++)
{
QString label{ui->enabledBackendList->item(i)->text()};
- for(int j = 0;backendList[j].backend_name[0];j++)
+ for(size_t j{0};j < backendList.size();++j)
{
if(label == backendList[j].full_string)
{
@@ -1082,7 +1055,7 @@ void MainWindow::saveConfig(const QString &fname) const
for(int i = 0;i < ui->disabledBackendList->count();i++)
{
QString label{ui->disabledBackendList->item(i)->text()};
- for(int j = 0;backendList[j].backend_name[0];j++)
+ for(size_t j{0};j < backendList.size();++j)
{
if(label == backendList[j].full_string)
{
@@ -1294,7 +1267,7 @@ void MainWindow::updateJackBufferSizeSlider()
void MainWindow::updateHrtfModeLabel(int num)
{
- ui->hrtfmodeLabel->setText(hrtfModeList[num].name);
+ ui->hrtfmodeLabel->setText(hrtfModeList[static_cast<uint>(num)].name);
enableApplyButton();
}
@@ -1311,11 +1284,10 @@ void MainWindow::addHrtfFile()
void MainWindow::removeHrtfFile()
{
- QList<QListWidgetItem*> selected{ui->hrtfFileList->selectedItems()};
+ QList<gsl::owner<QListWidgetItem*>> selected{ui->hrtfFileList->selectedItems()};
if(!selected.isEmpty())
{
- foreach(QListWidgetItem *item, selected)
- delete item;
+ std::for_each(selected.begin(), selected.end(), std::default_delete<QListWidgetItem>{});
enableApplyButton();
}
}
@@ -1336,7 +1308,7 @@ void MainWindow::showEnabledBackendMenu(QPoint pt)
if(ui->enabledBackendList->selectedItems().empty())
removeAction->setEnabled(false);
ctxmenu.addSeparator();
- for(size_t i = 0;backendList[i].backend_name[0];i++)
+ for(size_t i{0};i < backendList.size();++i)
{
QString backend{backendList[i].full_string};
QAction *action{ctxmenu.addAction(QString("Add ")+backend)};
@@ -1349,9 +1321,8 @@ void MainWindow::showEnabledBackendMenu(QPoint pt)
QAction *gotAction{ctxmenu.exec(pt)};
if(gotAction == removeAction)
{
- QList<QListWidgetItem*> selected{ui->enabledBackendList->selectedItems()};
- foreach(QListWidgetItem *item, selected)
- delete item;
+ QList<gsl::owner<QListWidgetItem*>> selected{ui->enabledBackendList->selectedItems()};
+ std::for_each(selected.begin(), selected.end(), std::default_delete<QListWidgetItem>{});
enableApplyButton();
}
else if(gotAction != nullptr)
@@ -1374,7 +1345,7 @@ void MainWindow::showDisabledBackendMenu(QPoint pt)
if(ui->disabledBackendList->selectedItems().empty())
removeAction->setEnabled(false);
ctxmenu.addSeparator();
- for(size_t i = 0;backendList[i].backend_name[0];i++)
+ for(size_t i{0};i < backendList.size();++i)
{
QString backend{backendList[i].full_string};
QAction *action{ctxmenu.addAction(QString("Add ")+backend)};
@@ -1387,9 +1358,8 @@ void MainWindow::showDisabledBackendMenu(QPoint pt)
QAction *gotAction{ctxmenu.exec(pt)};
if(gotAction == removeAction)
{
- QList<QListWidgetItem*> selected{ui->disabledBackendList->selectedItems()};
- foreach(QListWidgetItem *item, selected)
- delete item;
+ QList<gsl::owner<QListWidgetItem*>> selected{ui->disabledBackendList->selectedItems()};
+ std::for_each(selected.begin(), selected.end(), std::default_delete<QListWidgetItem>{});
enableApplyButton();
}
else if(gotAction != nullptr)
diff --git a/utils/alsoft-config/mainwindow.h b/utils/alsoft-config/mainwindow.h
index f7af8eac..96151ca2 100644
--- a/utils/alsoft-config/mainwindow.h
+++ b/utils/alsoft-config/mainwindow.h
@@ -1,6 +1,8 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
+#include <memory>
+
#include <QMainWindow>
#include <QListWidget>
@@ -8,13 +10,12 @@ namespace Ui {
class MainWindow;
}
-class MainWindow : public QMainWindow
-{
+class MainWindow : public QMainWindow {
Q_OBJECT
public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
+ explicit MainWindow(QWidget *parent=nullptr);
+ ~MainWindow() override;
private slots:
void cancelCloseAction();
@@ -61,19 +62,19 @@ private slots:
void selectWaveOutput();
private:
- Ui::MainWindow *ui;
+ std::unique_ptr<QValidator> mPeriodSizeValidator;
+ std::unique_ptr<QValidator> mPeriodCountValidator;
+ std::unique_ptr<QValidator> mSourceCountValidator;
+ std::unique_ptr<QValidator> mEffectSlotValidator;
+ std::unique_ptr<QValidator> mSourceSendValidator;
+ std::unique_ptr<QValidator> mSampleRateValidator;
+ std::unique_ptr<QValidator> mJackBufferValidator;
- QValidator *mPeriodSizeValidator;
- QValidator *mPeriodCountValidator;
- QValidator *mSourceCountValidator;
- QValidator *mEffectSlotValidator;
- QValidator *mSourceSendValidator;
- QValidator *mSampleRateValidator;
- QValidator *mJackBufferValidator;
+ std::unique_ptr<Ui::MainWindow> ui;
- bool mNeedsSave;
+ bool mNeedsSave{};
- void closeEvent(QCloseEvent *event);
+ void closeEvent(QCloseEvent *event) override;
void selectDecoderFile(QLineEdit *line, const char *name);
diff --git a/utils/makemhr/loaddef.cpp b/utils/makemhr/loaddef.cpp
index c8a98511..f01e93fc 100644
--- a/utils/makemhr/loaddef.cpp
+++ b/utils/makemhr/loaddef.cpp
@@ -34,9 +34,13 @@
#include <limits>
#include <memory>
#include <optional>
+#include <string>
+#include <string_view>
#include <vector>
+#include "albit.h"
#include "alfstream.h"
+#include "alnumeric.h"
#include "alspan.h"
#include "alstring.h"
#include "makemhr.h"
@@ -45,12 +49,12 @@
#include "mysofa.h"
// Constants for accessing the token reader's ring buffer.
-#define TR_RING_BITS (16)
-#define TR_RING_SIZE (1 << TR_RING_BITS)
-#define TR_RING_MASK (TR_RING_SIZE - 1)
+constexpr uint TRRingBits{16};
+constexpr uint TRRingSize{1 << TRRingBits};
+constexpr uint TRRingMask{TRRingSize - 1};
// The token reader's load interval in bytes.
-#define TR_LOAD_SIZE (TR_RING_SIZE >> 2)
+constexpr uint TRLoadSize{TRRingSize >> 2};
// Token reader state for parsing the data set definition.
struct TokenReaderT {
@@ -58,7 +62,7 @@ struct TokenReaderT {
const char *mName{};
uint mLine{};
uint mColumn{};
- char mRing[TR_RING_SIZE]{};
+ std::array<char,TRRingSize> mRing{};
std::streamsize mIn{};
std::streamsize mOut{};
@@ -69,44 +73,48 @@ struct TokenReaderT {
// The maximum identifier length used when processing the data set
// definition.
-#define MAX_IDENT_LEN (16)
+constexpr uint MaxIdentLen{16};
// The limits for the listener's head 'radius' in the data set definition.
-#define MIN_RADIUS (0.05)
-#define MAX_RADIUS (0.15)
+constexpr double MinRadius{0.05};
+constexpr double MaxRadius{0.15};
// The maximum number of channels that can be addressed for a WAVE file
// source listed in the data set definition.
-#define MAX_WAVE_CHANNELS (65535)
+constexpr uint MaxWaveChannels{65535};
// The limits to the byte size for a binary source listed in the definition
// file.
-#define MIN_BIN_SIZE (2)
-#define MAX_BIN_SIZE (4)
-
-// The minimum number of significant bits for binary sources listed in the
-// data set definition. The maximum is calculated from the byte size.
-#define MIN_BIN_BITS (16)
+enum : uint {
+ MinBinSize = 2,
+ MaxBinSize = 4
+};
// The limits to the number of significant bits for an ASCII source listed in
// the data set definition.
-#define MIN_ASCII_BITS (16)
-#define MAX_ASCII_BITS (32)
+enum : uint {
+ MinASCIIBits = 16,
+ MaxASCIIBits = 32
+};
// The four-character-codes for RIFF/RIFX WAVE file chunks.
-#define FOURCC_RIFF (0x46464952) // 'RIFF'
-#define FOURCC_RIFX (0x58464952) // 'RIFX'
-#define FOURCC_WAVE (0x45564157) // 'WAVE'
-#define FOURCC_FMT (0x20746D66) // 'fmt '
-#define FOURCC_DATA (0x61746164) // 'data'
-#define FOURCC_LIST (0x5453494C) // 'LIST'
-#define FOURCC_WAVL (0x6C766177) // 'wavl'
-#define FOURCC_SLNT (0x746E6C73) // 'slnt'
+enum : uint {
+ FOURCC_RIFF = 0x46464952, // 'RIFF'
+ FOURCC_RIFX = 0x58464952, // 'RIFX'
+ FOURCC_WAVE = 0x45564157, // 'WAVE'
+ FOURCC_FMT = 0x20746D66, // 'fmt '
+ FOURCC_DATA = 0x61746164, // 'data'
+ FOURCC_LIST = 0x5453494C, // 'LIST'
+ FOURCC_WAVL = 0x6C766177, // 'wavl'
+ FOURCC_SLNT = 0x746E6C73, // 'slnt'
+};
// The supported wave formats.
-#define WAVE_FORMAT_PCM (0x0001)
-#define WAVE_FORMAT_IEEE_FLOAT (0x0003)
-#define WAVE_FORMAT_EXTENSIBLE (0xFFFE)
+enum : uint {
+ WAVE_FORMAT_PCM = 0x0001,
+ WAVE_FORMAT_IEEE_FLOAT = 0x0003,
+ WAVE_FORMAT_EXTENSIBLE = 0xFFFE,
+};
enum ByteOrderT {
@@ -144,7 +152,7 @@ struct SourceRefT {
double mRadius;
uint mSkip;
uint mOffset;
- char mPath[MAX_PATH_LEN+1];
+ std::array<char,MAX_PATH_LEN+1> mPath;
};
@@ -196,13 +204,14 @@ static int TrLoad(TokenReaderT *tr)
{
std::istream &istream = tr->mIStream;
- std::streamsize toLoad{TR_RING_SIZE - static_cast<std::streamsize>(tr->mIn - tr->mOut)};
- if(toLoad >= TR_LOAD_SIZE && istream.good())
+ std::streamsize toLoad{TRRingSize - static_cast<std::streamsize>(tr->mIn - tr->mOut)};
+ if(toLoad >= TRLoadSize && istream.good())
{
- // Load TR_LOAD_SIZE (or less if at the end of the file) per read.
- toLoad = TR_LOAD_SIZE;
- std::streamsize in{tr->mIn&TR_RING_MASK};
- std::streamsize count{TR_RING_SIZE - in};
+ // Load TRLoadSize (or less if at the end of the file) per read.
+ toLoad = TRLoadSize;
+
+ const auto in = static_cast<uint>(tr->mIn&TRRingMask);
+ std::streamsize count{TRRingSize - in};
if(count < toLoad)
{
istream.read(&tr->mRing[in], count);
@@ -216,10 +225,10 @@ static int TrLoad(TokenReaderT *tr)
tr->mIn += istream.gcount();
}
- if(tr->mOut >= TR_RING_SIZE)
+ if(tr->mOut >= TRRingSize)
{
- tr->mOut -= TR_RING_SIZE;
- tr->mIn -= TR_RING_SIZE;
+ tr->mOut -= TRRingSize;
+ tr->mIn -= TRRingSize;
}
}
if(tr->mIn > tr->mOut)
@@ -263,7 +272,7 @@ static void TrSkipLine(TokenReaderT *tr)
while(TrLoad(tr))
{
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
tr->mOut++;
if(ch == '\n')
{
@@ -280,7 +289,7 @@ static int TrSkipWhitespace(TokenReaderT *tr)
{
while(TrLoad(tr))
{
- char ch{tr->mRing[tr->mOut&TR_RING_MASK]};
+ char ch{tr->mRing[tr->mOut&TRRingMask]};
if(isspace(ch))
{
tr->mOut++;
@@ -314,7 +323,7 @@ static int TrIsIdent(TokenReaderT *tr)
{
if(!TrSkipWhitespace(tr))
return 0;
- char ch{tr->mRing[tr->mOut&TR_RING_MASK]};
+ char ch{tr->mRing[tr->mOut&TRRingMask]};
return ch == '_' || isalpha(ch);
}
@@ -333,7 +342,7 @@ static int TrIsOperator(TokenReaderT *tr, const char *op)
len = 0;
while(op[len] != '\0' && out < tr->mIn)
{
- ch = tr->mRing[out&TR_RING_MASK];
+ ch = tr->mRing[out&TRRingMask];
if(ch != op[len]) break;
len++;
out++;
@@ -358,7 +367,7 @@ static int TrReadIdent(TokenReaderT *tr, const uint maxLen, char *ident)
if(TrSkipWhitespace(tr))
{
col = tr->mColumn;
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
if(ch == '_' || isalpha(ch))
{
len = 0;
@@ -369,7 +378,7 @@ static int TrReadIdent(TokenReaderT *tr, const uint maxLen, char *ident)
tr->mOut++;
if(!TrLoad(tr))
break;
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
} while(ch == '_' || isdigit(ch) || isalpha(ch));
tr->mColumn += len;
@@ -389,25 +398,23 @@ static int TrReadIdent(TokenReaderT *tr, const uint maxLen, char *ident)
// Reads and validates (including bounds) an integer token.
static int TrReadInt(TokenReaderT *tr, const int loBound, const int hiBound, int *value)
{
- uint col, digis, len;
- char ch, temp[64+1];
-
- col = tr->mColumn;
+ uint col{tr->mColumn};
if(TrSkipWhitespace(tr))
{
col = tr->mColumn;
- len = 0;
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ uint len{0};
+ std::array<char,64+1> temp{};
+ char ch{tr->mRing[tr->mOut&TRRingMask]};
if(ch == '+' || ch == '-')
{
temp[len] = ch;
len++;
tr->mOut++;
}
- digis = 0;
+ uint digis{0};
while(TrLoad(tr))
{
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
if(!isdigit(ch)) break;
if(len < 64)
temp[len] = ch;
@@ -424,7 +431,7 @@ static int TrReadInt(TokenReaderT *tr, const int loBound, const int hiBound, int
return 0;
}
temp[len] = '\0';
- *value = static_cast<int>(strtol(temp, nullptr, 10));
+ *value = static_cast<int>(strtol(temp.data(), nullptr, 10));
if(*value < loBound || *value > hiBound)
{
TrErrorAt(tr, tr->mLine, col, "Expected a value from %d to %d.\n", loBound, hiBound);
@@ -440,15 +447,13 @@ static int TrReadInt(TokenReaderT *tr, const int loBound, const int hiBound, int
// Reads and validates (including bounds) a float token.
static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBound, double *value)
{
- uint col, digis, len;
- char ch, temp[64+1];
-
- col = tr->mColumn;
+ uint col{tr->mColumn};
if(TrSkipWhitespace(tr))
{
col = tr->mColumn;
- len = 0;
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ std::array<char,64+1> temp{};
+ uint len{0};
+ char ch{tr->mRing[tr->mOut&TRRingMask]};
if(ch == '+' || ch == '-')
{
temp[len] = ch;
@@ -456,10 +461,10 @@ static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBo
tr->mOut++;
}
- digis = 0;
+ uint digis{0};
while(TrLoad(tr))
{
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
if(!isdigit(ch)) break;
if(len < 64)
temp[len] = ch;
@@ -476,7 +481,7 @@ static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBo
}
while(TrLoad(tr))
{
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
if(!isdigit(ch)) break;
if(len < 64)
temp[len] = ch;
@@ -502,7 +507,7 @@ static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBo
}
while(TrLoad(tr))
{
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
if(!isdigit(ch)) break;
if(len < 64)
temp[len] = ch;
@@ -520,7 +525,7 @@ static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBo
return 0;
}
temp[len] = '\0';
- *value = strtod(temp, nullptr);
+ *value = strtod(temp.data(), nullptr);
if(*value < loBound || *value > hiBound)
{
TrErrorAt(tr, tr->mLine, col, "Expected a value from %f to %f.\n", loBound, hiBound);
@@ -546,14 +551,14 @@ static int TrReadString(TokenReaderT *tr, const uint maxLen, char *text)
if(TrSkipWhitespace(tr))
{
col = tr->mColumn;
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
if(ch == '\"')
{
tr->mOut++;
len = 0;
while(TrLoad(tr))
{
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
tr->mOut++;
if(ch == '\"')
break;
@@ -599,7 +604,7 @@ static int TrReadOperator(TokenReaderT *tr, const char *op)
len = 0;
while(op[len] != '\0' && TrLoad(tr))
{
- ch = tr->mRing[tr->mOut&TR_RING_MASK];
+ ch = tr->mRing[tr->mOut&TRRingMask];
if(ch != op[len]) break;
len++;
tr->mOut++;
@@ -621,8 +626,8 @@ static int TrReadOperator(TokenReaderT *tr, const char *op)
// storing it as a 32-bit unsigned integer.
static int ReadBin4(std::istream &istream, const char *filename, const ByteOrderT order, const uint bytes, uint32_t *out)
{
- uint8_t in[4];
- istream.read(reinterpret_cast<char*>(in), static_cast<int>(bytes));
+ std::array<uint8_t,4> in{};
+ istream.read(reinterpret_cast<char*>(in.data()), static_cast<int>(bytes));
if(istream.gcount() != bytes)
{
fprintf(stderr, "\nError: Bad read from file '%s'.\n", filename);
@@ -650,29 +655,27 @@ static int ReadBin4(std::istream &istream, const char *filename, const ByteOrder
// a 64-bit unsigned integer.
static int ReadBin8(std::istream &istream, const char *filename, const ByteOrderT order, uint64_t *out)
{
- uint8_t in[8];
- uint64_t accum;
- uint i;
-
- istream.read(reinterpret_cast<char*>(in), 8);
+ std::array<uint8_t,8> in{};
+ istream.read(reinterpret_cast<char*>(in.data()), 8);
if(istream.gcount() != 8)
{
fprintf(stderr, "\nError: Bad read from file '%s'.\n", filename);
return 0;
}
- accum = 0;
+
+ uint64_t accum{};
switch(order)
{
- case BO_LITTLE:
- for(i = 0;i < 8;i++)
- accum = (accum<<8) | in[8 - i - 1];
- break;
- case BO_BIG:
- for(i = 0;i < 8;i++)
- accum = (accum<<8) | in[i];
- break;
- default:
- break;
+ case BO_LITTLE:
+ for(uint i{0};i < 8;++i)
+ accum = (accum<<8) | in[8 - i - 1];
+ break;
+ case BO_BIG:
+ for(uint i{0};i < 8;++i)
+ accum = (accum<<8) | in[i];
+ break;
+ default:
+ break;
}
*out = accum;
return 1;
@@ -687,40 +690,32 @@ static int ReadBin8(std::istream &istream, const char *filename, const ByteOrder
static int ReadBinAsDouble(std::istream &istream, const char *filename, const ByteOrderT order,
const ElementTypeT type, const uint bytes, const int bits, double *out)
{
- union {
- uint32_t ui;
- int32_t i;
- float f;
- } v4;
- union {
- uint64_t ui;
- double f;
- } v8;
-
*out = 0.0;
if(bytes > 4)
{
- if(!ReadBin8(istream, filename, order, &v8.ui))
+ uint64_t val{};
+ if(!ReadBin8(istream, filename, order, &val))
return 0;
if(type == ET_FP)
- *out = v8.f;
+ *out = al::bit_cast<double>(val);
}
else
{
- if(!ReadBin4(istream, filename, order, bytes, &v4.ui))
+ uint32_t val{};
+ if(!ReadBin4(istream, filename, order, bytes, &val))
return 0;
if(type == ET_FP)
- *out = v4.f;
+ *out = al::bit_cast<float>(val);
else
{
if(bits > 0)
- v4.ui >>= (8*bytes) - (static_cast<uint>(bits));
+ val >>= (8*bytes) - (static_cast<uint>(bits));
else
- v4.ui &= (0xFFFFFFFF >> (32+bits));
+ val &= (0xFFFFFFFF >> (32+bits));
- if(v4.ui&static_cast<uint>(1<<(std::abs(bits)-1)))
- v4.ui |= (0xFFFFFFFF << std::abs(bits));
- *out = v4.i / static_cast<double>(1<<(std::abs(bits)-1));
+ if(val&static_cast<uint>(1<<(std::abs(bits)-1)))
+ val |= (0xFFFFFFFF << std::abs(bits));
+ *out = static_cast<int32_t>(val) / static_cast<double>(1<<(std::abs(bits)-1));
}
}
return 1;
@@ -776,20 +771,20 @@ static int ReadWaveFormat(std::istream &istream, const ByteOrderT order, const u
do {
if(chunkSize > 0)
istream.seekg(static_cast<int>(chunkSize), std::ios::cur);
- if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC)
- || !ReadBin4(istream, src->mPath, order, 4, &chunkSize))
+ if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC)
+ || !ReadBin4(istream, src->mPath.data(), order, 4, &chunkSize))
return 0;
} while(fourCC != FOURCC_FMT);
- if(!ReadBin4(istream, src->mPath, order, 2, &format)
- || !ReadBin4(istream, src->mPath, order, 2, &channels)
- || !ReadBin4(istream, src->mPath, order, 4, &rate)
- || !ReadBin4(istream, src->mPath, order, 4, &dummy)
- || !ReadBin4(istream, src->mPath, order, 2, &block))
+ if(!ReadBin4(istream, src->mPath.data(), order, 2, &format)
+ || !ReadBin4(istream, src->mPath.data(), order, 2, &channels)
+ || !ReadBin4(istream, src->mPath.data(), order, 4, &rate)
+ || !ReadBin4(istream, src->mPath.data(), order, 4, &dummy)
+ || !ReadBin4(istream, src->mPath.data(), order, 2, &block))
return 0;
block /= channels;
if(chunkSize > 14)
{
- if(!ReadBin4(istream, src->mPath, order, 2, &size))
+ if(!ReadBin4(istream, src->mPath.data(), order, 2, &size))
return 0;
size /= 8;
if(block > size)
@@ -800,12 +795,12 @@ static int ReadWaveFormat(std::istream &istream, const ByteOrderT order, const u
if(format == WAVE_FORMAT_EXTENSIBLE)
{
istream.seekg(2, std::ios::cur);
- if(!ReadBin4(istream, src->mPath, order, 2, &bits))
+ if(!ReadBin4(istream, src->mPath.data(), order, 2, &bits))
return 0;
if(bits == 0)
bits = 8 * size;
istream.seekg(4, std::ios::cur);
- if(!ReadBin4(istream, src->mPath, order, 2, &format))
+ if(!ReadBin4(istream, src->mPath.data(), order, 2, &format))
return 0;
istream.seekg(static_cast<int>(chunkSize - 26), std::ios::cur);
}
@@ -819,29 +814,32 @@ static int ReadWaveFormat(std::istream &istream, const ByteOrderT order, const u
}
if(format != WAVE_FORMAT_PCM && format != WAVE_FORMAT_IEEE_FLOAT)
{
- fprintf(stderr, "\nError: Unsupported WAVE format in file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Unsupported WAVE format in file '%s'.\n", src->mPath.data());
return 0;
}
if(src->mChannel >= channels)
{
- fprintf(stderr, "\nError: Missing source channel in WAVE file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Missing source channel in WAVE file '%s'.\n", src->mPath.data());
return 0;
}
if(rate != hrirRate)
{
- fprintf(stderr, "\nError: Mismatched source sample rate in WAVE file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Mismatched source sample rate in WAVE file '%s'.\n",
+ src->mPath.data());
return 0;
}
if(format == WAVE_FORMAT_PCM)
{
if(size < 2 || size > 4)
{
- fprintf(stderr, "\nError: Unsupported sample size in WAVE file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Unsupported sample size in WAVE file '%s'.\n",
+ src->mPath.data());
return 0;
}
if(bits < 16 || bits > (8*size))
{
- fprintf(stderr, "\nError: Bad significant bits in WAVE file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Bad significant bits in WAVE file '%s'.\n",
+ src->mPath.data());
return 0;
}
src->mType = ET_INT;
@@ -850,7 +848,8 @@ static int ReadWaveFormat(std::istream &istream, const ByteOrderT order, const u
{
if(size != 4 && size != 8)
{
- fprintf(stderr, "\nError: Unsupported sample size in WAVE file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Unsupported sample size in WAVE file '%s'.\n",
+ src->mPath.data());
return 0;
}
src->mType = ET_FP;
@@ -876,7 +875,8 @@ static int ReadWaveData(std::istream &istream, const SourceRefT *src, const Byte
skip += pre;
if(skip > 0)
istream.seekg(skip, std::ios::cur);
- if(!ReadBinAsDouble(istream, src->mPath, order, src->mType, src->mSize, src->mBits, &hrir[i]))
+ if(!ReadBinAsDouble(istream, src->mPath.data(), order, src->mType, src->mSize, src->mBits,
+ &hrir[i]))
return 0;
skip = post;
}
@@ -896,8 +896,8 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
for(;;)
{
- if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC)
- || !ReadBin4(istream, src->mPath, order, 4, &chunkSize))
+ if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC)
+ || !ReadBin4(istream, src->mPath.data(), order, 4, &chunkSize))
return 0;
if(fourCC == FOURCC_DATA)
@@ -906,17 +906,18 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
count = chunkSize / block;
if(count < (src->mOffset + n))
{
- fprintf(stderr, "\nError: Bad read from file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Bad read from file '%s'.\n", src->mPath.data());
return 0;
}
- istream.seekg(static_cast<long>(src->mOffset * block), std::ios::cur);
+ using off_type = std::istream::off_type;
+ istream.seekg(off_type(src->mOffset) * off_type(block), std::ios::cur);
if(!ReadWaveData(istream, src, order, n, &hrir[0]))
return 0;
return 1;
}
else if(fourCC == FOURCC_LIST)
{
- if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC))
+ if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC))
return 0;
chunkSize -= 4;
if(fourCC == FOURCC_WAVL)
@@ -932,8 +933,8 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
lastSample = 0.0;
while(offset < n && listSize > 8)
{
- if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC)
- || !ReadBin4(istream, src->mPath, order, 4, &chunkSize))
+ if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC)
+ || !ReadBin4(istream, src->mPath.data(), order, 4, &chunkSize))
return 0;
listSize -= 8 + chunkSize;
if(fourCC == FOURCC_DATA)
@@ -941,7 +942,8 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
count = chunkSize / block;
if(count > skip)
{
- istream.seekg(static_cast<long>(skip * block), std::ios::cur);
+ using off_type = std::istream::off_type;
+ istream.seekg(off_type(skip) * off_type(block), std::ios::cur);
chunkSize -= skip * block;
count -= skip;
skip = 0;
@@ -961,7 +963,7 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
}
else if(fourCC == FOURCC_SLNT)
{
- if(!ReadBin4(istream, src->mPath, order, 4, &count))
+ if(!ReadBin4(istream, src->mPath.data(), order, 4, &count))
return 0;
chunkSize -= 4;
if(count > skip)
@@ -985,7 +987,7 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
}
if(offset < n)
{
- fprintf(stderr, "\nError: Bad read from file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Bad read from file '%s'.\n", src->mPath.data());
return 0;
}
return 1;
@@ -997,22 +999,25 @@ static int LoadAsciiSource(std::istream &istream, const SourceRefT *src,
const uint n, double *hrir)
{
TokenReaderT tr{istream};
- uint i, j;
- double dummy;
TrSetup(nullptr, 0, nullptr, &tr);
- for(i = 0;i < src->mOffset;i++)
+ for(uint i{0};i < src->mOffset;++i)
{
- if(!ReadAsciiAsDouble(&tr, src->mPath, src->mType, static_cast<uint>(src->mBits), &dummy))
+ double dummy{};
+ if(!ReadAsciiAsDouble(&tr, src->mPath.data(), src->mType, static_cast<uint>(src->mBits),
+ &dummy))
return 0;
}
- for(i = 0;i < n;i++)
+ for(uint i{0};i < n;++i)
{
- if(!ReadAsciiAsDouble(&tr, src->mPath, src->mType, static_cast<uint>(src->mBits), &hrir[i]))
+ if(!ReadAsciiAsDouble(&tr, src->mPath.data(), src->mType, static_cast<uint>(src->mBits),
+ &hrir[i]))
return 0;
- for(j = 0;j < src->mSkip;j++)
+ for(uint j{0};j < src->mSkip;++j)
{
- if(!ReadAsciiAsDouble(&tr, src->mPath, src->mType, static_cast<uint>(src->mBits), &dummy))
+ double dummy{};
+ if(!ReadAsciiAsDouble(&tr, src->mPath.data(), src->mType,
+ static_cast<uint>(src->mBits), &dummy))
return 0;
}
}
@@ -1026,7 +1031,8 @@ static int LoadBinarySource(std::istream &istream, const SourceRefT *src, const
istream.seekg(static_cast<long>(src->mOffset), std::ios::beg);
for(uint i{0};i < n;i++)
{
- if(!ReadBinAsDouble(istream, src->mPath, order, src->mType, src->mSize, src->mBits, &hrir[i]))
+ if(!ReadBinAsDouble(istream, src->mPath.data(), order, src->mType, src->mSize, src->mBits,
+ &hrir[i]))
return 0;
if(src->mSkip > 0)
istream.seekg(static_cast<long>(src->mSkip), std::ios::cur);
@@ -1041,8 +1047,8 @@ static int LoadWaveSource(std::istream &istream, SourceRefT *src, const uint hri
uint32_t fourCC, dummy;
ByteOrderT order;
- if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC)
- || !ReadBin4(istream, src->mPath, BO_LITTLE, 4, &dummy))
+ if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC)
+ || !ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &dummy))
return 0;
if(fourCC == FOURCC_RIFF)
order = BO_LITTLE;
@@ -1050,15 +1056,15 @@ static int LoadWaveSource(std::istream &istream, SourceRefT *src, const uint hri
order = BO_BIG;
else
{
- fprintf(stderr, "\nError: No RIFF/RIFX chunk in file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: No RIFF/RIFX chunk in file '%s'.\n", src->mPath.data());
return 0;
}
- if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC))
+ if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC))
return 0;
if(fourCC != FOURCC_WAVE)
{
- fprintf(stderr, "\nError: Not a RIFF/RIFX WAVE file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Not a RIFF/RIFX WAVE file '%s'.\n", src->mPath.data());
return 0;
}
if(!ReadWaveFormat(istream, order, hrirRate, src))
@@ -1069,15 +1075,39 @@ static int LoadWaveSource(std::istream &istream, SourceRefT *src, const uint hri
}
+namespace {
+
+struct SofaEasyDeleter {
+ void operator()(gsl::owner<MYSOFA_EASY*> sofa)
+ {
+ if(sofa->neighborhood) mysofa_neighborhood_free(sofa->neighborhood);
+ if(sofa->lookup) mysofa_lookup_free(sofa->lookup);
+ if(sofa->hrtf) mysofa_free(sofa->hrtf);
+ delete sofa;
+ }
+};
+using SofaEasyPtr = std::unique_ptr<MYSOFA_EASY,SofaEasyDeleter>;
+
+struct SofaCacheEntry {
+ std::string mName;
+ uint mSampleRate{};
+ SofaEasyPtr mSofa;
+};
+std::vector<SofaCacheEntry> gSofaCache;
+
+} // namespace
// Load a Spatially Oriented Format for Accoustics (SOFA) file.
static MYSOFA_EASY* LoadSofaFile(SourceRefT *src, const uint hrirRate, const uint n)
{
- struct MYSOFA_EASY *sofa{mysofa_cache_lookup(src->mPath, static_cast<float>(hrirRate))};
- if(sofa) return sofa;
-
- sofa = static_cast<MYSOFA_EASY*>(calloc(1, sizeof(*sofa)));
- if(sofa == nullptr)
+ const std::string_view srcname{src->mPath.data()};
+ auto iter = std::find_if(gSofaCache.begin(), gSofaCache.end(),
+ [srcname,hrirRate](SofaCacheEntry &entry) -> bool
+ { return entry.mName == srcname && entry.mSampleRate == hrirRate; });
+ if(iter != gSofaCache.end()) return iter->mSofa.get();
+
+ SofaEasyPtr sofa{new(std::nothrow) MYSOFA_EASY{}};
+ if(!sofa)
{
fprintf(stderr, "\nError: Out of memory.\n");
return nullptr;
@@ -1086,38 +1116,37 @@ static MYSOFA_EASY* LoadSofaFile(SourceRefT *src, const uint hrirRate, const uin
sofa->neighborhood = nullptr;
int err;
- sofa->hrtf = mysofa_load(src->mPath, &err);
+ sofa->hrtf = mysofa_load(src->mPath.data(), &err);
if(!sofa->hrtf)
{
- mysofa_close(sofa);
- fprintf(stderr, "\nError: Could not load source file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Could not load source file '%s' (error: %d).\n",
+ src->mPath.data(), err);
return nullptr;
}
/* NOTE: Some valid SOFA files are failing this check. */
err = mysofa_check(sofa->hrtf);
if(err != MYSOFA_OK)
- fprintf(stderr, "\nWarning: Supposedly malformed source file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nWarning: Supposedly malformed source file '%s' (error: %d).\n",
+ src->mPath.data(), err);
if((src->mOffset + n) > sofa->hrtf->N)
{
- mysofa_close(sofa);
- fprintf(stderr, "\nError: Not enough samples in SOFA file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Not enough samples in SOFA file '%s'.\n", src->mPath.data());
return nullptr;
}
if(src->mChannel >= sofa->hrtf->R)
{
- mysofa_close(sofa);
- fprintf(stderr, "\nError: Missing source receiver in SOFA file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Missing source receiver in SOFA file '%s'.\n",src->mPath.data());
return nullptr;
}
mysofa_tocartesian(sofa->hrtf);
sofa->lookup = mysofa_lookup_init(sofa->hrtf);
if(sofa->lookup == nullptr)
{
- mysofa_close(sofa);
fprintf(stderr, "\nError: Out of memory.\n");
return nullptr;
}
- return mysofa_cache_store(sofa, src->mPath, static_cast<float>(hrirRate));
+ gSofaCache.emplace_back(SofaCacheEntry{std::string{srcname}, hrirRate, std::move(sofa)});
+ return gSofaCache.back().mSofa.get();
}
// Copies the HRIR data from a particular SOFA measurement.
@@ -1131,40 +1160,39 @@ static void ExtractSofaHrir(const MYSOFA_EASY *sofa, const uint index, const uin
// file.
static int LoadSofaSource(SourceRefT *src, const uint hrirRate, const uint n, double *hrir)
{
- struct MYSOFA_EASY *sofa;
- float target[3];
- int nearest;
- float *coords;
+ MYSOFA_EASY *sofa{LoadSofaFile(src, hrirRate, n)};
+ if(sofa == nullptr) return 0;
- sofa = LoadSofaFile(src, hrirRate, n);
- if(sofa == nullptr)
- return 0;
-
- /* NOTE: At some point it may be benficial or necessary to consider the
+ /* NOTE: At some point it may be beneficial or necessary to consider the
various coordinate systems, listener/source orientations, and
- direciontal vectors defined in the SOFA file.
+ directional vectors defined in the SOFA file.
*/
- target[0] = static_cast<float>(src->mAzimuth);
- target[1] = static_cast<float>(src->mElevation);
- target[2] = static_cast<float>(src->mRadius);
- mysofa_s2c(target);
-
- nearest = mysofa_lookup(sofa->lookup, target);
+ std::array target{
+ static_cast<float>(src->mAzimuth),
+ static_cast<float>(src->mElevation),
+ static_cast<float>(src->mRadius)
+ };
+ mysofa_s2c(target.data());
+
+ int nearest{mysofa_lookup(sofa->lookup, target.data())};
if(nearest < 0)
{
- fprintf(stderr, "\nError: Lookup failed in source file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Lookup failed in source file '%s'.\n", src->mPath.data());
return 0;
}
- coords = &sofa->hrtf->SourcePosition.values[3 * nearest];
- if(std::abs(coords[0] - target[0]) > 0.001 || std::abs(coords[1] - target[1]) > 0.001 || std::abs(coords[2] - target[2]) > 0.001)
+ al::span<float,3> coords{&sofa->hrtf->SourcePosition.values[3_z * nearest], 3};
+ if(std::abs(coords[0] - target[0]) > 0.001 || std::abs(coords[1] - target[1]) > 0.001
+ || std::abs(coords[2] - target[2]) > 0.001)
{
- fprintf(stderr, "\nError: No impulse response at coordinates (%.3fr, %.1fev, %.1faz) in file '%s'.\n", src->mRadius, src->mElevation, src->mAzimuth, src->mPath);
+ fprintf(stderr, "\nError: No impulse response at coordinates (%.3fr, %.1fev, %.1faz) in file '%s'.\n",
+ src->mRadius, src->mElevation, src->mAzimuth, src->mPath.data());
target[0] = coords[0];
target[1] = coords[1];
target[2] = coords[2];
- mysofa_c2s(target);
- fprintf(stderr, " Nearest candidate at (%.3fr, %.1fev, %.1faz).\n", target[2], target[1], target[0]);
+ mysofa_c2s(target.data());
+ fprintf(stderr, " Nearest candidate at (%.3fr, %.1fev, %.1faz).\n", target[2],
+ target[1], target[0]);
return 0;
}
@@ -1180,12 +1208,12 @@ static int LoadSource(SourceRefT *src, const uint hrirRate, const uint n, double
if(src->mFormat != SF_SOFA)
{
if(src->mFormat == SF_ASCII)
- istream.reset(new al::ifstream{src->mPath});
+ istream = std::make_unique<al::ifstream>(src->mPath.data());
else
- istream.reset(new al::ifstream{src->mPath, std::ios::binary});
+ istream = std::make_unique<al::ifstream>(src->mPath.data(), std::ios::binary);
if(!istream->good())
{
- fprintf(stderr, "\nError: Could not open source file '%s'.\n", src->mPath);
+ fprintf(stderr, "\nError: Could not open source file '%s'.\n", src->mPath.data());
return 0;
}
}
@@ -1230,14 +1258,14 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
{
int hasRate = 0, hasType = 0, hasPoints = 0, hasRadius = 0;
int hasDistance = 0, hasAzimuths = 0;
- char ident[MAX_IDENT_LEN+1];
+ std::array<char,MaxIdentLen+1> ident;
uint line, col;
double fpVal;
uint points;
int intVal;
- double distances[MAX_FD_COUNT];
+ std::array<double,MAX_FD_COUNT> distances;
uint fdCount = 0;
- uint evCounts[MAX_FD_COUNT];
+ std::array<uint,MAX_FD_COUNT> evCounts;
auto azCounts = std::vector<std::array<uint,MAX_EV_COUNT>>(MAX_FD_COUNT);
for(auto &azs : azCounts) azs.fill(0u);
@@ -1245,9 +1273,9 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
while(TrIsIdent(tr))
{
TrIndication(tr, &line, &col);
- if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+ if(!TrReadIdent(tr, MaxIdentLen, ident.data()))
return 0;
- if(al::strcasecmp(ident, "rate") == 0)
+ if(al::strcasecmp(ident.data(), "rate") == 0)
{
if(hasRate)
{
@@ -1261,9 +1289,9 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
hData->mIrRate = static_cast<uint>(intVal);
hasRate = 1;
}
- else if(al::strcasecmp(ident, "type") == 0)
+ else if(al::strcasecmp(ident.data(), "type") == 0)
{
- char type[MAX_IDENT_LEN+1];
+ std::array<char,MaxIdentLen+1> type;
if(hasType)
{
@@ -1273,9 +1301,9 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
if(!TrReadOperator(tr, "="))
return 0;
- if(!TrReadIdent(tr, MAX_IDENT_LEN, type))
+ if(!TrReadIdent(tr, MaxIdentLen, type.data()))
return 0;
- hData->mChannelType = MatchChannelType(type);
+ hData->mChannelType = MatchChannelType(type.data());
if(hData->mChannelType == CT_NONE)
{
TrErrorAt(tr, line, col, "Expected a channel type.\n");
@@ -1288,7 +1316,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
}
hasType = 1;
}
- else if(al::strcasecmp(ident, "points") == 0)
+ else if(al::strcasecmp(ident.data(), "points") == 0)
{
if(hasPoints)
{
@@ -1318,7 +1346,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
hData->mIrSize = points;
hasPoints = 1;
}
- else if(al::strcasecmp(ident, "radius") == 0)
+ else if(al::strcasecmp(ident.data(), "radius") == 0)
{
if(hasRadius)
{
@@ -1327,12 +1355,12 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
}
if(!TrReadOperator(tr, "="))
return 0;
- if(!TrReadFloat(tr, MIN_RADIUS, MAX_RADIUS, &fpVal))
+ if(!TrReadFloat(tr, MinRadius, MaxRadius, &fpVal))
return 0;
hData->mRadius = fpVal;
hasRadius = 1;
}
- else if(al::strcasecmp(ident, "distance") == 0)
+ else if(al::strcasecmp(ident.data(), "distance") == 0)
{
uint count = 0;
@@ -1371,7 +1399,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
fdCount = count;
hasDistance = 1;
}
- else if(al::strcasecmp(ident, "azimuths") == 0)
+ else if(al::strcasecmp(ident.data(), "azimuths") == 0)
{
uint count = 0;
@@ -1451,7 +1479,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
if(hData->mChannelType == CT_NONE)
hData->mChannelType = CT_MONO;
const auto azs = al::span{azCounts}.first<MAX_FD_COUNT>();
- if(!PrepareHrirData({distances, fdCount}, evCounts, azs, hData))
+ if(!PrepareHrirData(al::span{distances}.first(fdCount), evCounts, azs, hData))
{
fprintf(stderr, "Error: Out of memory.\n");
exit(-1);
@@ -1516,15 +1544,15 @@ static ElementTypeT MatchElementType(const char *ident)
// Parse and validate a source reference from the data set definition.
static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
{
- char ident[MAX_IDENT_LEN+1];
+ std::array<char,MaxIdentLen+1> ident;
uint line, col;
double fpVal;
int intVal;
TrIndication(tr, &line, &col);
- if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+ if(!TrReadIdent(tr, MaxIdentLen, ident.data()))
return 0;
- src->mFormat = MatchSourceFormat(ident);
+ src->mFormat = MatchSourceFormat(ident.data());
if(src->mFormat == SF_NONE)
{
TrErrorAt(tr, line, col, "Expected a source format.\n");
@@ -1549,7 +1577,7 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
src->mAzimuth = fpVal;
if(!TrReadOperator(tr, ":"))
return 0;
- if(!TrReadInt(tr, 0, MAX_WAVE_CHANNELS, &intVal))
+ if(!TrReadInt(tr, 0, MaxWaveChannels, &intVal))
return 0;
src->mType = ET_NONE;
src->mSize = 0;
@@ -1559,7 +1587,7 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
}
else if(src->mFormat == SF_WAVE)
{
- if(!TrReadInt(tr, 0, MAX_WAVE_CHANNELS, &intVal))
+ if(!TrReadInt(tr, 0, MaxWaveChannels, &intVal))
return 0;
src->mType = ET_NONE;
src->mSize = 0;
@@ -1570,9 +1598,9 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
else
{
TrIndication(tr, &line, &col);
- if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+ if(!TrReadIdent(tr, MaxIdentLen, ident.data()))
return 0;
- src->mType = MatchElementType(ident);
+ src->mType = MatchElementType(ident.data());
if(src->mType == ET_NONE)
{
TrErrorAt(tr, line, col, "Expected a source element type.\n");
@@ -1584,7 +1612,7 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
return 0;
if(src->mType == ET_INT)
{
- if(!TrReadInt(tr, MIN_BIN_SIZE, MAX_BIN_SIZE, &intVal))
+ if(!TrReadInt(tr, MinBinSize, MaxBinSize, &intVal))
return 0;
src->mSize = static_cast<uint>(intVal);
if(!TrIsOperator(tr, ","))
@@ -1595,9 +1623,9 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
TrIndication(tr, &line, &col);
if(!TrReadInt(tr, -2147483647-1, 2147483647, &intVal))
return 0;
- if(std::abs(intVal) < MIN_BIN_BITS || static_cast<uint>(std::abs(intVal)) > (8*src->mSize))
+ if(std::abs(intVal) < int{MinBinSize}*8 || static_cast<uint>(std::abs(intVal)) > (8*src->mSize))
{
- TrErrorAt(tr, line, col, "Expected a value of (+/-) %d to %d.\n", MIN_BIN_BITS, 8*src->mSize);
+ TrErrorAt(tr, line, col, "Expected a value of (+/-) %d to %d.\n", MinBinSize*8, 8*src->mSize);
return 0;
}
src->mBits = intVal;
@@ -1621,7 +1649,7 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
{
if(!TrReadOperator(tr, ","))
return 0;
- if(!TrReadInt(tr, MIN_ASCII_BITS, MAX_ASCII_BITS, &intVal))
+ if(!TrReadInt(tr, MinASCIIBits, MaxASCIIBits, &intVal))
return 0;
src->mSize = 0;
src->mBits = intVal;
@@ -1655,7 +1683,7 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
src->mOffset = 0;
if(!TrReadOperator(tr, ":"))
return 0;
- if(!TrReadString(tr, MAX_PATH_LEN, src->mPath))
+ if(!TrReadString(tr, MAX_PATH_LEN, src->mPath.data()))
return 0;
return 1;
}
@@ -1663,14 +1691,14 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
// Parse and validate a SOFA source reference from the data set definition.
static int ReadSofaRef(TokenReaderT *tr, SourceRefT *src)
{
- char ident[MAX_IDENT_LEN+1];
+ std::array<char,MaxIdentLen+1> ident;
uint line, col;
int intVal;
TrIndication(tr, &line, &col);
- if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+ if(!TrReadIdent(tr, MaxIdentLen, ident.data()))
return 0;
- src->mFormat = MatchSourceFormat(ident);
+ src->mFormat = MatchSourceFormat(ident.data());
if(src->mFormat != SF_SOFA)
{
TrErrorAt(tr, line, col, "Expected the SOFA source format.\n");
@@ -1694,7 +1722,7 @@ static int ReadSofaRef(TokenReaderT *tr, SourceRefT *src)
src->mOffset = 0;
if(!TrReadOperator(tr, ":"))
return 0;
- if(!TrReadString(tr, MAX_PATH_LEN, src->mPath))
+ if(!TrReadString(tr, MAX_PATH_LEN, src->mPath.data()))
return 0;
return 1;
}
@@ -1745,12 +1773,12 @@ static void AverageHrirMagnitude(const uint points, const uint n, const double *
static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate)
{
const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
- hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize);
+ hData->mHrirsBase.resize(size_t{channels} * hData->mIrCount * hData->mIrSize);
double *hrirs = hData->mHrirsBase.data();
- auto hrir = std::make_unique<double[]>(hData->mIrSize);
+ auto hrir = std::vector<double>(hData->mIrSize);
uint line, col, fi, ei, ai;
- std::vector<double> onsetSamples(OnsetRateMultiple * hData->mIrPoints);
+ std::vector<double> onsetSamples(size_t{OnsetRateMultiple} * hData->mIrPoints);
PPhaseResampler onsetResampler;
onsetResampler.init(hData->mIrRate, OnsetRateMultiple*hData->mIrRate);
@@ -1767,57 +1795,50 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
int count{0};
while(TrIsOperator(tr, "["))
{
- double factor[2]{ 1.0, 1.0 };
+ std::array factor{1.0, 1.0};
TrIndication(tr, &line, &col);
TrReadOperator(tr, "[");
if(TrIsOperator(tr, "*"))
{
- SourceRefT src;
- struct MYSOFA_EASY *sofa;
- uint si;
-
TrReadOperator(tr, "*");
if(!TrReadOperator(tr, "]") || !TrReadOperator(tr, "="))
return 0;
TrIndication(tr, &line, &col);
+ SourceRefT src{};
if(!ReadSofaRef(tr, &src))
return 0;
if(hData->mChannelType == CT_STEREO)
{
- char type[MAX_IDENT_LEN+1];
- ChannelTypeT channelType;
+ std::array<char,MaxIdentLen+1> type{};
- if(!TrReadIdent(tr, MAX_IDENT_LEN, type))
+ if(!TrReadIdent(tr, MaxIdentLen, type.data()))
return 0;
- channelType = MatchChannelType(type);
-
+ const ChannelTypeT channelType{MatchChannelType(type.data())};
switch(channelType)
{
- case CT_NONE:
- TrErrorAt(tr, line, col, "Expected a channel type.\n");
- return 0;
- case CT_MONO:
- src.mChannel = 0;
- break;
- case CT_STEREO:
- src.mChannel = 1;
- break;
+ case CT_NONE:
+ TrErrorAt(tr, line, col, "Expected a channel type.\n");
+ return 0;
+ case CT_MONO:
+ src.mChannel = 0;
+ break;
+ case CT_STEREO:
+ src.mChannel = 1;
+ break;
}
}
else
{
- char type[MAX_IDENT_LEN+1];
- ChannelTypeT channelType;
-
- if(!TrReadIdent(tr, MAX_IDENT_LEN, type))
+ std::array<char,MaxIdentLen+1> type{};
+ if(!TrReadIdent(tr, MaxIdentLen, type.data()))
return 0;
- channelType = MatchChannelType(type);
+ ChannelTypeT channelType{MatchChannelType(type.data())};
if(channelType != CT_MONO)
{
TrErrorAt(tr, line, col, "Expected a mono channel type.\n");
@@ -1826,20 +1847,20 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
src.mChannel = 0;
}
- sofa = LoadSofaFile(&src, hData->mIrRate, hData->mIrPoints);
+ MYSOFA_EASY *sofa{LoadSofaFile(&src, hData->mIrRate, hData->mIrPoints)};
if(!sofa) return 0;
- for(si = 0;si < sofa->hrtf->M;si++)
+ for(uint si{0};si < sofa->hrtf->M;++si)
{
printf("\rLoading sources... %d of %d", si+1, sofa->hrtf->M);
fflush(stdout);
- float aer[3] = {
- sofa->hrtf->SourcePosition.values[3*si],
- sofa->hrtf->SourcePosition.values[3*si + 1],
- sofa->hrtf->SourcePosition.values[3*si + 2]
+ std::array aer{
+ sofa->hrtf->SourcePosition.values[3_uz*si],
+ sofa->hrtf->SourcePosition.values[3_uz*si + 1],
+ sofa->hrtf->SourcePosition.values[3_uz*si + 2]
};
- mysofa_c2s(aer);
+ mysofa_c2s(aer.data());
if(std::fabs(aer[1]) >= 89.999f)
aer[0] = 0.0f;
@@ -1875,24 +1896,25 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
return 0;
}
- ExtractSofaHrir(sofa, si, 0, src.mOffset, hData->mIrPoints, hrir.get());
- azd->mIrs[0] = &hrirs[hData->mIrSize * azd->mIndex];
+ ExtractSofaHrir(sofa, si, 0, src.mOffset, hData->mIrPoints, hrir.data());
+ azd->mIrs[0] = &hrirs[size_t{hData->mIrSize} * azd->mIndex];
azd->mDelays[0] = AverageHrirOnset(onsetResampler, onsetSamples, hData->mIrRate,
- hData->mIrPoints, hrir.get(), 1.0, azd->mDelays[0]);
+ hData->mIrPoints, hrir.data(), 1.0, azd->mDelays[0]);
if(resampler)
- resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize, hrir.get());
- AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0, azd->mIrs[0]);
+ resampler->process(hData->mIrPoints, hrir.data(), hData->mIrSize, hrir.data());
+ AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.data(), 1.0, azd->mIrs[0]);
if(src.mChannel == 1)
{
- ExtractSofaHrir(sofa, si, 1, src.mOffset, hData->mIrPoints, hrir.get());
- azd->mIrs[1] = &hrirs[hData->mIrSize * (hData->mIrCount + azd->mIndex)];
+ ExtractSofaHrir(sofa, si, 1, src.mOffset, hData->mIrPoints, hrir.data());
+ azd->mIrs[1] = &hrirs[hData->mIrSize * (size_t{hData->mIrCount}+azd->mIndex)];
azd->mDelays[1] = AverageHrirOnset(onsetResampler, onsetSamples,
- hData->mIrRate, hData->mIrPoints, hrir.get(), 1.0, azd->mDelays[1]);
+ hData->mIrRate, hData->mIrPoints, hrir.data(), 1.0, azd->mDelays[1]);
if(resampler)
- resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize,
- hrir.get());
- AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0, azd->mIrs[1]);
+ resampler->process(hData->mIrPoints, hrir.data(), hData->mIrSize,
+ hrir.data());
+ AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.data(), 1.0,
+ azd->mIrs[1]);
}
// TODO: Since some SOFA files contain minimum phase HRIRs,
@@ -1917,10 +1939,9 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
if(!TrReadOperator(tr, "="))
return 0;
- for(;;)
+ while(true)
{
- SourceRefT src;
-
+ SourceRefT src{};
if(!ReadSourceRef(tr, &src))
return 0;
@@ -1931,29 +1952,28 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
printf("\rLoading sources... %d file%s", count, (count==1)?"":"s");
fflush(stdout);
- if(!LoadSource(&src, hData->mIrRate, hData->mIrPoints, hrir.get()))
+ if(!LoadSource(&src, hData->mIrRate, hData->mIrPoints, hrir.data()))
return 0;
uint ti{0};
if(hData->mChannelType == CT_STEREO)
{
- char ident[MAX_IDENT_LEN+1];
-
- if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+ std::array<char,MaxIdentLen+1> ident{};
+ if(!TrReadIdent(tr, MaxIdentLen, ident.data()))
return 0;
- ti = static_cast<uint>(MatchTargetEar(ident));
+ ti = static_cast<uint>(MatchTargetEar(ident.data()));
if(static_cast<int>(ti) < 0)
{
TrErrorAt(tr, line, col, "Expected a target ear.\n");
return 0;
}
}
- azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti * hData->mIrCount + azd->mIndex)];
+ azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti*size_t{hData->mIrCount} + azd->mIndex)];
azd->mDelays[ti] = AverageHrirOnset(onsetResampler, onsetSamples, hData->mIrRate,
- hData->mIrPoints, hrir.get(), 1.0 / factor[ti], azd->mDelays[ti]);
+ hData->mIrPoints, hrir.data(), 1.0 / factor[ti], azd->mDelays[ti]);
if(resampler)
- resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize, hrir.get());
- AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0 / factor[ti],
+ resampler->process(hData->mIrPoints, hrir.data(), hData->mIrSize, hrir.data());
+ AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.data(), 1.0 / factor[ti],
azd->mIrs[ti]);
factor[ti] += 1.0;
if(!TrIsOperator(tr, "+"))
@@ -1975,7 +1995,7 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
}
}
printf("\n");
- hrir = nullptr;
+ hrir.clear();
if(resampler)
{
hData->mIrRate = outRate;
@@ -2025,19 +2045,19 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
{
HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
- azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti * hData->mIrCount + azd->mIndex)];
+ azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti*size_t{hData->mIrCount} + azd->mIndex)];
}
}
}
}
if(!TrLoad(tr))
{
- mysofa_cache_release_all();
+ gSofaCache.clear();
return 1;
}
TrError(tr, "Errant data at end of source list.\n");
- mysofa_cache_release_all();
+ gSofaCache.clear();
return 0;
}
diff --git a/utils/makemhr/loadsofa.cpp b/utils/makemhr/loadsofa.cpp
index 9bcfc38d..b2038c77 100644
--- a/utils/makemhr/loadsofa.cpp
+++ b/utils/makemhr/loadsofa.cpp
@@ -39,6 +39,7 @@
#include <vector>
#include "alspan.h"
+#include "alnumeric.h"
#include "makemhr.h"
#include "polyphase_resampler.h"
#include "sofa-support.h"
@@ -65,8 +66,8 @@ static bool PrepareLayout(const uint m, const float *xyzs, HrirDataT *hData)
return false;
}
- double distances[MAX_FD_COUNT]{};
- uint evCounts[MAX_FD_COUNT]{};
+ std::array<double,MAX_FD_COUNT> distances{};
+ std::array<uint,MAX_FD_COUNT> evCounts{};
auto azCounts = std::vector<std::array<uint,MAX_EV_COUNT>>(MAX_FD_COUNT);
for(auto &azs : azCounts) azs.fill(0u);
@@ -88,7 +89,7 @@ static bool PrepareLayout(const uint m, const float *xyzs, HrirDataT *hData)
}
fprintf(stdout, "Using %u of %u IRs.\n", ir_total, m);
const auto azs = al::span{azCounts}.first<MAX_FD_COUNT>();
- return PrepareHrirData({distances, fi}, evCounts, azs, hData);
+ return PrepareHrirData(al::span{distances}.first(fi), evCounts, azs, hData);
}
@@ -144,7 +145,7 @@ float GetSampleRate(MYSOFA_HRTF *sofaHrtf)
return 0.0f;
}
/* I dimensions guarantees 1 element, so just extract it. */
- if(srate_array->values[0] < MIN_RATE || srate_array->values[0] > MAX_RATE)
+ if(srate_array->values[0] < float{MIN_RATE} || srate_array->values[0] > float{MAX_RATE})
{
fprintf(stderr, "Sample rate out of range: %f (expected %u to %u)", srate_array->values[0],
MIN_RATE, MAX_RATE);
@@ -261,27 +262,27 @@ static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData, const DelayTy
auto load_proc = [sofaHrtf,hData,delayType,outRate,&loaded_count]() -> bool
{
const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
- hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize, 0.0);
+ hData->mHrirsBase.resize(channels * size_t{hData->mIrCount} * hData->mIrSize, 0.0);
double *hrirs = hData->mHrirsBase.data();
- std::unique_ptr<double[]> restmp;
+ std::vector<double> restmp;
std::optional<PPhaseResampler> resampler;
if(outRate && outRate != hData->mIrRate)
{
resampler.emplace().init(hData->mIrRate, outRate);
- restmp = std::make_unique<double[]>(sofaHrtf->N);
+ restmp.resize(sofaHrtf->N);
}
for(uint si{0u};si < sofaHrtf->M;++si)
{
loaded_count.fetch_add(1u);
- float aer[3]{
- sofaHrtf->SourcePosition.values[3*si],
- sofaHrtf->SourcePosition.values[3*si + 1],
- sofaHrtf->SourcePosition.values[3*si + 2]
+ std::array aer{
+ sofaHrtf->SourcePosition.values[3_uz*si],
+ sofaHrtf->SourcePosition.values[3_uz*si + 1],
+ sofaHrtf->SourcePosition.values[3_uz*si + 2]
};
- mysofa_c2s(aer);
+ mysofa_c2s(aer.data());
if(std::abs(aer[1]) >= 89.999f)
aer[0] = 0.0f;
@@ -317,15 +318,15 @@ static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData, const DelayTy
for(uint ti{0u};ti < channels;++ti)
{
- azd->mIrs[ti] = &hrirs[hData->mIrSize * (hData->mIrCount*ti + azd->mIndex)];
+ azd->mIrs[ti] = &hrirs[(size_t{hData->mIrCount}*ti + azd->mIndex)*hData->mIrSize];
if(!resampler)
- std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
+ std::copy_n(&sofaHrtf->DataIR.values[(size_t{si}*sofaHrtf->R + ti)*sofaHrtf->N],
sofaHrtf->N, azd->mIrs[ti]);
else
{
- std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
- sofaHrtf->N, restmp.get());
- resampler->process(sofaHrtf->N, restmp.get(), hData->mIrSize, azd->mIrs[ti]);
+ std::copy_n(&sofaHrtf->DataIR.values[(size_t{si}*sofaHrtf->R + ti)*sofaHrtf->N],
+ sofaHrtf->N, restmp.data());
+ resampler->process(sofaHrtf->N, restmp.data(), hData->mIrSize, azd->mIrs[ti]);
}
}
@@ -382,7 +383,7 @@ struct MagCalculator {
{
auto htemp = std::vector<complex_d>(mFftSize);
- while(1)
+ while(true)
{
/* Load the current index to process. */
size_t idx{mCurrent.load()};
@@ -459,7 +460,7 @@ bool LoadSofaFile(const char *filename, const uint numThreads, const uint fftSiz
/* Assume a default head radius of 9cm. */
hData->mRadius = 0.09;
- hData->mIrRate = static_cast<uint>(GetSampleRate(sofaHrtf.get()) + 0.5f);
+ hData->mIrRate = static_cast<uint>(std::lround(GetSampleRate(sofaHrtf.get())));
if(!hData->mIrRate)
return false;
@@ -520,7 +521,7 @@ bool LoadSofaFile(const char *filename, const uint numThreads, const uint fftSiz
for(uint ai{0u};ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
{
HrirAzT &azd = hData->mFds[fi].mEvs[ei].mAzs[ai];
- for(uint ti{0u};ti < channels;ti++)
+ for(size_t ti{0u};ti < channels;ti++)
azd.mIrs[ti] = &hrirs[hData->mIrSize * (hData->mIrCount*ti + azd.mIndex)];
}
}
@@ -533,7 +534,7 @@ bool LoadSofaFile(const char *filename, const uint numThreads, const uint fftSiz
auto onset_proc = [hData,channels,&hrir_done]() -> bool
{
/* Temporary buffer used to calculate the IR's onset. */
- auto upsampled = std::vector<double>(OnsetRateMultiple * hData->mIrPoints);
+ auto upsampled = std::vector<double>(size_t{OnsetRateMultiple} * hData->mIrPoints);
/* This resampler is used to help detect the response onset. */
PPhaseResampler rs;
rs.init(hData->mIrRate, OnsetRateMultiple*hData->mIrRate);
diff --git a/utils/makemhr/makemhr.cpp b/utils/makemhr/makemhr.cpp
index 98e1b73f..0a9b71e7 100644
--- a/utils/makemhr/makemhr.cpp
+++ b/utils/makemhr/makemhr.cpp
@@ -90,6 +90,8 @@
#include "alcomplex.h"
#include "alfstream.h"
+#include "alnumbers.h"
+#include "alnumeric.h"
#include "alspan.h"
#include "alstring.h"
#include "loaddef.h"
@@ -98,61 +100,61 @@
#include "win_main_utf8.h"
-namespace {
-
-using namespace std::placeholders;
-
-} // namespace
-
-#ifndef M_PI
-#define M_PI (3.14159265358979323846)
-#endif
-
-
HrirDataT::~HrirDataT() = default;
-// Head model used for calculating the impulse delays.
-enum HeadModelT {
- HM_NONE,
- HM_DATASET, // Measure the onset from the dataset.
- HM_SPHERE // Calculate the onset using a spherical head model.
+namespace {
+
+struct FileDeleter {
+ void operator()(gsl::owner<FILE*> f) { fclose(f); }
};
+using FilePtr = std::unique_ptr<FILE,FileDeleter>;
+using namespace std::placeholders;
// The epsilon used to maintain signal stability.
-#define EPSILON (1e-9)
+constexpr double Epsilon{1e-9};
// The limits to the FFT window size override on the command line.
-#define MIN_FFTSIZE (65536)
-#define MAX_FFTSIZE (131072)
+constexpr uint MinFftSize{65536};
+constexpr uint MaxFftSize{131072};
// The limits to the equalization range limit on the command line.
-#define MIN_LIMIT (2.0)
-#define MAX_LIMIT (120.0)
+constexpr double MinLimit{2.0};
+constexpr double MaxLimit{120.0};
// The limits to the truncation window size on the command line.
-#define MIN_TRUNCSIZE (16)
-#define MAX_TRUNCSIZE (128)
+constexpr uint MinTruncSize{16};
+constexpr uint MaxTruncSize{128};
// The limits to the custom head radius on the command line.
-#define MIN_CUSTOM_RADIUS (0.05)
-#define MAX_CUSTOM_RADIUS (0.15)
-
-// The defaults for the command line options.
-#define DEFAULT_FFTSIZE (65536)
-#define DEFAULT_EQUALIZE (1)
-#define DEFAULT_SURFACE (1)
-#define DEFAULT_LIMIT (24.0)
-#define DEFAULT_TRUNCSIZE (64)
-#define DEFAULT_HEAD_MODEL (HM_DATASET)
-#define DEFAULT_CUSTOM_RADIUS (0.0)
+constexpr double MinCustomRadius{0.05};
+constexpr double MaxCustomRadius{0.15};
// The maximum propagation delay value supported by OpenAL Soft.
-#define MAX_HRTD (63.0)
+constexpr double MaxHrtd{63.0};
// The OpenAL Soft HRTF format marker. It stands for minimum-phase head
// response protocol 03.
-#define MHR_FORMAT ("MinPHR03")
+constexpr char MHRFormat[] = "MinPHR03"; // NOLINT(*-avoid-c-arrays)
+
+
+// Head model used for calculating the impulse delays.
+enum HeadModelT {
+ HM_NONE,
+ HM_DATASET, // Measure the onset from the dataset.
+ HM_SPHERE, // Calculate the onset using a spherical head model.
+
+ DEFAULT_HEAD_MODEL = HM_DATASET
+};
+
+
+// The defaults for the command line options.
+constexpr uint DefaultFftSize{65536};
+constexpr bool DefaultEqualize{true};
+constexpr bool DefaultSurface{true};
+constexpr double DefaultLimit{24.0};
+constexpr uint DefaultTruncSize{64};
+constexpr double DefaultCustomRadius{0.0};
/* Channel index enums. Mono uses LeftChannel only. */
enum ChannelIndex : uint {
@@ -165,7 +167,7 @@ enum ChannelIndex : uint {
* pattern string are replaced with the replacement string. The result is
* truncated if necessary.
*/
-static std::string StrSubst(al::span<const char> in, const al::span<const char> pat,
+std::string StrSubst(al::span<const char> in, const al::span<const char> pat,
const al::span<const char> rep)
{
std::string ret;
@@ -198,12 +200,12 @@ static std::string StrSubst(al::span<const char> in, const al::span<const char>
*********************/
// Simple clamp routine.
-static double Clamp(const double val, const double lower, const double upper)
+double Clamp(const double val, const double lower, const double upper)
{
return std::min(std::max(val, lower), upper);
}
-static inline uint dither_rng(uint *seed)
+inline uint dither_rng(uint *seed)
{
*seed = *seed * 96314165 + 907633515;
return *seed;
@@ -211,8 +213,8 @@ static inline uint dither_rng(uint *seed)
// Performs a triangular probability density function dither. The input samples
// should be normalized (-1 to +1).
-static void TpdfDither(double *RESTRICT out, const double *RESTRICT in, const double scale,
- const uint count, const uint step, uint *seed)
+void TpdfDither(double *RESTRICT out, const double *RESTRICT in, const double scale,
+ const uint count, const uint step, uint *seed)
{
static constexpr double PRNG_SCALE = 1.0 / std::numeric_limits<uint>::max();
@@ -231,9 +233,11 @@ static void TpdfDither(double *RESTRICT out, const double *RESTRICT in, const do
* of a signal's magnitude response, the imaginary components can be used as
* the angles for minimum-phase reconstruction.
*/
-inline static void Hilbert(const uint n, complex_d *inout)
+inline void Hilbert(const uint n, complex_d *inout)
{ complex_hilbert({inout, n}); }
+} // namespace
+
/* Calculate the magnitude response of the given input. This is used in
* place of phase decomposition, since the phase residuals are discarded for
* minimum phase reconstruction. The mirrored half of the response is also
@@ -244,7 +248,7 @@ void MagnitudeResponse(const uint n, const complex_d *in, double *out)
const uint m = 1 + (n / 2);
uint i;
for(i = 0;i < m;i++)
- out[i] = std::max(std::abs(in[i]), EPSILON);
+ out[i] = std::max(std::abs(in[i]), Epsilon);
}
/* Apply a range limit (in dB) to the given magnitude response. This is used
@@ -295,7 +299,7 @@ static void MinimumPhase(const uint n, double *mags, complex_d *out)
}
Hilbert(n, out);
// Remove any DC offset the filter has.
- mags[0] = EPSILON;
+ mags[0] = Epsilon;
for(i = 0;i < n;i++)
out[i] = std::polar(mags[i], out[i].imag());
}
@@ -313,7 +317,6 @@ static int WriteAscii(const char *out, FILE *fp, const char *filename)
len = strlen(out);
if(fwrite(out, 1, len, fp) != len)
{
- fclose(fp);
fprintf(stderr, "\nError: Bad write to file '%s'.\n", filename);
return 0;
}
@@ -324,13 +327,11 @@ static int WriteAscii(const char *out, FILE *fp, const char *filename)
// loading it from a 32-bit unsigned integer.
static int WriteBin4(const uint bytes, const uint32_t in, FILE *fp, const char *filename)
{
- uint8_t out[4];
- uint i;
-
- for(i = 0;i < bytes;i++)
+ std::array<uint8_t,4> out{};
+ for(uint i{0};i < bytes;i++)
out[i] = (in>>(i*8)) & 0x000000FF;
- if(fwrite(out, 1, bytes, fp) != bytes)
+ if(fwrite(out.data(), 1, bytes, fp) != bytes)
{
fprintf(stderr, "\nError: Bad write to file '%s'.\n", filename);
return 0;
@@ -345,34 +346,34 @@ static int StoreMhr(const HrirDataT *hData, const char *filename)
const uint n{hData->mIrPoints};
uint dither_seed{22222};
uint fi, ei, ai, i;
- FILE *fp;
- if((fp=fopen(filename, "wb")) == nullptr)
+ FilePtr fp{fopen(filename, "wb")};
+ if(!fp)
{
fprintf(stderr, "\nError: Could not open MHR file '%s'.\n", filename);
return 0;
}
- if(!WriteAscii(MHR_FORMAT, fp, filename))
+ if(!WriteAscii(MHRFormat, fp.get(), filename))
return 0;
- if(!WriteBin4(4, hData->mIrRate, fp, filename))
+ if(!WriteBin4(4, hData->mIrRate, fp.get(), filename))
return 0;
- if(!WriteBin4(1, static_cast<uint32_t>(hData->mChannelType), fp, filename))
+ if(!WriteBin4(1, static_cast<uint32_t>(hData->mChannelType), fp.get(), filename))
return 0;
- if(!WriteBin4(1, hData->mIrPoints, fp, filename))
+ if(!WriteBin4(1, hData->mIrPoints, fp.get(), filename))
return 0;
- if(!WriteBin4(1, static_cast<uint>(hData->mFds.size()), fp, filename))
+ if(!WriteBin4(1, static_cast<uint>(hData->mFds.size()), fp.get(), filename))
return 0;
for(fi = static_cast<uint>(hData->mFds.size()-1);fi < hData->mFds.size();fi--)
{
auto fdist = static_cast<uint32_t>(std::round(1000.0 * hData->mFds[fi].mDistance));
- if(!WriteBin4(2, fdist, fp, filename))
+ if(!WriteBin4(2, fdist, fp.get(), filename))
return 0;
- if(!WriteBin4(1, static_cast<uint32_t>(hData->mFds[fi].mEvs.size()), fp, filename))
+ if(!WriteBin4(1, static_cast<uint32_t>(hData->mFds[fi].mEvs.size()), fp.get(), filename))
return 0;
for(ei = 0;ei < hData->mFds[fi].mEvs.size();ei++)
{
const auto &elev = hData->mFds[fi].mEvs[ei];
- if(!WriteBin4(1, static_cast<uint32_t>(elev.mAzs.size()), fp, filename))
+ if(!WriteBin4(1, static_cast<uint32_t>(elev.mAzs.size()), fp.get(), filename))
return 0;
}
}
@@ -387,15 +388,15 @@ static int StoreMhr(const HrirDataT *hData, const char *filename)
for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
{
HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
- double out[2 * MAX_TRUNCSIZE];
+ std::array<double,MaxTruncSize*2_uz> out{};
- TpdfDither(out, azd->mIrs[0], scale, n, channels, &dither_seed);
+ TpdfDither(out.data(), azd->mIrs[0], scale, n, channels, &dither_seed);
if(hData->mChannelType == CT_STEREO)
- TpdfDither(out+1, azd->mIrs[1], scale, n, channels, &dither_seed);
+ TpdfDither(out.data()+1, azd->mIrs[1], scale, n, channels, &dither_seed);
for(i = 0;i < (channels * n);i++)
{
const auto v = static_cast<int>(Clamp(out[i], -scale-1.0, scale));
- if(!WriteBin4(bps, static_cast<uint32_t>(v), fp, filename))
+ if(!WriteBin4(bps, static_cast<uint32_t>(v), fp.get(), filename))
return 0;
}
}
@@ -410,16 +411,15 @@ static int StoreMhr(const HrirDataT *hData, const char *filename)
for(const auto &azd : hData->mFds[fi].mEvs[ei].mAzs)
{
auto v = static_cast<uint>(std::round(azd.mDelays[0]*DelayPrecScale));
- if(!WriteBin4(1, v, fp, filename)) return 0;
+ if(!WriteBin4(1, v, fp.get(), filename)) return 0;
if(hData->mChannelType == CT_STEREO)
{
v = static_cast<uint>(std::round(azd.mDelays[1]*DelayPrecScale));
- if(!WriteBin4(1, v, fp, filename)) return 0;
+ if(!WriteBin4(1, v, fp.get(), filename)) return 0;
}
}
}
}
- fclose(fp);
return 1;
}
@@ -434,21 +434,18 @@ static int StoreMhr(const HrirDataT *hData, const char *filename)
*/
static void BalanceFieldMagnitudes(const HrirDataT *hData, const uint channels, const uint m)
{
- double maxMags[MAX_FD_COUNT];
- uint fi, ei, ti, i;
-
+ std::array<double,MAX_FD_COUNT> maxMags{};
double maxMag{0.0};
- for(fi = 0;fi < hData->mFds.size();fi++)
- {
- maxMags[fi] = 0.0;
- for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
+ for(size_t fi{0};fi < hData->mFds.size();++fi)
+ {
+ for(size_t ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();++ei)
{
for(const auto &azd : hData->mFds[fi].mEvs[ei].mAzs)
{
- for(ti = 0;ti < channels;ti++)
+ for(size_t ti{0};ti < channels;++ti)
{
- for(i = 0;i < m;i++)
+ for(size_t i{0};i < m;++i)
maxMags[fi] = std::max(azd.mIrs[ti][i], maxMags[fi]);
}
}
@@ -457,17 +454,17 @@ static void BalanceFieldMagnitudes(const HrirDataT *hData, const uint channels,
maxMag = std::max(maxMags[fi], maxMag);
}
- for(fi = 0;fi < hData->mFds.size();fi++)
+ for(size_t fi{0};fi < hData->mFds.size();++fi)
{
const double magFactor{maxMag / maxMags[fi]};
- for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
+ for(size_t ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();++ei)
{
for(const auto &azd : hData->mFds[fi].mEvs[ei].mAzs)
{
- for(ti = 0;ti < channels;ti++)
+ for(size_t ti{0};ti < channels;++ti)
{
- for(i = 0;i < m;i++)
+ for(size_t i{0};i < m;++i)
azd.mIrs[ti][i] *= magFactor;
}
}
@@ -499,17 +496,17 @@ static void CalculateDfWeights(const HrirDataT *hData, double *weights)
outerRa = 10.0f;
const double raPowDiff{std::pow(outerRa, 3.0) - std::pow(innerRa, 3.0)};
- evs = M_PI / 2.0 / static_cast<double>(hData->mFds[fi].mEvs.size() - 1);
+ evs = al::numbers::pi / 2.0 / static_cast<double>(hData->mFds[fi].mEvs.size() - 1);
for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
{
const auto &elev = hData->mFds[fi].mEvs[ei];
// For each elevation, calculate the upper and lower limits of
// the patch band.
ev = elev.mElevation;
- lowerEv = std::max(-M_PI / 2.0, ev - evs);
- upperEv = std::min(M_PI / 2.0, ev + evs);
+ lowerEv = std::max(-al::numbers::pi / 2.0, ev - evs);
+ upperEv = std::min(al::numbers::pi / 2.0, ev + evs);
// Calculate the surface area of the patch band.
- solidAngle = 2.0 * M_PI * (std::sin(upperEv) - std::sin(lowerEv));
+ solidAngle = 2.0 * al::numbers::pi * (std::sin(upperEv) - std::sin(lowerEv));
// Then the volume of the extruded patch band.
solidVolume = solidAngle * raPowDiff / 3.0;
// Each weight is the volume of one extruded patch.
@@ -539,7 +536,7 @@ static void CalculateDiffuseFieldAverage(const HrirDataT *hData, const uint chan
const int weighted, const double limit, double *dfa)
{
std::vector<double> weights(hData->mFds.size() * MAX_EV_COUNT);
- uint count, ti, fi, ei, i, ai;
+ uint count;
if(weighted)
{
@@ -553,42 +550,42 @@ static void CalculateDiffuseFieldAverage(const HrirDataT *hData, const uint chan
// If coverage weighting is not used, the weights still need to be
// averaged by the number of existing HRIRs.
count = hData->mIrCount;
- for(fi = 0;fi < hData->mFds.size();fi++)
+ for(size_t fi{0};fi < hData->mFds.size();++fi)
{
- for(ei = 0;ei < hData->mFds[fi].mEvStart;ei++)
+ for(size_t ei{0};ei < hData->mFds[fi].mEvStart;++ei)
count -= static_cast<uint>(hData->mFds[fi].mEvs[ei].mAzs.size());
}
weight = 1.0 / count;
- for(fi = 0;fi < hData->mFds.size();fi++)
+ for(size_t fi{0};fi < hData->mFds.size();++fi)
{
- for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
+ for(size_t ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();++ei)
weights[(fi * MAX_EV_COUNT) + ei] = weight;
}
}
- for(ti = 0;ti < channels;ti++)
+ for(size_t ti{0};ti < channels;++ti)
{
- for(i = 0;i < m;i++)
+ for(size_t i{0};i < m;++i)
dfa[(ti * m) + i] = 0.0;
- for(fi = 0;fi < hData->mFds.size();fi++)
+ for(size_t fi{0};fi < hData->mFds.size();++fi)
{
- for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
+ for(size_t ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();++ei)
{
- for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
+ for(size_t ai{0};ai < hData->mFds[fi].mEvs[ei].mAzs.size();++ai)
{
HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
// Get the weight for this HRIR's contribution.
double weight = weights[(fi * MAX_EV_COUNT) + ei];
// Add this HRIR's weighted power average to the total.
- for(i = 0;i < m;i++)
+ for(size_t i{0};i < m;++i)
dfa[(ti * m) + i] += weight * azd->mIrs[ti][i] * azd->mIrs[ti][i];
}
}
}
// Finish the average calculation and keep it from being too small.
- for(i = 0;i < m;i++)
- dfa[(ti * m) + i] = std::max(sqrt(dfa[(ti * m) + i]), EPSILON);
+ for(size_t i{0};i < m;++i)
+ dfa[(ti * m) + i] = std::max(sqrt(dfa[(ti * m) + i]), Epsilon);
// Apply a limit to the magnitude range of the diffuse-field average
// if desired.
if(limit > 0.0)
@@ -600,17 +597,15 @@ static void CalculateDiffuseFieldAverage(const HrirDataT *hData, const uint chan
// set using the given average response.
static void DiffuseFieldEqualize(const uint channels, const uint m, const double *dfa, const HrirDataT *hData)
{
- uint ti, fi, ei, i;
-
- for(fi = 0;fi < hData->mFds.size();fi++)
+ for(size_t fi{0};fi < hData->mFds.size();++fi)
{
- for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
+ for(size_t ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();++ei)
{
for(auto &azd : hData->mFds[fi].mEvs[ei].mAzs)
{
- for(ti = 0;ti < channels;ti++)
+ for(size_t ti{0};ti < channels;++ti)
{
- for(i = 0;i < m;i++)
+ for(size_t i{0};i < m;++i)
azd.mIrs[ti][i] /= dfa[(ti * m) + i];
}
}
@@ -624,7 +619,8 @@ static void DiffuseFieldEqualize(const uint channels, const uint m, const double
*/
static void CalcAzIndices(const HrirFdT &field, const uint ei, const double az, uint *a0, uint *a1, double *af)
{
- double f{(2.0*M_PI + az) * static_cast<double>(field.mEvs[ei].mAzs.size()) / (2.0*M_PI)};
+ double f{(2.0*al::numbers::pi + az) * static_cast<double>(field.mEvs[ei].mAzs.size()) /
+ (2.0*al::numbers::pi)};
const uint i{static_cast<uint>(f) % static_cast<uint>(field.mEvs[ei].mAzs.size())};
f -= std::floor(f);
@@ -674,7 +670,7 @@ static void SynthesizeOnsets(HrirDataT *hData)
* the mirrored elevation to find the indices for the polar
* opposite position (may need blending).
*/
- const double az{field.mEvs[ei].mAzs[ai].mAzimuth + M_PI};
+ const double az{field.mEvs[ei].mAzs[ai].mAzimuth + al::numbers::pi};
CalcAzIndices(field, topElev, az, &a0, &a1, &af);
/* Blend the delays, and again, swap the ears. */
@@ -706,8 +702,8 @@ static void SynthesizeOnsets(HrirDataT *hData)
* measurement).
*/
double az{field.mEvs[ei].mAzs[ai].mAzimuth};
- if(az <= M_PI) az = M_PI - az;
- else az = (M_PI*2.0)-az + M_PI;
+ if(az <= al::numbers::pi) az = al::numbers::pi - az;
+ else az = (al::numbers::pi*2.0)-az + al::numbers::pi;
CalcAzIndices(field, topElev, az, &a0, &a1, &af);
field.mEvs[ei].mAzs[ai].mDelays[0] = Lerp(
@@ -735,12 +731,12 @@ static void SynthesizeOnsets(HrirDataT *hData)
double az{field.mEvs[ei].mAzs[ai].mAzimuth};
CalcAzIndices(field, upperElevReal, az, &a0, &a1, &af0);
CalcAzIndices(field, lowerElevFake, az, &a2, &a3, &af1);
- double blend[4]{
+ std::array<double,4> blend{{
(1.0-ef) * (1.0-af0),
(1.0-ef) * ( af0),
( ef) * (1.0-af1),
( ef) * ( af1)
- };
+ }};
for(uint ti{0u};ti < channels;ti++)
{
@@ -785,7 +781,7 @@ static void SynthesizeHrirs(HrirDataT *hData)
* and vice-versa, this produces a decent phantom-center response
* underneath the head.
*/
- CalcAzIndices(field, oi, ((ti==0) ? -M_PI : M_PI) / 2.0, &a0, &a1, &af);
+ CalcAzIndices(field, oi, al::numbers::pi / ((ti==0) ? -2.0 : 2.0), &a0, &a1, &af);
for(uint i{0u};i < m;i++)
{
field.mEvs[0].mAzs[0].mIrs[ti][i] = Lerp(field.mEvs[oi].mAzs[a0].mIrs[ti][i],
@@ -797,7 +793,7 @@ static void SynthesizeHrirs(HrirDataT *hData)
{
const double of{static_cast<double>(ei) / field.mEvStart};
const double b{(1.0 - of) * beta};
- double lp[4]{};
+ std::array<double,4> lp{};
/* Calculate a low-pass filter to simulate body occlusion. */
lp[0] = Lerp(1.0, lp[0], b);
@@ -842,7 +838,7 @@ static void SynthesizeHrirs(HrirDataT *hData)
}
}
const double b{beta};
- double lp[4]{};
+ std::array<double,4> lp{};
lp[0] = Lerp(1.0, lp[0], b);
lp[1] = Lerp(lp[0], lp[1], b);
lp[2] = Lerp(lp[1], lp[2], b);
@@ -877,10 +873,10 @@ static void SynthesizeHrirs(HrirDataT *hData)
*/
struct HrirReconstructor {
std::vector<double*> mIrs;
- std::atomic<size_t> mCurrent;
- std::atomic<size_t> mDone;
- uint mFftSize;
- uint mIrPoints;
+ std::atomic<size_t> mCurrent{};
+ std::atomic<size_t> mDone{};
+ uint mFftSize{};
+ uint mIrPoints{};
void Worker()
{
@@ -888,7 +884,7 @@ struct HrirReconstructor {
auto mags = std::vector<double>(mFftSize);
size_t m{(mFftSize/2) + 1};
- while(1)
+ while(true)
{
/* Load the current index to process. */
size_t idx{mCurrent.load()};
@@ -907,7 +903,7 @@ struct HrirReconstructor {
* time-domain response.
*/
for(size_t i{0};i < m;++i)
- mags[i] = std::max(mIrs[idx][i], EPSILON);
+ mags[i] = std::max(mIrs[idx][i], Epsilon);
MinimumPhase(mFftSize, mags.data(), h.data());
FftInverse(mFftSize, h.data());
for(uint i{0u};i < mIrPoints;++i)
@@ -991,7 +987,7 @@ static void NormalizeHrirs(HrirDataT *hData)
return LevelPair{std::max(current.amp, levels.amp), std::max(current.rms, levels.rms)};
};
auto measure_azi = [channels,mesasure_channel](const LevelPair levels, const HrirAzT &azi)
- { return std::accumulate(azi.mIrs, azi.mIrs+channels, levels, mesasure_channel); };
+ { return std::accumulate(azi.mIrs.begin(), azi.mIrs.begin()+channels, levels, mesasure_channel); };
auto measure_elev = [measure_azi](const LevelPair levels, const HrirEvT &elev)
{ return std::accumulate(elev.mAzs.cbegin(), elev.mAzs.cend(), levels, measure_azi); };
auto measure_field = [measure_elev](const LevelPair levels, const HrirFdT &field)
@@ -1018,7 +1014,7 @@ static void NormalizeHrirs(HrirDataT *hData)
auto proc_channel = [irSize,factor](double *ir)
{ std::transform(ir, ir+irSize, ir, [factor](double s){ return s * factor; }); };
auto proc_azi = [channels,proc_channel](HrirAzT &azi)
- { std::for_each(azi.mIrs, azi.mIrs+channels, proc_channel); };
+ { std::for_each(azi.mIrs.begin(), azi.mIrs.begin()+channels, proc_channel); };
auto proc_elev = [proc_azi](HrirEvT &elev)
{ std::for_each(elev.mAzs.begin(), elev.mAzs.end(), proc_azi); };
auto proc1_field = [proc_elev](HrirFdT &field)
@@ -1035,7 +1031,7 @@ static double CalcLTD(const double ev, const double az, const double rad, const
azp = std::asin(std::cos(ev) * std::sin(az));
dlp = std::sqrt((dist*dist) + (rad*rad) + (2.0*dist*rad*sin(azp)));
l = std::sqrt((dist*dist) - (rad*rad));
- al = (0.5 * M_PI) + azp;
+ al = (0.5 * al::numbers::pi) + azp;
if(dlp > l)
dlp = l + (rad * (al - std::acos(rad / dist)));
return dlp / 343.3;
@@ -1103,10 +1099,10 @@ static void CalculateHrtds(const HeadModelT model, const double radius, HrirData
}
}
}
- if(maxHrtd > MAX_HRTD)
+ if(maxHrtd > MaxHrtd)
{
- fprintf(stdout, " Scaling for max delay of %f samples to %f\n...\n", maxHrtd, MAX_HRTD);
- const double scale{MAX_HRTD / maxHrtd};
+ fprintf(stdout, " Scaling for max delay of %f samples to %f\n...\n", maxHrtd, MaxHrtd);
+ const double scale{MaxHrtd / maxHrtd};
for(auto &field : hData->mFds)
{
for(auto &elev : field.mEvs)
@@ -1153,11 +1149,12 @@ bool PrepareHrirData(const al::span<const double> distances,
{
uint azCount = azCounts[fi][ei];
- hData->mFds[fi].mEvs[ei].mElevation = -M_PI / 2.0 + M_PI * ei / (evCounts[fi] - 1);
+ hData->mFds[fi].mEvs[ei].mElevation = -al::numbers::pi / 2.0 + al::numbers::pi * ei /
+ (evCounts[fi] - 1);
hData->mFds[fi].mEvs[ei].mAzs = {&hData->mAzsBase[azTotal], azCount};
for(uint ai{0};ai < azCount;ai++)
{
- hData->mFds[fi].mEvs[ei].mAzs[ai].mAzimuth = 2.0 * M_PI * ai / azCount;
+ hData->mFds[fi].mEvs[ei].mAzs[ai].mAzimuth = 2.0 * al::numbers::pi * ai / azCount;
hData->mFds[fi].mEvs[ei].mAzs[ai].mIndex = azTotal + ai;
hData->mFds[fi].mEvs[ei].mAzs[ai].mDelays[0] = 0.0;
hData->mFds[fi].mEvs[ei].mAzs[ai].mDelays[1] = 0.0;
@@ -1199,10 +1196,10 @@ static int ProcessDefinition(const char *inName, const uint outRate, const Chann
return 0;
}
- char startbytes[4]{};
- input->read(startbytes, sizeof(startbytes));
+ std::array<char,4> startbytes{};
+ input->read(startbytes.data(), startbytes.size());
std::streamsize startbytecount{input->gcount()};
- if(startbytecount != sizeof(startbytes) || !input->good())
+ if(startbytecount != startbytes.size() || !input->good())
{
fprintf(stderr, "Error: Could not read input file '%s'\n", inName);
return 0;
@@ -1219,7 +1216,8 @@ static int ProcessDefinition(const char *inName, const uint outRate, const Chann
else
{
fprintf(stdout, "Reading HRIR definition from %s...\n", inName);
- if(!LoadDefInput(*input, startbytes, startbytecount, inName, fftSize, truncSize, outRate, chanMode, &hData))
+ if(!LoadDefInput(*input, startbytes.data(), startbytecount, inName, fftSize, truncSize,
+ outRate, chanMode, &hData))
return 0;
}
}
@@ -1228,7 +1226,7 @@ static int ProcessDefinition(const char *inName, const uint outRate, const Chann
{
uint c{(hData.mChannelType == CT_STEREO) ? 2u : 1u};
uint m{hData.mFftSize/2u + 1u};
- auto dfa = std::vector<double>(c * m);
+ auto dfa = std::vector<double>(size_t{c} * m);
if(hData.mFds.size() > 1)
{
@@ -1264,7 +1262,7 @@ static int ProcessDefinition(const char *inName, const uint outRate, const Chann
fprintf(stdout, "Normalizing final HRIRs...\n");
NormalizeHrirs(&hData);
fprintf(stdout, "Calculating impulse delays...\n");
- CalculateHrtds(model, (radius > DEFAULT_CUSTOM_RADIUS) ? radius : hData.mRadius, &hData);
+ CalculateHrtds(model, (radius > DefaultCustomRadius) ? radius : hData.mRadius, &hData);
const auto rateStr = std::to_string(hData.mIrRate);
const auto expName = StrSubst({outName, strlen(outName)}, {"%r", 2},
@@ -1283,13 +1281,13 @@ static void PrintHelp(const char *argv0, FILE *ofile)
fprintf(ofile, " right ear.\n");
fprintf(ofile, " -a Change the data set to single field, using the farthest field.\n");
fprintf(ofile, " -j <threads> Number of threads used to process HRIRs (default: 2).\n");
- fprintf(ofile, " -f <points> Override the FFT window size (default: %u).\n", DEFAULT_FFTSIZE);
- fprintf(ofile, " -e {on|off} Toggle diffuse-field equalization (default: %s).\n", (DEFAULT_EQUALIZE ? "on" : "off"));
- fprintf(ofile, " -s {on|off} Toggle surface-weighted diffuse-field average (default: %s).\n", (DEFAULT_SURFACE ? "on" : "off"));
+ fprintf(ofile, " -f <points> Override the FFT window size (default: %u).\n", DefaultFftSize);
+ fprintf(ofile, " -e {on|off} Toggle diffuse-field equalization (default: %s).\n", (DefaultEqualize ? "on" : "off"));
+ fprintf(ofile, " -s {on|off} Toggle surface-weighted diffuse-field average (default: %s).\n", (DefaultSurface ? "on" : "off"));
fprintf(ofile, " -l {<dB>|none} Specify a limit to the magnitude range of the diffuse-field\n");
- fprintf(ofile, " average (default: %.2f).\n", DEFAULT_LIMIT);
+ fprintf(ofile, " average (default: %.2f).\n", DefaultLimit);
fprintf(ofile, " -w <points> Specify the size of the truncation window that's applied\n");
- fprintf(ofile, " after minimum-phase reconstruction (default: %u).\n", DEFAULT_TRUNCSIZE);
+ fprintf(ofile, " after minimum-phase reconstruction (default: %u).\n", DefaultTruncSize);
fprintf(ofile, " -d {dataset| Specify the model used for calculating the head-delay timing\n");
fprintf(ofile, " sphere} values (default: %s).\n", ((DEFAULT_HEAD_MODEL == HM_DATASET) ? "dataset" : "sphere"));
fprintf(ofile, " -c <radius> Use a customized head radius measured to-ear in meters.\n");
@@ -1324,14 +1322,14 @@ int main(int argc, char *argv[])
outName = "./oalsoft_hrtf_%r.mhr";
outRate = 0;
chanMode = CM_AllowStereo;
- fftSize = DEFAULT_FFTSIZE;
- equalize = DEFAULT_EQUALIZE;
- surface = DEFAULT_SURFACE;
- limit = DEFAULT_LIMIT;
+ fftSize = DefaultFftSize;
+ equalize = DefaultEqualize;
+ surface = DefaultSurface;
+ limit = DefaultLimit;
numThreads = 2;
- truncSize = DEFAULT_TRUNCSIZE;
+ truncSize = DefaultTruncSize;
model = DEFAULT_HEAD_MODEL;
- radius = DEFAULT_CUSTOM_RADIUS;
+ radius = DefaultCustomRadius;
farfield = false;
while((opt=getopt(argc, argv, "r:maj:f:e:s:l:w:d:c:e:i:o:h")) != -1)
@@ -1368,9 +1366,9 @@ int main(int argc, char *argv[])
case 'f':
fftSize = static_cast<uint>(strtoul(optarg, &end, 10));
- if(end[0] != '\0' || (fftSize&(fftSize-1)) || fftSize < MIN_FFTSIZE || fftSize > MAX_FFTSIZE)
+ if(end[0] != '\0' || (fftSize&(fftSize-1)) || fftSize < MinFftSize || fftSize > MaxFftSize)
{
- fprintf(stderr, "\nError: Got unexpected value \"%s\" for option -%c, expected a power-of-two between %u to %u.\n", optarg, opt, MIN_FFTSIZE, MAX_FFTSIZE);
+ fprintf(stderr, "\nError: Got unexpected value \"%s\" for option -%c, expected a power-of-two between %u to %u.\n", optarg, opt, MinFftSize, MaxFftSize);
exit(EXIT_FAILURE);
}
break;
@@ -1405,9 +1403,9 @@ int main(int argc, char *argv[])
else
{
limit = strtod(optarg, &end);
- if(end[0] != '\0' || limit < MIN_LIMIT || limit > MAX_LIMIT)
+ if(end[0] != '\0' || limit < MinLimit || limit > MaxLimit)
{
- fprintf(stderr, "\nError: Got unexpected value \"%s\" for option -%c, expected between %.0f to %.0f.\n", optarg, opt, MIN_LIMIT, MAX_LIMIT);
+ fprintf(stderr, "\nError: Got unexpected value \"%s\" for option -%c, expected between %.0f to %.0f.\n", optarg, opt, MinLimit, MaxLimit);
exit(EXIT_FAILURE);
}
}
@@ -1415,9 +1413,9 @@ int main(int argc, char *argv[])
case 'w':
truncSize = static_cast<uint>(strtoul(optarg, &end, 10));
- if(end[0] != '\0' || truncSize < MIN_TRUNCSIZE || truncSize > MAX_TRUNCSIZE)
+ if(end[0] != '\0' || truncSize < MinTruncSize || truncSize > MaxTruncSize)
{
- fprintf(stderr, "\nError: Got unexpected value \"%s\" for option -%c, expected between %u to %u.\n", optarg, opt, MIN_TRUNCSIZE, MAX_TRUNCSIZE);
+ fprintf(stderr, "\nError: Got unexpected value \"%s\" for option -%c, expected between %u to %u.\n", optarg, opt, MinTruncSize, MaxTruncSize);
exit(EXIT_FAILURE);
}
break;
@@ -1436,9 +1434,9 @@ int main(int argc, char *argv[])
case 'c':
radius = strtod(optarg, &end);
- if(end[0] != '\0' || radius < MIN_CUSTOM_RADIUS || radius > MAX_CUSTOM_RADIUS)
+ if(end[0] != '\0' || radius < MinCustomRadius || radius > MaxCustomRadius)
{
- fprintf(stderr, "\nError: Got unexpected value \"%s\" for option -%c, expected between %.2f to %.2f.\n", optarg, opt, MIN_CUSTOM_RADIUS, MAX_CUSTOM_RADIUS);
+ fprintf(stderr, "\nError: Got unexpected value \"%s\" for option -%c, expected between %.2f to %.2f.\n", optarg, opt, MinCustomRadius, MaxCustomRadius);
exit(EXIT_FAILURE);
}
break;
diff --git a/utils/makemhr/makemhr.h b/utils/makemhr/makemhr.h
index aa18134d..71c2e55b 100644
--- a/utils/makemhr/makemhr.h
+++ b/utils/makemhr/makemhr.h
@@ -9,35 +9,43 @@
// The maximum path length used when processing filenames.
-#define MAX_PATH_LEN (256)
+enum { MAX_PATH_LEN = 256u };
// The limit to the number of 'distances' listed in the data set definition.
// Must be less than 256
-#define MAX_FD_COUNT (16)
+enum { MAX_FD_COUNT = 16u };
// The limits to the number of 'elevations' listed in the data set definition.
// Must be less than 256.
-#define MIN_EV_COUNT (5)
-#define MAX_EV_COUNT (181)
+enum {
+ MIN_EV_COUNT = 5u,
+ MAX_EV_COUNT = 181u
+};
// The limits for each of the 'azimuths' listed in the data set definition.
// Must be less than 256.
-#define MIN_AZ_COUNT (1)
-#define MAX_AZ_COUNT (255)
+enum {
+ MIN_AZ_COUNT = 1u,
+ MAX_AZ_COUNT = 255u
+};
// The limits for the 'distance' from source to listener for each field in
// the definition file.
-#define MIN_DISTANCE (0.05)
-#define MAX_DISTANCE (2.50)
+inline constexpr double MIN_DISTANCE{0.05};
+inline constexpr double MAX_DISTANCE{2.50};
// The limits for the sample 'rate' metric in the data set definition and for
// resampling.
-#define MIN_RATE (32000)
-#define MAX_RATE (96000)
+enum {
+ MIN_RATE = 32000u,
+ MAX_RATE = 96000u
+};
// The limits for the HRIR 'points' metric in the data set definition.
-#define MIN_POINTS (16)
-#define MAX_POINTS (8192)
+enum {
+ MIN_POINTS = 16u,
+ MAX_POINTS = 8192u
+};
using uint = unsigned int;
@@ -68,8 +76,8 @@ enum ChannelTypeT {
struct HrirAzT {
double mAzimuth{0.0};
uint mIndex{0u};
- double mDelays[2]{0.0, 0.0};
- double *mIrs[2]{nullptr, nullptr};
+ std::array<double,2> mDelays{};
+ std::array<double*,2> mIrs{};
};
struct HrirEvT {
diff --git a/utils/openal-info.c b/utils/openal-info.c
index 8ef6ebde..669727a6 100644
--- a/utils/openal-info.c
+++ b/utils/openal-info.c
@@ -45,11 +45,11 @@
#define FUNCTION_CAST(T, ptr) (T)(ptr)
#endif
-#define MAX_WIDTH 80
+enum { MaxWidth = 80 };
static void printList(const char *list, char separator)
{
- size_t col = MAX_WIDTH, len;
+ size_t col = MaxWidth, len;
const char *indent = " ";
const char *next;
@@ -71,7 +71,7 @@ static void printList(const char *list, char separator)
else
len = strlen(list);
- if(len + col + 2 >= MAX_WIDTH)
+ if(len + col + 2 >= MaxWidth)
{
fprintf(stdout, "\n%s", indent);
col = strlen(indent);
@@ -181,6 +181,14 @@ static void printHRTFInfo(ALCdevice *device)
checkALCErrors(device);
}
+static void printALCIntegerValue(ALCdevice *device, ALCenum enumValue, char* enumName)
+{
+ ALCint value;
+ alcGetIntegerv(device, enumValue, 1, &value);
+ if (checkALCErrors(device) == ALC_NO_ERROR)
+ printf("%s: %d\n", enumName, value);
+}
+
static void printModeInfo(ALCdevice *device)
{
ALCint srate = 0;
@@ -228,6 +236,9 @@ static void printModeInfo(ALCdevice *device)
}
printf("Device HRTF profile: %s\n", hrtfname ? hrtfname : "<null>");
}
+
+ printALCIntegerValue(device, ALC_MONO_SOURCES, "Device number of mono sources");
+ printALCIntegerValue(device, ALC_STEREO_SOURCES, "Device number of stereo sources");
}
static void printALCSOFTSystemEventIsSupportedResult(LPALCEVENTISSUPPORTEDSOFT alcEventIsSupportedSOFT, ALCenum eventType, ALCenum deviceType)
@@ -382,7 +393,7 @@ static void printEFXInfo(ALCdevice *device)
palFilteri(object, AL_FILTER_TYPE, filters[i]);
if(alGetError() != AL_NO_ERROR)
- memmove(current, next+1, strlen(next));
+ memmove(current, next+1, strlen(next)); /* NOLINT(clang-analyzer-security.insecureAPI.*) */
else
current = next+1;
}
@@ -401,7 +412,7 @@ static void printEFXInfo(ALCdevice *device)
palEffecti(object, AL_EFFECT_TYPE, effects[i]);
if(alGetError() != AL_NO_ERROR)
- memmove(current, next+1, strlen(next));
+ memmove(current, next+1, strlen(next)); /* NOLINT(clang-analyzer-security.insecureAPI.*) */
else
current = next+1;
}
@@ -414,7 +425,7 @@ static void printEFXInfo(ALCdevice *device)
palEffecti(object, AL_EFFECT_TYPE, dedeffects[i]);
if(alGetError() != AL_NO_ERROR)
- memmove(current, next+1, strlen(next));
+ memmove(current, next+1, strlen(next)); /* NOLINT(clang-analyzer-security.insecureAPI.*) */
else
current = next+1;
}
@@ -425,7 +436,7 @@ static void printEFXInfo(ALCdevice *device)
{
char *next = strchr(current, ',');
assert(next != NULL);
- memmove(current, next+1, strlen(next));
+ memmove(current, next+1, strlen(next)); /* NOLINT(clang-analyzer-security.insecureAPI.*) */
}
}
printf("Supported effects:");
diff --git a/utils/sofa-info.cpp b/utils/sofa-info.cpp
index 6dffef44..7775b8e3 100644
--- a/utils/sofa-info.cpp
+++ b/utils/sofa-info.cpp
@@ -21,8 +21,7 @@
* Or visit: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
-#include <stdio.h>
-
+#include <cstdio>
#include <memory>
#include <vector>
diff --git a/utils/sofa-support.cpp b/utils/sofa-support.cpp
index e37789d5..ceb3067a 100644
--- a/utils/sofa-support.cpp
+++ b/utils/sofa-support.cpp
@@ -24,11 +24,11 @@
#include "sofa-support.h"
-#include <stdio.h>
#include <algorithm>
#include <array>
#include <cmath>
+#include <cstdio>
#include <utility>
#include <vector>
@@ -47,7 +47,7 @@ using double3 = std::array<double,3>;
* equality of unique elements.
*/
std::vector<double> GetUniquelySortedElems(const std::vector<double3> &aers, const uint axis,
- const double *const (&filters)[3], const double (&epsilons)[3])
+ const std::array<const double*,3> filters, const std::array<double,3> epsilons)
{
std::vector<double> elems;
for(const double3 &aer : aers)
@@ -183,8 +183,8 @@ std::vector<SofaField> GetCompatibleLayout(const size_t m, const float *xyzs)
auto aers = std::vector<double3>(m, double3{});
for(size_t i{0u};i < m;++i)
{
- float vals[3]{xyzs[i*3], xyzs[i*3 + 1], xyzs[i*3 + 2]};
- mysofa_c2s(&vals[0]);
+ std::array vals{xyzs[i*3], xyzs[i*3 + 1], xyzs[i*3 + 2]};
+ mysofa_c2s(vals.data());
aers[i] = {vals[0], vals[1], vals[2]};
}
diff --git a/utils/uhjdecoder.cpp b/utils/uhjdecoder.cpp
index c7efa376..970d9f82 100644
--- a/utils/uhjdecoder.cpp
+++ b/utils/uhjdecoder.cpp
@@ -48,7 +48,7 @@
struct FileDeleter {
- void operator()(FILE *file) { fclose(file); }
+ void operator()(gsl::owner<FILE*> file) { fclose(file); }
};
using FilePtr = std::unique_ptr<FILE,FileDeleter>;
@@ -66,22 +66,22 @@ using complex_d = std::complex<double>;
using byte4 = std::array<std::byte,4>;
-constexpr ubyte SUBTYPE_BFORMAT_FLOAT[]{
+constexpr std::array<ubyte,16> SUBTYPE_BFORMAT_FLOAT{
0x03, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
0xca, 0x00, 0x00, 0x00
};
void fwrite16le(ushort val, FILE *f)
{
- ubyte data[2]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff) };
- fwrite(data, 1, 2, f);
+ std::array data{static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff)};
+ fwrite(data.data(), 1, data.size(), f);
}
void fwrite32le(uint val, FILE *f)
{
- ubyte data[4]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff),
- static_cast<ubyte>((val>>16)&0xff), static_cast<ubyte>((val>>24)&0xff) };
- fwrite(data, 1, 4, f);
+ std::array data{static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff),
+ static_cast<ubyte>((val>>16)&0xff), static_cast<ubyte>((val>>24)&0xff)};
+ fwrite(data.data(), 1, data.size(), f);
}
template<al::endian = al::endian::native>
@@ -129,8 +129,6 @@ struct UhjDecoder {
const al::span<FloatBufferLine> OutSamples, const std::size_t SamplesToDo);
void decode2(const float *RESTRICT InSamples, const al::span<FloatBufferLine> OutSamples,
const std::size_t SamplesToDo);
-
- DEF_NEWDEL(UhjDecoder)
};
const PhaseShifterT<UhjDecoder::sFilterDelay*2> PShift{};
@@ -389,7 +387,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Failed to open %s\n", argv[fidx]);
continue;
}
- if(sf_command(infile.get(), SFC_WAVEX_GET_AMBISONIC, NULL, 0) == SF_AMBISONIC_B_FORMAT)
+ if(sf_command(infile.get(), SFC_WAVEX_GET_AMBISONIC, nullptr, 0) == SF_AMBISONIC_B_FORMAT)
{
fprintf(stderr, "%s is already B-Format\n", argv[fidx]);
continue;
@@ -438,7 +436,7 @@ int main(int argc, char **argv)
// 32-bit val, frequency
fwrite32le(static_cast<uint>(ininfo.samplerate), outfile.get());
// 32-bit val, bytes per second
- fwrite32le(static_cast<uint>(ininfo.samplerate)*sizeof(float)*outchans, outfile.get());
+ fwrite32le(static_cast<uint>(ininfo.samplerate)*outchans*uint{sizeof(float)}, outfile.get());
// 16-bit val, frame size
fwrite16le(static_cast<ushort>(sizeof(float)*outchans), outfile.get());
// 16-bit val, bits per sample
@@ -450,7 +448,7 @@ int main(int argc, char **argv)
// 32-bit val, channel mask
fwrite32le(0, outfile.get());
// 16 byte GUID, sub-type format
- fwrite(SUBTYPE_BFORMAT_FLOAT, 1, 16, outfile.get());
+ fwrite(SUBTYPE_BFORMAT_FLOAT.data(), 1, SUBTYPE_BFORMAT_FLOAT.size(), outfile.get());
fputs("data", outfile.get());
fwrite32le(0xFFFFFFFF, outfile.get()); // 'data' header len; filled in at close
@@ -463,9 +461,9 @@ int main(int argc, char **argv)
auto DataStart = ftell(outfile.get());
auto decoder = std::make_unique<UhjDecoder>();
- auto inmem = std::make_unique<float[]>(BufferLineSize*static_cast<uint>(ininfo.channels));
+ auto inmem = std::vector<float>(size_t{BufferLineSize}*static_cast<uint>(ininfo.channels));
auto decmem = al::vector<std::array<float,BufferLineSize>, 16>(outchans);
- auto outmem = std::make_unique<byte4[]>(BufferLineSize*outchans);
+ auto outmem = std::vector<byte4>(size_t{BufferLineSize}*outchans);
/* A number of initial samples need to be skipped to cut the lead-in
* from the all-pass filter delay. The same number of samples need to
@@ -476,21 +474,21 @@ int main(int argc, char **argv)
sf_count_t LeadOut{UhjDecoder::sFilterDelay};
while(LeadOut > 0)
{
- sf_count_t sgot{sf_readf_float(infile.get(), inmem.get(), BufferLineSize)};
+ sf_count_t sgot{sf_readf_float(infile.get(), inmem.data(), BufferLineSize)};
sgot = std::max<sf_count_t>(sgot, 0);
if(sgot < BufferLineSize)
{
const sf_count_t remaining{std::min(BufferLineSize - sgot, LeadOut)};
- std::fill_n(inmem.get() + sgot*ininfo.channels, remaining*ininfo.channels, 0.0f);
+ std::fill_n(inmem.data() + sgot*ininfo.channels, remaining*ininfo.channels, 0.0f);
sgot += remaining;
LeadOut -= remaining;
}
auto got = static_cast<std::size_t>(sgot);
if(ininfo.channels > 2 || use_general)
- decoder->decode(inmem.get(), static_cast<uint>(ininfo.channels), decmem, got);
+ decoder->decode(inmem.data(), static_cast<uint>(ininfo.channels), decmem, got);
else
- decoder->decode2(inmem.get(), decmem, got);
+ decoder->decode2(inmem.data(), decmem, got);
if(LeadIn >= got)
{
LeadIn -= got;
@@ -507,7 +505,7 @@ int main(int argc, char **argv)
}
LeadIn = 0;
- std::size_t wrote{fwrite(outmem.get(), sizeof(byte4)*outchans, got, outfile.get())};
+ std::size_t wrote{fwrite(outmem.data(), sizeof(byte4)*outchans, got, outfile.get())};
if(wrote < got)
{
fprintf(stderr, "Error writing wave data: %s (%d)\n", strerror(errno), errno);
diff --git a/utils/uhjencoder.cpp b/utils/uhjencoder.cpp
index 154a1155..02836181 100644
--- a/utils/uhjencoder.cpp
+++ b/utils/uhjencoder.cpp
@@ -26,14 +26,13 @@
#include <array>
#include <cinttypes>
+#include <cstddef>
#include <cstring>
#include <memory>
-#include <stddef.h>
#include <string>
#include <utility>
#include <vector>
-#include "almalloc.h"
#include "alnumbers.h"
#include "alspan.h"
#include "opthelpers.h"
@@ -82,8 +81,6 @@ struct UhjEncoder {
void encode(const al::span<FloatBufferLine> OutSamples,
const al::span<FloatBufferLine,4> InSamples, const size_t SamplesToDo);
-
- DEF_NEWDEL(UhjEncoder)
};
const PhaseShifterT<UhjEncoder::sFilterDelay*2> PShift{};
@@ -179,50 +176,55 @@ struct SpeakerPos {
};
/* Azimuth is counter-clockwise. */
-constexpr SpeakerPos StereoMap[2]{
- { SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
- { SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
-}, QuadMap[4]{
- { SF_CHANNEL_MAP_LEFT, 45.0f, 0.0f },
- { SF_CHANNEL_MAP_RIGHT, -45.0f, 0.0f },
- { SF_CHANNEL_MAP_REAR_LEFT, 135.0f, 0.0f },
- { SF_CHANNEL_MAP_REAR_RIGHT, -135.0f, 0.0f },
-}, X51Map[6]{
- { SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
- { SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
- { SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f },
- { SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
- { SF_CHANNEL_MAP_SIDE_LEFT, 110.0f, 0.0f },
- { SF_CHANNEL_MAP_SIDE_RIGHT, -110.0f, 0.0f },
-}, X51RearMap[6]{
- { SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
- { SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
- { SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f },
- { SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
- { SF_CHANNEL_MAP_REAR_LEFT, 110.0f, 0.0f },
- { SF_CHANNEL_MAP_REAR_RIGHT, -110.0f, 0.0f },
-}, X71Map[8]{
- { SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
- { SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
- { SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f },
- { SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
- { SF_CHANNEL_MAP_REAR_LEFT, 150.0f, 0.0f },
- { SF_CHANNEL_MAP_REAR_RIGHT, -150.0f, 0.0f },
- { SF_CHANNEL_MAP_SIDE_LEFT, 90.0f, 0.0f },
- { SF_CHANNEL_MAP_SIDE_RIGHT, -90.0f, 0.0f },
-}, X714Map[12]{
- { SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
- { SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
- { SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f },
- { SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
- { SF_CHANNEL_MAP_REAR_LEFT, 150.0f, 0.0f },
- { SF_CHANNEL_MAP_REAR_RIGHT, -150.0f, 0.0f },
- { SF_CHANNEL_MAP_SIDE_LEFT, 90.0f, 0.0f },
- { SF_CHANNEL_MAP_SIDE_RIGHT, -90.0f, 0.0f },
- { SF_CHANNEL_MAP_TOP_FRONT_LEFT, 45.0f, 35.0f },
- { SF_CHANNEL_MAP_TOP_FRONT_RIGHT, -45.0f, 35.0f },
- { SF_CHANNEL_MAP_TOP_REAR_LEFT, 135.0f, 35.0f },
- { SF_CHANNEL_MAP_TOP_REAR_RIGHT, -135.0f, 35.0f },
+constexpr std::array StereoMap{
+ SpeakerPos{SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f},
+};
+constexpr std::array QuadMap{
+ SpeakerPos{SF_CHANNEL_MAP_LEFT, 45.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_RIGHT, -45.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_REAR_LEFT, 135.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_REAR_RIGHT, -135.0f, 0.0f},
+};
+constexpr std::array X51Map{
+ SpeakerPos{SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_LFE, 0.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_SIDE_LEFT, 110.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_SIDE_RIGHT, -110.0f, 0.0f},
+};
+constexpr std::array X51RearMap{
+ SpeakerPos{SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_LFE, 0.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_REAR_LEFT, 110.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_REAR_RIGHT, -110.0f, 0.0f},
+};
+constexpr std::array X71Map{
+ SpeakerPos{SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_LFE, 0.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_REAR_LEFT, 150.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_REAR_RIGHT, -150.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_SIDE_LEFT, 90.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_SIDE_RIGHT, -90.0f, 0.0f},
+};
+constexpr std::array X714Map{
+ SpeakerPos{SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_LFE, 0.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_REAR_LEFT, 150.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_REAR_RIGHT, -150.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_SIDE_LEFT, 90.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_SIDE_RIGHT, -90.0f, 0.0f},
+ SpeakerPos{SF_CHANNEL_MAP_TOP_FRONT_LEFT, 45.0f, 35.0f},
+ SpeakerPos{SF_CHANNEL_MAP_TOP_FRONT_RIGHT, -45.0f, 35.0f},
+ SpeakerPos{SF_CHANNEL_MAP_TOP_REAR_LEFT, 135.0f, 35.0f},
+ SpeakerPos{SF_CHANNEL_MAP_TOP_REAR_RIGHT, -135.0f, 35.0f},
};
constexpr auto GenCoeffs(double x /*+front*/, double y /*+left*/, double z /*+up*/) noexcept
@@ -413,11 +415,11 @@ int main(int argc, char **argv)
}
auto encoder = std::make_unique<UhjEncoder>();
- auto splbuf = al::vector<FloatBufferLine, 16>(static_cast<uint>(9+ininfo.channels)+uhjchans);
- auto ambmem = al::span<FloatBufferLine,4>{splbuf.data(), 4};
- auto encmem = al::span<FloatBufferLine,4>{&splbuf[4], 4};
- auto srcmem = al::span<float,BufferLineSize>{splbuf[8].data(), BufferLineSize};
- auto outmem = al::span<float>{splbuf[9].data(), BufferLineSize*uhjchans};
+ auto splbuf = al::vector<FloatBufferLine, 16>(static_cast<uint>(ininfo.channels)+9+size_t{uhjchans});
+ auto ambmem = al::span{splbuf}.subspan<0,4>();
+ auto encmem = al::span{splbuf}.subspan<4,4>();
+ auto srcmem = al::span{splbuf[8]};
+ auto outmem = al::span<float>{splbuf[9].data(), size_t{BufferLineSize}*uhjchans};
/* A number of initial samples need to be skipped to cut the lead-in
* from the all-pass filter delay. The same number of samples need to