diff --git a/Configurator/Configurator.cpp b/Configurator/Configurator.cpp index fa465be..0732560 100644 --- a/Configurator/Configurator.cpp +++ b/Configurator/Configurator.cpp @@ -235,7 +235,7 @@ bool Configurator::onButtonClicked(unsigned sourceId) command += L"; "; DeviceAPOInfo info = apoInfos[index][item.lParam]; - command += StringHelper::replaceCharacters(info.deviceName + L" " + info.connectionName + L" " + info.deviceGuid, L";", L' '); + command += StringHelper::replaceCharacters(info.deviceName + L" " + info.connectionName + L" " + info.deviceGuid, L";", L" "); } } diff --git a/ParametricEQ.cpp b/ParametricEQ.cpp index 9e35755..201238b 100644 --- a/ParametricEQ.cpp +++ b/ParametricEQ.cpp @@ -39,7 +39,7 @@ using namespace std; using namespace stdext; static wregex regexType(L"^\\s*ON\\s+([A-Za-z]+)"); -static wregex regexFreq(L"\\s+Fc\\s*([0-9.]+)\\s*H\\s*z"); +static wregex regexFreq(L"\\s+Fc\\s*([0-9.\u00A0]+)\\s*H\\s*z"); static wregex regexGain(L"\\s+Gain\\s*([-+0-9.]+)\\s*dB"); static wregex regexQ(L"\\s+Q\\s*([0-9.]+)"); static wregex regexBW(L"\\s+BW\\s+Oct\\s*([0-9.]+)"); @@ -395,7 +395,7 @@ void ParametricEQ::loadConfig(const wstring& path, vector selectedChannels else if(key.find(L"Filter") == 0) { //Conversion to period as decimal mark, if needed - value = StringHelper::replaceCharacters(value, L",", L'.'); + value = StringHelper::replaceCharacters(value, L",", L"."); wsmatch match; wstring typeString; @@ -547,7 +547,7 @@ void ParametricEQ::loadConfig(const wstring& path, vector selectedChannels else if(key == L"Preamp") { //Conversion to period as decimal mark, if needed - value = StringHelper::replaceCharacters(value, L",", L'.'); + value = StringHelper::replaceCharacters(value, L",", L"."); float preamp_dB; int matched = swscanf_s(value.c_str(), L" %f dB", &preamp_dB); @@ -646,12 +646,14 @@ void ParametricEQ::process(float *output, float *input, unsigned frameCount) float ParametricEQ::getFreq(const wstring& freqString) { float result; - int matched = swscanf_s(freqString.c_str(), L"%f", &result); + // remove thousand's separator for locales utilizing non-breaking space + wstring s = StringHelper::replaceCharacters(freqString, L"\u00A0", L""); + int matched = swscanf_s(s.c_str(), L"%f", &result); if(matched == 1) { - if(freqString.length() >= 5) + if(s.length() >= 5) { - if(freqString[freqString.length() - 4] == L'.') + if(s[s.length() - 4] == L'.') { //Interpret as thousands separator because of Room EQ Wizard result *= 1000.0f; diff --git a/StringHelper.cpp b/StringHelper.cpp index fa2d0b7..4a86989 100644 --- a/StringHelper.cpp +++ b/StringHelper.cpp @@ -25,7 +25,7 @@ using namespace std; -wstring StringHelper::replaceCharacters(std::wstring s, std::wstring chars, wchar_t replacement) +wstring StringHelper::replaceCharacters(wstring s, wstring chars, wstring replacement) { wstring result; result.reserve(s.length()); @@ -33,10 +33,10 @@ wstring StringHelper::replaceCharacters(std::wstring s, std::wstring chars, wcha for(unsigned i=0; i:\"/\\|?*", '_'); + return replaceCharacters(filename, L"<>:\"/\\|?*", L"_"); } wstring StringHelper::toWString(string s, unsigned codepage) diff --git a/StringHelper.h b/StringHelper.h index f7ecc0f..d735896 100644 --- a/StringHelper.h +++ b/StringHelper.h @@ -25,7 +25,8 @@ class StringHelper { public: - static std::wstring replaceCharacters(std::wstring s, std::wstring chars, wchar_t replacement); + // replaces any occurrence of a character from chars in s with the replacement string + static std::wstring replaceCharacters(std::wstring s, std::wstring chars, std::wstring replacement); static std::wstring replaceIllegalCharacters(std::wstring filename); static std::wstring toWString(std::string s, unsigned codepage); static std::wstring toLowerCase(std::wstring s); diff --git a/Wiki/Documentation.txt b/Wiki/Documentation.txt index b73980f..956de82 100644 --- a/Wiki/Documentation.txt +++ b/Wiki/Documentation.txt @@ -120,3 +120,29 @@ Surround | 1 | 2 | 3 | | | | 4 | | Although it might be tempting to assign low frequency filters only to the subwoofer channel, this might not lead to the expected results. Many audio systems apply bass redirection after Equalizer APO has processed the signal, so filters applied to the subwoofer channel won't be effective for redirected sound. Furthermore, as crossover filters only gradually fade in, the low frequency audio might be played over multiple speakers, not just the subwoofer, reducing the effectivity of subwoofer-only filters. Therefore, to avoid these problems, it's recommended to apply low frequency filters to all channels. + + +# Troubleshooting + +This section describes approaches to solve possible problems impeding the successful operation of Equalizer APO. + +## Control Panel +If you installed Equalizer APO and no changes to the configuration file lead to any changes in the signal, APOs might have been disabled for the device in the Control Panel. +To check this, open Start Menu -> Control Panel -> Sound and double click on your audio device to open the properties dialog. + +If the dialog has an "Enhancements" tab, go to that tab. You should see a view similar to the left screenshot below. Make sure the "Disable all enhancements" check box (red box) is unchecked, even if you don't use any of the enhancements in the list. + +If the dialog does not have an "Enhancements" tab, go to the "Advanced" tab. You should see a view similar to the right screenshot below. Make sure the "Enable audio enhancements" check box (red box) is checked. + + + +## Log files +When Equalizer APO encounters a critical problem while running, it writes a line into the log file C:\\Windows\\ServiceProfiles\\LocalService\\AppData\\Local\\Temp\\EqualizerAPO.log . So, in case of problems this file might contain useful information. Under normal circumstances, this file does not even exist, as it will only be created when an error occurs. + +To get more information, you can enable trace messages, which means that Equalizer APO will write lines marked with "(TRACE)" to the file even when running normally. To do this, open regedit.exe, go to HKEY_LOCAL_MACHINE\\SOFTWARE\\EqualizerAPO and set the value EnableTrace to true. Then, when playing back or recording audio via a device that Equalizer APO is installed to, information about initialization and the configuration files will be output to the log file. This might help e.g. to see if the configuration files are interpreted as intended. After you have finished, you should set EnableTrace back to false, so that the log file does not grow unnecessarily. + +## Hardware-accelerated OpenAL +Normally, applications utilizing OpenAL for their audio output do not present a problem as they will often use DirectSound as their backend, which supports APOs. Some sound card manufacturers however provide OpenAL libraries with hardware-acceleration that access the hardware directly, circumventing APOs. There is no way to enable APO support for hardware-accelerated OpenAL, so the only solution for this is to either switch to another output library, if the application supports that, or to make OpenAL fall back to software. + +To force OpenAL to fall back to software, the OpenAL32.dll may be replaced with a different one, for example from http://kcat.strangesoft.net/openal.html +A way to globally disable OpenAL hardware-acceleration however is to move or rename the vendor-specific OpenAL library in C:\\Windows\\System32 or C:\\Windows\\SysWOW64, which is often called like *_oal.dll, for example ct_oal.dll . Warning: This is a modification to the sound driver, which is of course not officially supported and can lead to unexpected results. \ No newline at end of file diff --git a/Wiki/EnhancementsTab.png b/Wiki/EnhancementsTab.png new file mode 100644 index 0000000..112f7ff Binary files /dev/null and b/Wiki/EnhancementsTab.png differ diff --git a/Wiki/NoEnhancementsTab.png b/Wiki/NoEnhancementsTab.png new file mode 100644 index 0000000..0cd65d5 Binary files /dev/null and b/Wiki/NoEnhancementsTab.png differ