Added: Loudness correction filter by Alexander Walch that adjusts shelving filters based on the system volume. Also includes a GUI that allows calibration using a test sound.
This commit is contained in:
1 parent
534b63da5f
commit
ce857887af
33 files changed
+2146
-14
No files matched your search
+21
-4
@@ -124,7 +124,14 @@ SOURCES += main.cpp\
|
||||
guis/VSTPluginFilterGUIDialog.cpp \
|
||||
../filters/VSTPluginFilter.cpp \
|
||||
../filters/VSTPluginFilterFactory.cpp \
|
||||
../helpers/VSTPluginInstance.cpp
|
||||
../helpers/VSTPluginInstance.cpp \
|
||||
guis/LoudnessCorrectionFilterGUI.cpp \
|
||||
guis/LoudnessCorrectionFilterGUIFactory.cpp \
|
||||
../filters/loudnessCorrection/LoudnessCorrectionFilter.cpp \
|
||||
../filters/loudnessCorrection/LoudnessCorrectionFilterFactory.cpp \
|
||||
../filters/loudnessCorrection/VolumeController.cpp \
|
||||
guis/LoudnessCorrectionFilterGUIDialog.cpp \
|
||||
helpers/QtSndfileHandle.cpp
|
||||
|
||||
HEADERS += \
|
||||
../helpers/LogHelper.h \
|
||||
@@ -237,7 +244,15 @@ HEADERS += \
|
||||
guis/VSTPluginFilterGUIDialog.h \
|
||||
../filters/VSTPluginFilter.h \
|
||||
../filters/VSTPluginFilterFactory.h \
|
||||
../helpers/VSTPluginInstance.h
|
||||
../helpers/VSTPluginInstance.h \
|
||||
guis/LoudnessCorrectionFilterGUI.h \
|
||||
guis/LoudnessCorrectionFilterGUIFactory.h \
|
||||
../filters/loudnessCorrection/LoudnessCorrectionFilter.h \
|
||||
../filters/loudnessCorrection/LoudnessCorrectionFilterFactory.h \
|
||||
../filters/loudnessCorrection/ParameterArchive.h \
|
||||
../filters/loudnessCorrection/VolumeController.h \
|
||||
guis/LoudnessCorrectionFilterGUIDialog.h \
|
||||
helpers/QtSndfileHandle.h
|
||||
|
||||
FORMS += \
|
||||
guis/PreampFilterGUI.ui \
|
||||
@@ -257,10 +272,12 @@ FORMS += \
|
||||
MainWindow.ui \
|
||||
guis/StageFilterGUI.ui \
|
||||
guis/VSTPluginFilterGUI.ui \
|
||||
guis/VSTPluginFilterGUIDialog.ui
|
||||
guis/VSTPluginFilterGUIDialog.ui \
|
||||
guis/LoudnessCorrectionFilterGUI.ui \
|
||||
guis/LoudnessCorrectionFilterGUIDialog.ui
|
||||
|
||||
INCLUDEPATH += $$PWD/.. "C:/Program Files/libsndfile/include" "C:/Program Files/fftw3" "C:/Program Files/muparserx_v3_0_1/parser"
|
||||
LIBS += user32.lib advapi32.lib version.lib ole32.lib Shlwapi.lib authz.lib crypt32.lib dbghelp.lib libsndfile-1.lib libfftw3f-3.lib
|
||||
LIBS += user32.lib advapi32.lib version.lib ole32.lib Shlwapi.lib authz.lib crypt32.lib dbghelp.lib winmm.lib libsndfile-1.lib libfftw3f-3.lib
|
||||
|
||||
build_pass:CONFIG(debug, debug|release) {
|
||||
LIBS += muparserxd.lib
|
||||
|
||||
@@ -23,5 +23,6 @@
|
||||
<file>icons/normalize_response.ico</file>
|
||||
<file>icons/reset_response.ico</file>
|
||||
<file>icons/resize_corner.ico</file>
|
||||
<file>sounds/pinkNoise.flac</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "guis/GraphicEQFilterGUIFactory.h"
|
||||
#include "guis/ConvolutionFilterGUIFactory.h"
|
||||
#include "guis/VSTPluginFilterGUIFactory.h"
|
||||
#include "guis/LoudnessCorrectionFilterGUIFactory.h"
|
||||
#include "Editor/helpers/DPIHelper.h"
|
||||
#include "helpers/StringHelper.h"
|
||||
#include "helpers/LogHelper.h"
|
||||
@@ -81,6 +82,7 @@ FilterTable::FilterTable(MainWindow* mainWindow, QWidget* parent)
|
||||
factories.append(new GraphicEQFilterGUIFactory);
|
||||
factories.append(new ConvolutionFilterGUIFactory);
|
||||
factories.append(new VSTPluginFilterGUIFactory);
|
||||
factories.append(new LoudnessCorrectionFilterGUIFactory);
|
||||
|
||||
QApplication::instance()->installEventFilter(this);
|
||||
}
|
||||
@@ -594,6 +596,12 @@ void FilterTable::setScrollOffsets(int x, int y)
|
||||
presetScrollY = y;
|
||||
}
|
||||
|
||||
void FilterTable::updateAnalysis()
|
||||
{
|
||||
if (isVisible())
|
||||
mainWindow->startAnalysis();
|
||||
}
|
||||
|
||||
void FilterTable::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
|
||||
@@ -93,6 +93,8 @@ public:
|
||||
void savePreferences();
|
||||
void setScrollOffsets(int x, int y);
|
||||
|
||||
void updateAnalysis();
|
||||
|
||||
signals:
|
||||
void linesChanged();
|
||||
|
||||
|
||||
+1
-1
@@ -52,6 +52,7 @@ public:
|
||||
void save(FilterTable* filterTable, QString path);
|
||||
bool isEmpty();
|
||||
bool shouldRestart();
|
||||
void startAnalysis();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
@@ -93,7 +94,6 @@ private:
|
||||
FilterTable* addTab(QString title, QString tooltip, QString configPath, QList<QString> lines);
|
||||
void getDeviceAndChannelMask(std::shared_ptr<AbstractAPOInfo>* selectedDevice, int* channelMask);
|
||||
bool askForClose(int tabIndex);
|
||||
void startAnalysis();
|
||||
void loadPreferences();
|
||||
void savePreferences();
|
||||
void updateRecentFiles();
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 Jonas Thedering
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "Editor/helpers/DPIHelper.h"
|
||||
#include "LoudnessCorrectionFilterGUIDialog.h"
|
||||
#include "LoudnessCorrectionFilterGUI.h"
|
||||
#include "ui_LoudnessCorrectionFilterGUI.h"
|
||||
|
||||
LoudnessCorrectionFilterGUI::LoudnessCorrectionFilterGUI(float refLevel, float refOffset, float att)
|
||||
: IFilterGUI(),
|
||||
ui(new Ui::LoudnessCorrectionFilterGUI)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->refLevelDial->setFixedSize(DPIHelper::scale(QSize(100, 66)));
|
||||
ui->refOffsetDial->setFixedSize(DPIHelper::scale(QSize(100, 66)));
|
||||
ui->attDial->setFixedSize(DPIHelper::scale(QSize(100, 66)));
|
||||
|
||||
ui->refLevelSpinBox->setValue((int)refLevel);
|
||||
ui->refOffsetSpinBox->setValue((int)refOffset);
|
||||
ui->attSpinBox->setValue(att);
|
||||
|
||||
connect(&timer, SIGNAL(timeout()), this, SLOT(updateVolume()));
|
||||
timer.start(10);
|
||||
}
|
||||
|
||||
LoudnessCorrectionFilterGUI::~LoudnessCorrectionFilterGUI()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUI::store(QString& command, QString& parameters)
|
||||
{
|
||||
command = "LoudnessCorrection";
|
||||
parameters = QString("State %0 ReferenceLevel %1 ReferenceOffset %2 Attenuation ").arg(state ? 1 : 0).arg(ui->refLevelSpinBox->value()).arg(ui->refOffsetSpinBox->value());
|
||||
double att = ui->attSpinBox->value();
|
||||
if (att == 0.0 || att == 1.0)
|
||||
parameters += QString("%0").arg(att, 0, 'f', 1);
|
||||
else
|
||||
parameters += QString("%0").arg(att);
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUI::on_refLevelSpinBox_valueChanged(int value)
|
||||
{
|
||||
emit updateModel();
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUI::on_refOffsetSpinBox_valueChanged(int value)
|
||||
{
|
||||
emit updateModel();
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUI::on_attDial_valueChanged(int value)
|
||||
{
|
||||
ui->attSpinBox->setValue(value / 100.0);
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUI::on_attSpinBox_valueChanged(double value)
|
||||
{
|
||||
bool previousValue = ui->attDial->blockSignals(true);
|
||||
ui->attDial->setValue(round(value * 100.0));
|
||||
ui->attDial->blockSignals(previousValue);
|
||||
|
||||
emit updateModel();
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUI::on_calibrateButton_clicked()
|
||||
{
|
||||
state = false;
|
||||
emit updateModel();
|
||||
|
||||
LoudnessCorrectionFilterGUIDialog dialog;
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
updateVolume();
|
||||
double refLevel = 75.0 - dialog.getMeasuredLevel() + lastVolume;
|
||||
ui->refLevelSpinBox->setValue(refLevel);
|
||||
}
|
||||
|
||||
state = true;
|
||||
emit updateModel();
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUI::updateVolume()
|
||||
{
|
||||
float volume;
|
||||
HRESULT res = volumeController.getVolume(volume);
|
||||
|
||||
if (SUCCEEDED(res) && volume != lastVolume)
|
||||
{
|
||||
ui->volumeSpinBox->setValue(volume);
|
||||
lastVolume = volume;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 Jonas Thedering
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#include "Editor/IFilterGUI.h"
|
||||
#include "filters/loudnessCorrection/VolumeController.h"
|
||||
|
||||
namespace Ui {
|
||||
class LoudnessCorrectionFilterGUI;
|
||||
}
|
||||
|
||||
class LoudnessCorrectionFilterGUI : public IFilterGUI
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LoudnessCorrectionFilterGUI(float refLevel, float refOffset, float att);
|
||||
~LoudnessCorrectionFilterGUI();
|
||||
|
||||
void store(QString& command, QString& parameters) override;
|
||||
|
||||
private slots:
|
||||
void on_refLevelSpinBox_valueChanged(int arg1);
|
||||
void on_refOffsetSpinBox_valueChanged(int arg1);
|
||||
void on_attDial_valueChanged(int value);
|
||||
void on_attSpinBox_valueChanged(double arg1);
|
||||
void on_calibrateButton_clicked();
|
||||
void updateVolume();
|
||||
|
||||
private:
|
||||
Ui::LoudnessCorrectionFilterGUI* ui;
|
||||
bool state = true;
|
||||
QTimer timer;
|
||||
VolumeController volumeController;
|
||||
float lastVolume = -1;
|
||||
};
|
||||
@@ -0,0 +1,401 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LoudnessCorrectionFilterGUI</class>
|
||||
<widget class="QWidget" name="LoudnessCorrectionFilterGUI">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1048</width>
|
||||
<height>66</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="13">
|
||||
<widget class="QDoubleSpinBox" name="volumeSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::NoButtons</enum>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string notr="true"> dB</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-99.989999999999995</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="refLevelLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reference level:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="14">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="13">
|
||||
<widget class="QLabel" name="volumeLabel">
|
||||
<property name="text">
|
||||
<string>Master volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>6</pointsize>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>contributed by
|
||||
Alexander Walch</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignHCenter|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="10">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="5" rowspan="2">
|
||||
<widget class="QDial" name="refOffsetDial">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>66</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>66</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-99</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="9">
|
||||
<widget class="QLabel" name="attLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Attenuation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QSpinBox" name="refLevelSpinBox">
|
||||
<property name="suffix">
|
||||
<string notr="true"> dB</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-999</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="8" rowspan="2">
|
||||
<widget class="QDial" name="attDial">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>66</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>66</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="9">
|
||||
<widget class="QDoubleSpinBox" name="attSpinBox">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QSpinBox" name="refOffsetSpinBox">
|
||||
<property name="suffix">
|
||||
<string notr="true"> dB</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-999</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLabel" name="refOffsetLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reference offset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<widget class="QDial" name="refLevelDial">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>66</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>66</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-99</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Loudness correction:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="11" rowspan="2">
|
||||
<widget class="QPushButton" name="calibrateButton">
|
||||
<property name="text">
|
||||
<string>Calibrate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="12">
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>refLevelDial</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>refLevelSpinBox</receiver>
|
||||
<slot>setValue(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>189</x>
|
||||
<y>43</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>278</x>
|
||||
<y>64</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>refLevelSpinBox</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>refLevelDial</receiver>
|
||||
<slot>setValue(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>278</x>
|
||||
<y>64</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>189</x>
|
||||
<y>43</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>refOffsetDial</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>refOffsetSpinBox</receiver>
|
||||
<slot>setValue(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>384</x>
|
||||
<y>43</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>476</x>
|
||||
<y>64</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>refOffsetSpinBox</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>refOffsetDial</receiver>
|
||||
<slot>setValue(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>476</x>
|
||||
<y>64</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>384</x>
|
||||
<y>43</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<signal>updateModel()</signal>
|
||||
</slots>
|
||||
</ui>
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 Jonas Thedering
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <QFile>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include "Editor/helpers/QtSndfileHandle.h"
|
||||
|
||||
#include "LoudnessCorrectionFilterGUIDialog.h"
|
||||
#include "ui_LoudnessCorrectionFilterGUIDialog.h"
|
||||
|
||||
LoudnessCorrectionFilterGUIDialog::LoudnessCorrectionFilterGUIDialog(QWidget* parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::LoudnessCorrectionFilterGUIDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
LoudnessCorrectionFilterGUIDialog::~LoudnessCorrectionFilterGUIDialog()
|
||||
{
|
||||
on_stopButton_clicked();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
int LoudnessCorrectionFilterGUIDialog::getMeasuredLevel()
|
||||
{
|
||||
return ui->levelSpinBox->value();
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUIDialog::on_playButton_clicked()
|
||||
{
|
||||
if (buffer.size() > 0)
|
||||
on_stopButton_clicked();
|
||||
|
||||
QFile file(":/sounds/pinkNoise.flac");
|
||||
file.open(QIODevice::ReadOnly);
|
||||
QtSndfileHandle fileHandle(file, SFM_READ);
|
||||
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
{
|
||||
QtSndfileHandle bufferHandle(buffer, SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_PCM_24, 2, fileHandle.samplerate());
|
||||
|
||||
bool leftEnabled = ui->leftRadioButton->isChecked() || ui->bothRadioButton->isChecked();
|
||||
bool rightEnabled = ui->rightRadioButton->isChecked() || ui->bothRadioButton->isChecked();
|
||||
|
||||
int buf[1024];
|
||||
int buf2[2 * ARRAYSIZE(buf)];
|
||||
int samplesRead;
|
||||
while ((samplesRead = fileHandle.read(buf, ARRAYSIZE(buf))) > 0)
|
||||
{
|
||||
for (int i = 0; i < samplesRead; i++)
|
||||
{
|
||||
buf2[2 * i] = leftEnabled ? buf[i] : 0;
|
||||
buf2[2 * i + 1] = rightEnabled ? buf[i] : 0;
|
||||
}
|
||||
bufferHandle.write(buf2, 2 * samplesRead);
|
||||
}
|
||||
}
|
||||
buffer.close();
|
||||
|
||||
PlaySoundA(buffer.data().data(), NULL, SND_MEMORY | SND_ASYNC | SND_LOOP);
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUIDialog::on_stopButton_clicked()
|
||||
{
|
||||
if (buffer.size() == 0)
|
||||
return;
|
||||
|
||||
PlaySoundA(NULL, NULL, 0);
|
||||
buffer.buffer().clear();
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUIDialog::on_leftRadioButton_toggled(bool checked)
|
||||
{
|
||||
if (checked && buffer.size() > 0)
|
||||
on_playButton_clicked();
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUIDialog::on_rightRadioButton_toggled(bool checked)
|
||||
{
|
||||
if (checked && buffer.size() > 0)
|
||||
on_playButton_clicked();
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUIDialog::on_bothRadioButton_toggled(bool checked)
|
||||
{
|
||||
if (checked && buffer.size() > 0)
|
||||
on_playButton_clicked();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 Jonas Thedering
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace Ui {
|
||||
class LoudnessCorrectionFilterGUIDialog;
|
||||
}
|
||||
|
||||
class LoudnessCorrectionFilterGUIDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LoudnessCorrectionFilterGUIDialog(QWidget* parent = 0);
|
||||
~LoudnessCorrectionFilterGUIDialog();
|
||||
|
||||
int getMeasuredLevel();
|
||||
|
||||
private slots:
|
||||
void on_playButton_clicked();
|
||||
void on_stopButton_clicked();
|
||||
|
||||
void on_leftRadioButton_toggled(bool checked);
|
||||
void on_rightRadioButton_toggled(bool checked);
|
||||
void on_bothRadioButton_toggled(bool checked);
|
||||
|
||||
private:
|
||||
Ui::LoudnessCorrectionFilterGUIDialog* ui;
|
||||
QBuffer buffer;
|
||||
};
|
||||
@@ -0,0 +1,274 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LoudnessCorrectionFilterGUIDialog</class>
|
||||
<widget class="QDialog" name="LoudnessCorrectionFilterGUIDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>486</width>
|
||||
<height>495</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Calibration</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>For a correct calibration, a sound level meter is required.<br/>These are the steps for calibration of a stereo system:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Disable loudness correction during measurement<br/>(done automatically while this dialog is open)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Enable only one speaker (e.g. select left or right channel below)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Play pink noise at full application volume:</li></ul></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="channelGroupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Channel</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="leftRadioButton">
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rightRadioButton">
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="bothRadioButton">
|
||||
<property name="text">
|
||||
<string>Both</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="4">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="stopButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="playButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Play</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label2">
|
||||
<property name="text">
|
||||
<string><html><head/><body><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Adjust volume via Windows volume control or external volume control (amplifier, etc.) so that the sound level meter shows 75 dB at listening position. If that volume can not be reached, please adjust the following setting:</li></ul></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="levelLabel">
|
||||
<property name="text">
|
||||
<string>Level at listening position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="levelSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> dB</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>75</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label3">
|
||||
<property name="text">
|
||||
<string><html><head/><body><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The reference level will be set to the Windows volume for which the level at the listening position is 75 dB.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">After calibration, volume should only be adjusted via Windows volume control</li></ul></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>LoudnessCorrectionFilterGUIDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>LoudnessCorrectionFilterGUIDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 Jonas Thedering
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "filters/loudnessCorrection/LoudnessCorrectionFilter.h"
|
||||
#include "LoudnessCorrectionFilterGUI.h"
|
||||
#include "LoudnessCorrectionFilterGUIFactory.h"
|
||||
|
||||
LoudnessCorrectionFilterGUIFactory::LoudnessCorrectionFilterGUIFactory()
|
||||
{
|
||||
}
|
||||
|
||||
LoudnessCorrectionFilterGUIFactory::~LoudnessCorrectionFilterGUIFactory()
|
||||
{
|
||||
if (timer != NULL)
|
||||
timer->stop();
|
||||
|
||||
if (volumeController != NULL)
|
||||
{
|
||||
delete volumeController;
|
||||
volumeController = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUIFactory::initialize(FilterTable* filterTable)
|
||||
{
|
||||
this->filterTable = filterTable;
|
||||
}
|
||||
|
||||
QList<FilterTemplate> LoudnessCorrectionFilterGUIFactory::createFilterTemplates()
|
||||
{
|
||||
QList<FilterTemplate> list;
|
||||
list.append(FilterTemplate(tr("Loudness correction"), "LoudnessCorrection: State 1 ReferenceLevel 0 ReferenceOffset 0 Attenuation 1.0", QStringList(tr("Advanced filters"))));
|
||||
return list;
|
||||
}
|
||||
|
||||
IFilterGUI* LoudnessCorrectionFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
|
||||
{
|
||||
LoudnessCorrectionFilterGUI* result = NULL;
|
||||
|
||||
if (command == "LoudnessCorrection")
|
||||
{
|
||||
LoudnessCorrectionFilter::FilterParameters params;
|
||||
if (!params.deSerialize(parameters.toStdWString()))
|
||||
{
|
||||
result = new LoudnessCorrectionFilterGUI(params.referenceLevel, params.referenceOffset, params.attenuation);
|
||||
|
||||
if (timer == NULL)
|
||||
{
|
||||
timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(checkVolume()));
|
||||
timer->start(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LoudnessCorrectionFilterGUIFactory::checkVolume()
|
||||
{
|
||||
if (volumeController == NULL)
|
||||
{
|
||||
volumeController = new VolumeController();
|
||||
volumeController->getVolume(lastVolume);
|
||||
}
|
||||
else
|
||||
{
|
||||
float volume;
|
||||
HRESULT res = volumeController->getVolume(volume);
|
||||
|
||||
if (SUCCEEDED(res) && volume != lastVolume)
|
||||
{
|
||||
filterTable->updateAnalysis();
|
||||
lastVolume = volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 Jonas Thedering
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QTimer>
|
||||
#include "Editor/IFilterGUIFactory.h"
|
||||
#include "Editor/FilterTable.h"
|
||||
#include "filters/loudnessCorrection/VolumeController.h"
|
||||
|
||||
class LoudnessCorrectionFilterGUIFactory : public IFilterGUIFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LoudnessCorrectionFilterGUIFactory();
|
||||
~LoudnessCorrectionFilterGUIFactory();
|
||||
|
||||
void initialize(FilterTable* filterTable) override;
|
||||
QList<FilterTemplate> createFilterTemplates() override;
|
||||
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
|
||||
|
||||
private slots:
|
||||
void checkVolume();
|
||||
|
||||
private:
|
||||
FilterTable* filterTable;
|
||||
QTimer* timer = NULL;
|
||||
VolumeController* volumeController = NULL;
|
||||
float lastVolume = -1;
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 Jonas Thedering
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "QtSndfileHandle.h"
|
||||
|
||||
sf_count_t getFileLenDevice(void* user_data)
|
||||
{
|
||||
QIODevice* device = (QIODevice*)user_data;
|
||||
return device->size();
|
||||
}
|
||||
|
||||
sf_count_t seekDevice(sf_count_t offset, int whence, void* user_data)
|
||||
{
|
||||
QIODevice* device = (QIODevice*)user_data;
|
||||
qint64 pos;
|
||||
if (whence == SF_SEEK_SET)
|
||||
pos = 0;
|
||||
else if (whence == SF_SEEK_CUR)
|
||||
pos = device->pos();
|
||||
else // whence == SF_SEEK_END
|
||||
pos = device->size();
|
||||
if (!device->seek(pos + offset))
|
||||
return -1;
|
||||
return device->pos();
|
||||
}
|
||||
|
||||
sf_count_t readDevice(void* ptr, sf_count_t count, void* user_data)
|
||||
{
|
||||
QIODevice* device = (QIODevice*)user_data;
|
||||
return device->read((char*)ptr, count);
|
||||
}
|
||||
|
||||
sf_count_t writeDevice(const void* ptr, sf_count_t count, void* user_data)
|
||||
{
|
||||
QIODevice* device = (QIODevice*)user_data;
|
||||
return device->write((const char*)ptr, count);
|
||||
}
|
||||
|
||||
sf_count_t tellDevice(void* user_data)
|
||||
{
|
||||
QIODevice* device = (QIODevice*)user_data;
|
||||
return device->pos();
|
||||
}
|
||||
|
||||
SF_VIRTUAL_IO g_deviceIo = {getFileLenDevice, seekDevice, readDevice, writeDevice, tellDevice};
|
||||
|
||||
QtSndfileHandle::QtSndfileHandle(QIODevice& device, int mode, int format, int channels, int samplerate)
|
||||
: SndfileHandle(g_deviceIo, &device, mode, format, channels, samplerate)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 Jonas Thedering
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
|
||||
#include <sndfile.hh>
|
||||
#include <QIODevice>
|
||||
|
||||
class QtSndfileHandle : public SndfileHandle
|
||||
{
|
||||
public:
|
||||
QtSndfileHandle(QIODevice& device, int mode = SFM_READ,
|
||||
int format = 0, int channels = 0, int samplerate = 0);
|
||||
};
|
||||
Binary file not shown.
Binary file not shown.
@@ -661,7 +661,7 @@ Wählen Sie eine andere Datei oder ändern Sie die Konfiguration des Geräts.</t
|
||||
<context>
|
||||
<name>FilterTable</name>
|
||||
<message>
|
||||
<location filename="../FilterTable.cpp" line="214"/>
|
||||
<location filename="../FilterTable.cpp" line="216"/>
|
||||
<source>Add filter</source>
|
||||
<translation>Filter hinzufügen</translation>
|
||||
</message>
|
||||
@@ -897,6 +897,130 @@ Change the file permissions or copy the file to the config directory.</source>
|
||||
<translation>Include (Konfigurationsdatei einbinden)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoudnessCorrectionFilterGUI</name>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUI.ui" line="158"/>
|
||||
<source>Attenuation:</source>
|
||||
<translation>Abschwächung:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUI.ui" line="251"/>
|
||||
<source>Reference offset:</source>
|
||||
<translation>Referenzversatz:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUI.ui" line="73"/>
|
||||
<source>Reference level:</source>
|
||||
<translation>Referenzpegel:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source> dB</source>
|
||||
<translation type="obsolete"> dB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUI.ui" line="93"/>
|
||||
<source>Master volume:</source>
|
||||
<translation>Gesamtlautstärke:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUI.ui" line="106"/>
|
||||
<source>contributed by
|
||||
Alexander Walch</source>
|
||||
<translation>beigetragen durch
|
||||
Alexander Walch</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUI.ui" line="299"/>
|
||||
<source>Loudness correction:</source>
|
||||
<translation>Lautheitskorrektur:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUI.ui" line="309"/>
|
||||
<source>Calibrate</source>
|
||||
<translation>Kalibrieren</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoudnessCorrectionFilterGUIDialog</name>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="14"/>
|
||||
<source>Calibration</source>
|
||||
<translation>Kalibrierung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p>For a correct calibration, a sound level meter is required.<br/>These are the steps for calibration of a stereo system:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Disable loudness equalization during measurement<br/>(done automatically while this dialog is open)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Enable only one speaker (e.g. select left or right channel below)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Play pink noise at full application volume:</li></ul></body></html></source>
|
||||
<translation type="vanished"><html><head/><body><p>Für eine korrekte Kalibrierung wird ein Schallpegelmesser benötigt.<br/>Dies sind die Schritte für die Kalibrierung eines Stereosystems:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Lautheitskorrektur während der Messung deaktivieren<br/>(geschieht automatisch, während dieser Dialog geöffnet ist)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Nur einen Lautsprecher aktivieren (z.B. linken oder rechten Kanal unten wählen)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Rosa Rauschen bei voller Anwendungslautstärke abspielen:</li></ul></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="20"/>
|
||||
<source><html><head/><body><p>For a correct calibration, a sound level meter is required.<br/>These are the steps for calibration of a stereo system:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Disable loudness correction during measurement<br/>(done automatically while this dialog is open)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Enable only one speaker (e.g. select left or right channel below)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Play pink noise at full application volume:</li></ul></body></html></source>
|
||||
<translation><html><head/><body><p>Für eine korrekte Kalibrierung wird ein Schallpegelmesser benötigt.<br/>Dies sind die Schritte für die Kalibrierung eines Stereosystems:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Lautheitskorrektur während der Messung deaktivieren<br/>(geschieht automatisch, während dieser Dialog geöffnet ist)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Nur einen Lautsprecher aktivieren (z.B. linken oder rechten Kanal unten wählen)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Rosa Rauschen bei voller Anwendungslautstärke abspielen:</li></ul></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="44"/>
|
||||
<source>Channel</source>
|
||||
<translation>Kanal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="50"/>
|
||||
<source>Left</source>
|
||||
<translation>Links</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="60"/>
|
||||
<source>Right</source>
|
||||
<translation>Rechts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="67"/>
|
||||
<source>Both</source>
|
||||
<translation>Beide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="100"/>
|
||||
<source>Stop</source>
|
||||
<translation>Stopp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="126"/>
|
||||
<source>Play</source>
|
||||
<translation>Abspielen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="135"/>
|
||||
<source><html><head/><body><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Adjust volume via Windows volume control or external volume control (amplifier, etc.) so that the sound level meter shows 75 dB at listening position. If that volume can not be reached, please adjust the following setting:</li></ul></body></html></source>
|
||||
<translation><html><head/><body><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Lautstärke über die Windows-Lautstärkeregelung oder externe Lautstärkeregelung (Verstärker, usw.) anpassen, sodass der Schallpegelmesser am Hörplatz 75 dB anzeigt. Wenn diese Lautstärke nicht erreicht werden kann, bitte die folgende Einstellung anpassen:</li></ul></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="163"/>
|
||||
<source>Level at listening position:</source>
|
||||
<translation>Pegel am Hörplatz:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="176"/>
|
||||
<source> dB</source>
|
||||
<translation> dB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIDialog.ui" line="204"/>
|
||||
<source><html><head/><body><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The reference level will be set to the Windows volume for which the level at the listening position is 75 dB.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">After calibration, volume should only be adjusted via Windows volume control</li></ul></body></html></source>
|
||||
<translation><html><head/><body><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Der Referenzpegel wird auf die Windows-Lautstärke gesetzt, bei der der Pegel am Hörplatz 75 dB beträgt.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Nach der Kalibrierung sollte die Lautstärke nur noch über die Windows-Lautstärkeregelung verändert werden</li></ul></body></html></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoudnessCorrectionFilterGUIFactory</name>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIFactory.cpp" line="48"/>
|
||||
<source>Loudness correction</source>
|
||||
<translation>Lautheitskorrektur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/LoudnessCorrectionFilterGUIFactory.cpp" line="48"/>
|
||||
<source>Advanced filters</source>
|
||||
<translation>Fortgeschrittene Filter</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
|
||||
Reference in new issue
Block a user