From a89f64900952a9c22d233db72e4c7b7d496b2857 Mon Sep 17 00:00:00 2001
From: jthedering <51533355+jthedering@users.noreply.github.com>
Date: Mon, 4 Nov 2013 21:46:39 +0000
Subject: [PATCH] Version 0.8.1 Fixed: Windows 8.1 is now supported. Added:
Filter types LSC and HSC that allow specifying the shelf slope with center
frequency, unlike LS/HS 6/12db which use corner frequency.
---
Benchmark/Benchmark.cpp | 8 +-
Benchmark/Benchmark.vcxproj | 2 +-
Configurator/Configurator.cpp | 41 ++++++++--
Configurator/Configurator.rc | Bin 14010 -> 14594 bytes
Configurator/resource.h | Bin 3882 -> 4062 bytes
DeviceAPOInfo.cpp | 140 ++++++++++++++++++++++++----------
DeviceAPOInfo.h | 7 ++
EqualizerAPO.rc | Bin 4814 -> 4898 bytes
EqualizerAPO64.rc | Bin 4814 -> 4898 bytes
ParametricEQ.cpp | 17 +++--
RegistryHelper.cpp | 23 ++++++
RegistryHelper.h | 1 +
Setup/Setup.nsi | 12 ++-
Setup/Setup32.nsi | 2 +-
Setup/Setup64.nsi | 2 +-
Wiki/Documentation.txt | 18 ++---
version.h | 1 +
17 files changed, 205 insertions(+), 69 deletions(-)
diff --git a/Benchmark/Benchmark.cpp b/Benchmark/Benchmark.cpp
index 07f753e..5360e7d 100644
--- a/Benchmark/Benchmark.cpp
+++ b/Benchmark/Benchmark.cpp
@@ -38,6 +38,8 @@ int main(int argc, char** argv)
{
stringstream versionStream;
versionStream << MAJOR << "." << MINOR;
+ if(REVISION != 0)
+ versionStream << "." << REVISION;
TCLAP::CmdLine cmd("Benchmark generates a linear sine sweep or reads from the given input file. "
"It then filters the waveform using the Equalizer APO filter configuration "
"and finally writes to the given file or into the user's temp directory.", ' ', versionStream.str());
@@ -67,7 +69,11 @@ int main(int argc, char** argv)
float length;
float* buf;
- printf("Benchmark %d.%d\n", MAJOR, MINOR);
+ if(REVISION == 0)
+ printf("Benchmark %d.%d\n", MAJOR, MINOR);
+ else
+ printf("Benchmark %d.%d.%d\n", MAJOR, MINOR, REVISION);
+
printf("Run \"%s -h\" to show usage info\n", argv[0]);
printf("\n");
diff --git a/Benchmark/Benchmark.vcxproj b/Benchmark/Benchmark.vcxproj
index dedaa40..730d66b 100644
--- a/Benchmark/Benchmark.vcxproj
+++ b/Benchmark/Benchmark.vcxproj
@@ -70,7 +70,7 @@
true
C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)
- C:\Program Files\libsndfile\lib;$(LibraryPath)
+ C:\Program Files\libsndfile\lib64;$(LibraryPath)
false
diff --git a/Configurator/Configurator.cpp b/Configurator/Configurator.cpp
index 0732560..58a4663 100644
--- a/Configurator/Configurator.cpp
+++ b/Configurator/Configurator.cpp
@@ -109,13 +109,13 @@ void Configurator::onInitDialog(HWND hDlg)
if(it->isInstalled)
{
ListView_SetCheckState(deviceList, itemCount, TRUE);
- if(!it->isInput && it->isLFX)
+ if(it->canBeUpgraded())
LoadStringW(hInstance, IDS_WILL_BE_UPGRADED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
else
LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
ListView_SetItemText(deviceList, itemCount, 2, stringBuf);
}
- else if(it->originalApoGuid == APOGUID_NOKEY)
+ else if(it->isExperimental())
{
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED_EXPERIMENTAL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
ListView_SetItemText(deviceList, itemCount, 2, stringBuf);
@@ -156,11 +156,11 @@ void Configurator::onLvnItemChanged(unsigned sourceId, LPNMLISTVIEW info)
LoadStringW(hInstance, IDS_WILL_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
else if(!checked && apoInfo.isInstalled)
LoadStringW(hInstance, IDS_WILL_BE_UNINSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
- else if(apoInfo.isInstalled && !apoInfo.isInput && apoInfo.isLFX)
+ else if(apoInfo.isInstalled && apoInfo.canBeUpgraded())
LoadStringW(hInstance, IDS_WILL_BE_UPGRADED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
else if(apoInfo.isInstalled)
LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
- else if(apoInfo.originalApoGuid == APOGUID_NOKEY)
+ else if(apoInfo.isExperimental())
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED_EXPERIMENTAL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
else
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
@@ -196,7 +196,7 @@ bool Configurator::onButtonClicked(unsigned sourceId)
info.install();
else if(!ListView_GetCheckState(deviceList, i) && info.isInstalled)
info.uninstall();
- else if(ListView_GetCheckState(deviceList, i) && !info.isInput && info.isLFX)
+ else if(ListView_GetCheckState(deviceList, i) && info.canBeUpgraded())
{
info.uninstall();
info.load(info.deviceGuid);
@@ -269,6 +269,33 @@ bool Configurator::onButtonClicked(unsigned sourceId)
LoadStringW(hInstance, IDS_AFTERINSTALL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
MessageBoxW(hDlg, stringBuf, L"Info", MB_ICONINFORMATION | MB_OK);
}
+ else if(sourceId == IDOK)
+ {
+ wchar_t captionBuf[255];
+ LoadStringW(hInstance, IDS_SHOULD_REBOOT_CAPTION, captionBuf, sizeof(captionBuf)/sizeof(wchar_t));
+ wchar_t stringBuf[255];
+ LoadStringW(hInstance, IDS_SHOULD_REBOOT, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
+ if(MessageBoxW(hDlg, stringBuf, captionBuf, MB_ICONQUESTION | MB_YESNO) == IDYES)
+ {
+ HANDLE tokenHandle;
+ if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenHandle))
+ {
+ LUID luid;
+ if(LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid))
+ {
+ TOKEN_PRIVILEGES tp;
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if(AdjustTokenPrivileges(tokenHandle, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
+ InitiateShutdownW(NULL, NULL, 0, SHUTDOWN_RESTART | SHUTDOWN_GRACE_OVERRIDE, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE);
+ }
+
+ CloseHandle(tokenHandle);
+ }
+ }
+ }
return true;
}
@@ -304,7 +331,7 @@ bool Configurator::isChanged()
item.mask = LVIF_PARAM;
ListView_GetItem(deviceList, &item);
if((ListView_GetCheckState(deviceList, i) != 0) != apoInfos[index][item.lParam].isInstalled
- || ListView_GetCheckState(deviceList, i) && apoInfos[index][item.lParam].isInstalled && !apoInfos[index][item.lParam].isInput && apoInfos[index][item.lParam].isLFX)
+ || ListView_GetCheckState(deviceList, i) && apoInfos[index][item.lParam].isInstalled && apoInfos[index][item.lParam].canBeUpgraded())
{
changed = true;
break;
@@ -330,7 +357,7 @@ bool Configurator::hasUpgrades()
item.iSubItem = 0;
item.mask = LVIF_PARAM;
ListView_GetItem(deviceList, &item);
- if(ListView_GetCheckState(deviceList, i) && apoInfos[index][item.lParam].isInstalled && !apoInfos[index][item.lParam].isInput && apoInfos[index][item.lParam].isLFX)
+ if(ListView_GetCheckState(deviceList, i) && apoInfos[index][item.lParam].isInstalled && apoInfos[index][item.lParam].canBeUpgraded())
{
hasUpgrades = true;
break;
diff --git a/Configurator/Configurator.rc b/Configurator/Configurator.rc
index 13de4b368c07e73632e144befa7ced3673dab231..9557b0712bbb8f491ddfa98abbbc28d2b523d018 100644
GIT binary patch
delta 491
zcmb7AJ!=9%5PiL!hl)ku5UV7_pCE{W1W`~!O7RN~-0g+i6VXO4mHqw&djoc<{a?wO
z5hNB0GO#=I=Dpc{^Amo>-&@aZ%h^p69lW81ItJ*Xfg0-$`tUEJL{3O#f)7l2A7PkJ
z5o5t@#>@~M@>~;HYAt<(XW|wS0!Bi_$2(_;IwH?D2^hi)9b!ota;Oj!c4Sbj4;j3$
zepP&}y_4#!aKG7yVh>mBxcy_!YwJ5_1uJt%y|8fC9{T*ZIQ?Vvl8=$9VxA*JB{szMM16KopklHgSyk1gqmX1Zs%0ZBOrUH||9
diff --git a/Configurator/resource.h b/Configurator/resource.h
index 1478dae9555af9277c00591392f74f1041822c3d..e0b3da184d7b174c296001c6649ac2b898d65b5b 100644
GIT binary patch
delta 101
zcmZ1_cTavp3fJTVEG&}23?2;r4517@3@!}u3_%R83{F74KSRjmgG`FdCJg428ChlV
fsM6+=p2Wz)YRF*1U@_T{NpkW5E|$$1T!&ZyUN;p*
delta 16
Ycmca7ze;XH3fJTd+$@`AxDT-a068lK_5c6?
diff --git a/DeviceAPOInfo.cpp b/DeviceAPOInfo.cpp
index 8f274b3..3017a4c 100644
--- a/DeviceAPOInfo.cpp
+++ b/DeviceAPOInfo.cpp
@@ -35,7 +35,12 @@ static const wchar_t* connectionValueName = L"{a45c254e-df1c-4efd-8020-67d146a85
static const wchar_t* deviceValueName = L"{b3f8fa53-0004-438e-9003-51a46e139bfc},6";
static const wchar_t* lfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},1";
static const wchar_t* gfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},2";
+static const wchar_t* lfxGuidValueName2 = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},5";
+static const wchar_t* gfxGuidValueName2 = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},6";
static const wchar_t* fxTitleValueName = L"{b725f130-47ef-101a-a5f1-02608c9eebac},10";
+static const wchar_t* sfxProcessingModesValueName = L"{d3993a3f-99c2-4402-b5ec-a92a0367664b},5";
+static const wchar_t* mfxProcessingModesValueName = L"{d3993a3f-99c2-4402-b5ec-a92a0367664b},6";
+static const wchar_t* defaultProcessingModeValue = L"{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}";
vector DeviceAPOInfo::loadAllInfos(bool input)
{
@@ -77,6 +82,9 @@ bool DeviceAPOInfo::load(const wstring& deviceGuid)
deviceName = RegistryHelper::readValue(keyPath + L"\\Properties", deviceValueName);
isInstalled = false;
+ isLFX = false;
+ isAPO2 = false;
+ foundAPO2Values = false;
if(!RegistryHelper::keyExists(keyPath + L"\\FxProperties"))
{
@@ -84,51 +92,58 @@ bool DeviceAPOInfo::load(const wstring& deviceGuid)
}
else
{
- if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", lfxGuidValueName))
+ originalApoGuid = APOGUID_NOVALUE;
+
+ bool found = tryAPOGuid(keyPath, lfxGuidValueName, true, false);
+ if(!found)
+ found = tryAPOGuid(keyPath, gfxGuidValueName, false, false);
+ if(!found)
+ found = tryAPOGuid(keyPath, lfxGuidValueName2, true, true);
+ if(!found)
+ found = tryAPOGuid(keyPath, gfxGuidValueName2, false, true);
+
+ foundAPO2Values = RegistryHelper::valueExists(keyPath + L"\\FxProperties", lfxGuidValueName2)
+ || RegistryHelper::valueExists(keyPath + L"\\FxProperties", gfxGuidValueName2);
+
+ if(found)
{
- originalApoGuid = RegistryHelper::readValue(keyPath + L"\\FxProperties", lfxGuidValueName);
-
- GUID apoGuid;
- if(!SUCCEEDED(CLSIDFromString(originalApoGuid.c_str(), &apoGuid)))
- return false;
-
- if(apoGuid == __uuidof(EqualizerAPO))
- {
- isInstalled = true;
- isLFX = true;
- }
+ if(RegistryHelper::valueExists(APP_REGPATH L"\\Child APOs", deviceGuid))
+ originalApoGuid = RegistryHelper::readValue(APP_REGPATH L"\\Child APOs", deviceGuid);
}
- else if(isInput)
+ else
{
- originalApoGuid = APOGUID_NOVALUE;
- }
-
- if(!isInput && !isInstalled)
- {
- if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", gfxGuidValueName))
+ wstring guidValueName;
+ if(isInput)
{
- originalApoGuid = RegistryHelper::readValue(keyPath + L"\\FxProperties", gfxGuidValueName);
-
- GUID apoGuid;
- if(!SUCCEEDED(CLSIDFromString(originalApoGuid.c_str(), &apoGuid)))
- return false;
-
- if(apoGuid == __uuidof(EqualizerAPO))
- {
- isInstalled = true;
- isLFX = false;
- }
+ guidValueName = lfxGuidValueName;
+ if(foundAPO2Values)
+ guidValueName = lfxGuidValueName2;
}
else
{
- originalApoGuid = APOGUID_NOVALUE;
+ guidValueName = gfxGuidValueName;
+ if(foundAPO2Values)
+ guidValueName = gfxGuidValueName2;
}
+
+ if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", guidValueName))
+ originalApoGuid = RegistryHelper::readValue(keyPath + L"\\FxProperties", guidValueName);
}
}
return true;
}
+bool DeviceAPOInfo::canBeUpgraded()
+{
+ return isInstalled && (!isInput && isLFX || !isAPO2 && foundAPO2Values);
+}
+
+bool DeviceAPOInfo::isExperimental()
+{
+ return !isInstalled && originalApoGuid == APOGUID_NOKEY;
+}
+
void DeviceAPOInfo::install()
{
RegistryHelper::createKey(APP_REGPATH L"\\Child APOs");
@@ -141,11 +156,15 @@ void DeviceAPOInfo::install()
{
keyPath = captureKeyPath L"\\" + deviceGuid;
guidValueName = lfxGuidValueName;
+ if(foundAPO2Values)
+ guidValueName = lfxGuidValueName2;
}
else
{
keyPath = renderKeyPath L"\\" + deviceGuid;
guidValueName = gfxGuidValueName;
+ if(foundAPO2Values)
+ guidValueName = gfxGuidValueName2;
}
if(originalApoGuid == APOGUID_NOKEY)
@@ -164,6 +183,8 @@ void DeviceAPOInfo::install()
}
RegistryHelper::writeValue(keyPath + L"\\FxProperties", fxTitleValueName, L"Equalizer APO");
+ RegistryHelper::writeMultiValue(keyPath + L"\\FxProperties", sfxProcessingModesValueName, defaultProcessingModeValue);
+ RegistryHelper::writeMultiValue(keyPath + L"\\FxProperties", mfxProcessingModesValueName, defaultProcessingModeValue);
}
else if(originalApoGuid != APOGUID_NOVALUE)
{
@@ -176,25 +197,64 @@ void DeviceAPOInfo::install()
void DeviceAPOInfo::uninstall()
{
- wstring originalChildApoGuid = RegistryHelper::readValue(APP_REGPATH L"\\Child APOs", deviceGuid);
-
wstring keyPath;
if(!isInput)
keyPath = renderKeyPath L"\\" + deviceGuid;
else
keyPath = captureKeyPath L"\\" + deviceGuid;
- if(originalChildApoGuid == APOGUID_NOKEY)
+ if(originalApoGuid == APOGUID_NOKEY)
+ {
RegistryHelper::deleteKey(keyPath + L"\\FxProperties");
- else if(originalChildApoGuid == APOGUID_NOVALUE)
- RegistryHelper::deleteValue(keyPath + L"\\FxProperties", isLFX ? lfxGuidValueName : gfxGuidValueName);
- else if(isLFX)
- RegistryHelper::writeValue(keyPath + L"\\FxProperties", lfxGuidValueName, originalChildApoGuid);
+ }
else
- RegistryHelper::writeValue(keyPath + L"\\FxProperties", gfxGuidValueName, originalChildApoGuid);
+ {
+ wstring guidValueName;
+ if(isLFX)
+ {
+ guidValueName = lfxGuidValueName;
+ if(isAPO2)
+ guidValueName = lfxGuidValueName2;
+ }
+ else
+ {
+ guidValueName = gfxGuidValueName;
+ if(isAPO2)
+ guidValueName = gfxGuidValueName2;
+ }
- RegistryHelper::deleteValue(APP_REGPATH L"\\Child APOs", deviceGuid);
+ if(originalApoGuid == APOGUID_NOVALUE)
+ RegistryHelper::deleteValue(keyPath + L"\\FxProperties", guidValueName);
+ else
+ RegistryHelper::writeValue(keyPath + L"\\FxProperties", guidValueName, originalApoGuid);
+ }
+
+ if(RegistryHelper::valueExists(APP_REGPATH L"\\Child APOs", deviceGuid))
+ RegistryHelper::deleteValue(APP_REGPATH L"\\Child APOs", deviceGuid);
if(RegistryHelper::valueCount(APP_REGPATH L"\\Child APOs") == 0)
RegistryHelper::deleteKey(APP_REGPATH L"\\Child APOs");
}
+
+bool DeviceAPOInfo::tryAPOGuid(const wstring& keyPath, const wchar_t* valueName, bool lfx, bool apo2)
+{
+ if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", valueName))
+ {
+ wstring apoGuidString = RegistryHelper::readValue(keyPath + L"\\FxProperties", valueName);
+
+ GUID apoGuid;
+ if(SUCCEEDED(CLSIDFromString(apoGuidString.c_str(), &apoGuid)))
+ {
+ if(apoGuid == __uuidof(EqualizerAPO))
+ {
+ isInstalled = true;
+ isLFX = lfx;
+ isAPO2 = apo2;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/DeviceAPOInfo.h b/DeviceAPOInfo.h
index 34ec5df..bf65b5c 100644
--- a/DeviceAPOInfo.h
+++ b/DeviceAPOInfo.h
@@ -31,6 +31,8 @@ class DeviceAPOInfo
public:
static std::vector loadAllInfos(bool input);
bool load(const std::wstring& deviceGuid);
+ bool canBeUpgraded();
+ bool isExperimental();
void install();
void uninstall();
@@ -41,4 +43,9 @@ public:
bool isInput;
bool isInstalled;
bool isLFX;
+ bool isAPO2;
+ bool foundAPO2Values;
+
+private:
+ bool tryAPOGuid(const std::wstring& keyPath, const wchar_t* valueName, bool lfx, bool apo2);
};
diff --git a/EqualizerAPO.rc b/EqualizerAPO.rc
index 729f6efd0c9815c7915894f6e8cff35c71088aad..84281fcb27988cf857461b2827bda6b58fcde504 100644
GIT binary patch
delta 118
zcmX@7x=3w<2`7ILgDXQAgC|2U5c@OuO*Z9pL>Jp!&iRsQavvXuD4JphO$G%9rOk;v
V?s%jpC-O*7zQ!lC`5NC3W&qiG8NdJl
delta 50
zcmZ3ac20GJ2`8h$WM@uCRs#kd27}2DIVCr5;5@?w$Nmrs=i
E0C3(8WdHyG
diff --git a/EqualizerAPO64.rc b/EqualizerAPO64.rc
index 3a11b3b3a56cf35ea9f2cd2afdbaa90b7af338f9..61585022d6087fdf6097dafd1f8f00a84b1eabdb 100644
GIT binary patch
delta 118
zcmX@7x=3w<2`7ILgDXQAgC|2U5c@OuO*Z9pL>Jp!&iRsQavvXuD4JphO$G%9rOk;v
V?s%jpC-O*7zQ!lC`5NC3W&qiG8NdJl
delta 50
zcmZ3ac20GJ2`8h$WM@uCRs#kd27}2DIVCr5;5@?w$Nmrs=i
E0C3(8WdHyG
diff --git a/ParametricEQ.cpp b/ParametricEQ.cpp
index 201238b..0d7c46c 100644
--- a/ParametricEQ.cpp
+++ b/ParametricEQ.cpp
@@ -81,6 +81,8 @@ ParametricEQ::ParametricEQ()
filterNameToTypeMap[L"BP"] = BiQuad::BAND_PASS;
filterNameToTypeMap[L"LS"] = BiQuad::LOW_SHELF;
filterNameToTypeMap[L"HS"] = BiQuad::HIGH_SHELF;
+ filterNameToTypeMap[L"LSC"] = BiQuad::LOW_SHELF;
+ filterNameToTypeMap[L"HSC"] = BiQuad::HIGH_SHELF;
filterNameToTypeMap[L"NO"] = BiQuad::NOTCH;
filterNameToTypeMap[L"AP"] = BiQuad::ALL_PASS;
@@ -517,12 +519,15 @@ void ParametricEQ::loadConfig(const wstring& path, vector selectedChannels
{
// Maximum S is 1 for 12 dB
bandwidthOrQOrS /= 12.0f;
- // frequency adjustment for DCX2496
- float centerFreqFactor = pow(10.0f, abs(gain) / 80.0f / bandwidthOrQOrS);
- if(type == BiQuad::LOW_SHELF)
- freq *= centerFreqFactor;
- else
- freq /= centerFreqFactor;
+ if(typeString[typeString.length()-1] != L'C')
+ {
+ // frequency adjustment for DCX2496
+ float centerFreqFactor = pow(10.0f, abs(gain) / 80.0f / bandwidthOrQOrS);
+ if(type == BiQuad::LOW_SHELF)
+ freq *= centerFreqFactor;
+ else
+ freq /= centerFreqFactor;
+ }
}
if(!error)
diff --git a/RegistryHelper.cpp b/RegistryHelper.cpp
index 5c58352..88dce56 100644
--- a/RegistryHelper.cpp
+++ b/RegistryHelper.cpp
@@ -131,6 +131,29 @@ void RegistryHelper::writeValue(wstring key, wstring valuename, wstring value)
throw RegistryException(L"Error while writing to registry value HKEY_LOCAL_MACHINE\\" + key + L"\\" + valuename + L": " + getSystemErrorString(status));
}
+void RegistryHelper::writeMultiValue(wstring key, wstring valuename, wstring value)
+{
+ LSTATUS status;
+ HKEY keyHandle;
+ status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_SET_VALUE | KEY_WOW64_64KEY, &keyHandle);
+ if(status != ERROR_SUCCESS)
+ throw RegistryException(L"Error while opening registry key HKEY_LOCAL_MACHINE\\" + key + L": " + getSystemErrorString(status));
+
+ wchar_t* data = new wchar_t[value.size() + 2];
+ value._Copy_s(data, (value.size()+2)*sizeof(wchar_t), value.size());
+ data[value.size()] = L'\0';
+ data[value.size()+1] = L'\0';
+
+ status = RegSetValueExW(keyHandle, valuename.c_str(), 0, REG_MULTI_SZ, (const BYTE*)data, (DWORD)((value.size()+2)*sizeof(wchar_t)));
+
+ delete data;
+
+ RegCloseKey(keyHandle);
+
+ if(status != ERROR_SUCCESS)
+ throw RegistryException(L"Error while writing to registry value HKEY_LOCAL_MACHINE\\" + key + L"\\" + valuename + L": " + getSystemErrorString(status));
+}
+
void RegistryHelper::deleteValue(wstring key, wstring valuename)
{
LSTATUS status;
diff --git a/RegistryHelper.h b/RegistryHelper.h
index 434f9d0..78c00f0 100644
--- a/RegistryHelper.h
+++ b/RegistryHelper.h
@@ -31,6 +31,7 @@ public:
static std::wstring readValue(std::wstring key, std::wstring valuename);
static unsigned long readDWORDValue(std::wstring key, std::wstring valuename);
static void writeValue(std::wstring key, std::wstring valuename, std::wstring value);
+ static void writeMultiValue(std::wstring key, std::wstring valuename, std::wstring value);
static void deleteValue(std::wstring key, std::wstring valuename);
static void createKey(std::wstring key);
static void deleteKey(std::wstring key);
diff --git a/Setup/Setup.nsi b/Setup/Setup.nsi
index 9f4eea0..a05be2e 100644
--- a/Setup/Setup.nsi
+++ b/Setup/Setup.nsi
@@ -5,6 +5,12 @@
!searchparse /file ..\version.h `#define MAJOR ` MAJOR
!searchparse /file ..\version.h `#define MINOR ` MINOR
+!searchparse /file ..\version.h `#define REVISION ` REVISION
+!if ${REVISION} == 0
+!define VERSION ${MAJOR}.${MINOR}
+!else
+!define VERSION ${MAJOR}.${MINOR}.${REVISION}
+!endif
!define REGPATH "Software\EqualizerAPO"
!define UNINST_REGPATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\EqualizerAPO"
@@ -13,7 +19,7 @@
;General
;Name and file
- Name "Equalizer APO ${MAJOR}.${MINOR}"
+ Name "Equalizer APO ${VERSION}"
;Request application privileges for Windows Vista
RequestExecutionLevel admin
@@ -80,7 +86,7 @@ Function .onInit
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
;Try to replace version number in start menu folder
- ${REReplace} $0 "Equalizer APO [0-9]+\.[0-9]+" "$StartMenuFolder" "Equalizer APO ${MAJOR}.${MINOR}" 1
+ ${REReplace} $0 "Equalizer APO [0-9]+\.[0-9]+(?:\.[0-9]+)?" "$StartMenuFolder" "Equalizer APO ${VERSION}" 1
StrCmp $0 "" +2 0
StrCpy $StartMenuFolder "$0"
@@ -141,7 +147,7 @@ Section "Install" SecInstall
!insertmacro MUI_STARTMENU_WRITE_END
WriteRegStr HKLM ${UNINST_REGPATH} "DisplayName" "Equalizer APO"
- WriteRegStr HKLM ${UNINST_REGPATH} "DisplayVersion" "${MAJOR}.${MINOR}"
+ WriteRegStr HKLM ${UNINST_REGPATH} "DisplayVersion" "${VERSION}"
WriteRegStr HKLM ${UNINST_REGPATH} "UninstallString" '"$INSTDIR\Uninstall.exe"'
WriteRegDWORD HKLM ${UNINST_REGPATH} "NoModify" 1
WriteRegDWORD HKLM ${UNINST_REGPATH} "NoRepair" 1
diff --git a/Setup/Setup32.nsi b/Setup/Setup32.nsi
index 0a3b936..bc5fa01 100644
--- a/Setup/Setup32.nsi
+++ b/Setup/Setup32.nsi
@@ -13,4 +13,4 @@ Function initCheck
Abort
FunctionEnd
-OutFile "EqualizerAPO32-${MAJOR}.${MINOR}.exe"
+OutFile "EqualizerAPO32-${VERSION}.exe"
diff --git a/Setup/Setup64.nsi b/Setup/Setup64.nsi
index 89317ff..2a94fc2 100644
--- a/Setup/Setup64.nsi
+++ b/Setup/Setup64.nsi
@@ -13,4 +13,4 @@ Function initCheck
Abort
FunctionEnd
-OutFile "EqualizerAPO64-${MAJOR}.${MINOR}.exe"
+OutFile "EqualizerAPO64-${VERSION}.exe"
diff --git a/Wiki/Documentation.txt b/Wiki/Documentation.txt
index 956de82..bff0411 100644
--- a/Wiki/Documentation.txt
+++ b/Wiki/Documentation.txt
@@ -57,16 +57,16 @@ Example:
Preamp: -5 dB
#Filters only for left channel
Include: demo.txt
- Filter 3: ON LS Fc 300 Hz Gain 5.0 dB
+ Filter 1: ON LS Fc 300 Hz Gain 5.0 dB
Channel: 2 C
#Filters for second(right) and center channel
- Filter 4: ON HP Fc 30 Hz
- Filter 5: ON LPQ Fc 10000 Hz Q 0.400
+ Filter 1: ON HP Fc 30 Hz
+ Filter 2: ON LPQ Fc 10000 Hz Q 0.400
Device: Microphone
#From here, the lines only apply to microphone devices
- Filter 1: ON NO Fc 50 Hz
+ Filter: ON NO Fc 50 Hz
The commands currently defined are:
@@ -74,8 +74,8 @@ Command | Parameters | Description
-|-|-
Preamp | ***Negative number*** dB | Sets a preamplification value in decibels. This is useful when you are using filters with positive gain, to make sure that no clipping occurs. Since version 0.8, when multiple preamps apply to the same channel, the resulting preamp is the sum in dB.
Include | ***File name*** | Loads the given file as a configuration file. Instead of directly replacing config.txt, it can be better to load the actual filter definition from a separate file so that you can e.g. set a preamp before.
-Filter ***n*** | ON ***Type*** Fc ***Frequency*** Hz Gain ***Gain value*** dB Q ***Q value*** | Adds a filter of the given type with the given frequency, gain and Q. The supported filter types and their parameters are listed below. This is the filter text format used by Room EQ Wizard for equalizer type "Generic".
-Filter ***n*** | ON ***Type*** Fc ***Frequency*** Hz Gain ***Gain value*** dB BW Oct ***Bandwidth value*** | Adds a filter of the given type with the given frequency, gain and bandwidth. The supported filter types and their parameters are listed below. This is the filter text format used by Room EQ Wizard for equalizer type "FBQ2496".
+Filter ***n*** | ON ***Type*** Fc ***Frequency*** Hz Gain ***Gain value*** dB Q ***Q value*** | Adds a filter of the given type with the given frequency, gain and Q. The supported filter types and their parameters are listed below. This is the filter text format used by Room EQ Wizard for equalizer type "Generic". The filter number (n) is not interpreted and can be omitted.
+Filter ***n*** | ON ***Type*** Fc ***Frequency*** Hz Gain ***Gain value*** dB BW Oct ***Bandwidth value*** | Adds a filter of the given type with the given frequency, gain and bandwidth. The supported filter types and their parameters are listed below. This is the filter text format used by Room EQ Wizard for equalizer type "FBQ2496". The filter number (n) is not interpreted and can be omitted.
Device | ***Device identification pattern*** | Matches the given pattern to the connection name, device name and GUID of the current output device. If the pattern does not match, all following commands except Device commands are ignored. The pattern consists of words separated by space that must all be found in the string "***Device_name*** ***Connection_name*** ***GUID***". Multiple patterns of which one must match can be specified by separating the patterns with ';'. The special pattern "all" matches always. The benchmark application uses the device name "Benchmark" and connection name "File output". The easiest way to generate a Device command is to use the button in the Configurator application. (added in version 0.7)
Channel | *** Channel positions *** | Selects the channels to which the following Filter and Preamp commands will be applied. Channel positions can be given by identifier (acronym of 1 up to 3 characters) or by number (counted from 1). The supported channel configurations are listed below. If a channel configuration is not supported, channels can only be selected by number. Multiple channels can be specified by separating with space. The special position "all" selects all channels. (added in version 0.8)
@@ -84,7 +84,7 @@ Lines that contain any command name not in this list are silently ignored.
# Filter types
-The following table lists the filter types supported by Equalizer APO since version 0.8. The columns Fc, Gain and Q/BW show the parameters supported by the filter type. An 'X' means that the parameter is required while an 'O' denotes an optional parameter. The filter types supported cover all filters of the "Generic" and the "FBQ2496" equalizer type. Other equalizer types may also be compatible if their filter text format is. There is one exception however: The band-pass filter supported by Equalizer APO is a real band-pass filter that does not support gain, like low/high-pass filters, but unlike the DCX2496's "BP" filter, which is actually a peaking filter.
+The following table lists the filter types supported by Equalizer APO since version 0.8.1. The columns Fc, Gain and Q/BW show the parameters supported by the filter type. An 'X' means that the parameter is required while an 'O' denotes an optional parameter. The filter types supported cover all filters of the "Generic" and the "FBQ2496" equalizer type. Other equalizer types may also be compatible if their filter text format is. There is one exception however: The band-pass filter supported by Equalizer APO is a real band-pass filter that does not support gain, like low/high-pass filters, but unlike the DCX2496's "BP" filter, which is actually a peaking filter.
Type | Description | Fc | Gain | Q/BW | Example for filter parameters
- | - | - | - | - | -
@@ -92,8 +92,8 @@ PK
Modal
PEQ | Peaking filter
(Parametric EQ) | X | X | X | ON PK
LP
LPQ | Low-pass filter | X | | O | ON LP Fc 8000 Hz
ON LPQ Fc 10000 Hz Q 0.400
HP
HPQ | High-pass filter | X | | O | ON HP Fc 30.0 Hz
ON HPQ Fc 20.0 Hz Q 0.500
BP | Band-pass filter
(not from DCX2496) | X | | O | ON BP Fc 1000 Hz Q 0.100
-LS | Low-shelf filter
(with center freq.) | X | X | | ON LS Fc 300 Hz Gain 5.0 dB
-HS | High-shelf filter
(with center freq.) | X | X | | ON HS Fc 1000 Hz Gain -3.0 dB
+LS
LSC x dB | Low-shelf filter
(with center freq.,
x dB per oct. (LSC)) | X | X | | ON LS Fc 300 Hz Gain 5.0 dB
ON LSC 10.8 dB Fc 300 Hz Gain 5.0 dB
+HS
HSC x dB | High-shelf filter
(with center freq.,
x dB per oct. (HSC)) | X | X | | ON HS Fc 1000 Hz Gain -3.0 dB
ON HSC 6 dB Fc 100 Hz Gain -6.0 dB
LS 6dB
LS 12dB | Low-shelf filter
(6 / 12 dB per octave
with corner freq.) | X | X | | ON LS 6dB Fc 50.0 Hz Gain 7.2 dB
ON LS 12dB Fc 2000 Hz Gain -5.0 dB
HS 6dB
HS 12dB | High-shelf filter
(6 / 12 dB per octave
with corner freq.) | X | X | | ON HS 6dB Fc 12000 Hz Gain 10.0 dB
ON HS 12dB Fc 500 Hz Gain 5.0 dB
NO | Notch filter | X | | O | ON NO Fc 800 Hz
diff --git a/version.h b/version.h
index 205396c..bd1c320 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,3 @@
#define MAJOR 0
#define MINOR 8
+#define REVISION 1