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:
jthedering committed 2017-07-17 19:22:59 +00:00
1 parent 534b63da5f
commit ce857887af
33 files changed
+2146 -14

No files matched your search

+110
View File
@@ -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;
}
}
+55
View File
@@ -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;
};
+401
View File
@@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;For a correct calibration, a sound level meter is required.&lt;br/&gt;These are the steps for calibration of a stereo system:&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Disable loudness correction during measurement&lt;br/&gt;(done automatically while this dialog is open)&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Enable only one speaker (e.g. select left or right channel below)&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Play pink noise at full application volume:&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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:&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The reference level will be set to the Windows volume for which the level at the listening position is 75 dB.&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;After calibration, volume should only be adjusted via Windows volume control&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</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;
};