Improved: The benchmark application now has a real command line interface. To see the available options, type "Benchmark.exe -h" .
This commit is contained in:
1 parent
fb5020e72f
commit
3dab99a85a
6 files changed
+258
-137
No files matched your search
+158
-99
@@ -22,122 +22,181 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sndfile.h>
|
#include <sndfile.h>
|
||||||
|
#include <tclap/CmdLine.h>
|
||||||
|
|
||||||
|
#include "../version.h"
|
||||||
#include "../ParametricEQ.h"
|
#include "../ParametricEQ.h"
|
||||||
|
#include "../LogHelper.h"
|
||||||
|
#include "../StringHelper.h"
|
||||||
#include "PerformanceCounter.h"
|
#include "PerformanceCounter.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
const int BATCH_SIZE = 65536;
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
unsigned sampleRate;
|
try
|
||||||
unsigned channelCount;
|
|
||||||
unsigned channelMask;
|
|
||||||
unsigned frameCount;
|
|
||||||
float* buf;
|
|
||||||
|
|
||||||
if(argc >= 2 && strlen(argv[1]) > 0)
|
|
||||||
{
|
{
|
||||||
SF_INFO info;
|
stringstream versionStream;
|
||||||
printf("Reading sound data from %s\n", argv[1]);
|
versionStream << MAJOR << "." << MINOR;
|
||||||
SNDFILE* inFile = sf_open(argv[1], SFM_READ, &info);
|
TCLAP::CmdLine cmd("Benchmark generates a linear sine sweep or reads from the given input file. "
|
||||||
if(inFile == NULL)
|
"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());
|
||||||
|
|
||||||
|
TCLAP::SwitchArg noPauseArg("", "nopause", "Do not wait for key press at the end", cmd);
|
||||||
|
TCLAP::SwitchArg verboseArg("v", "verbose", "Print trace and error messages to console instead of logfile", cmd);
|
||||||
|
TCLAP::ValueArg<string> guidArg("", "guid", "Endpoint GUID to use when parsing configuration (Default: <empty>)", false, "", "string", cmd);
|
||||||
|
TCLAP::ValueArg<string> connectionnameArg("", "connectionname", "Connection name to use when parsing configuration (Default: File output)", false, "File output", "string", cmd);
|
||||||
|
TCLAP::ValueArg<string> devicenameArg("", "devicename", "Device name to use when parsing configuration (Default: Benchmark)", false, "Benchmark", "string", cmd);
|
||||||
|
TCLAP::ValueArg<unsigned> batchsizeArg("", "batchsize", "Number of frames processed in one batch (Default: 65536)", false, 65536, "integer", cmd);
|
||||||
|
TCLAP::ValueArg<string> outputArg("o", "output", "File to write sound data to", false, "", "string", cmd);
|
||||||
|
TCLAP::ValueArg<string> inputArg("i", "input", "File to load sound data from instead of generating sweep", false, "", "string", cmd);
|
||||||
|
TCLAP::ValueArg<unsigned> rateArg("r", "rate", "Sample rate of generated sweep (Default: 44100)", false, 44100, "integer", cmd);
|
||||||
|
TCLAP::ValueArg<float> toArg("t", "to", "End frequency of generated sweep in Hz (Default: 20000.0)", false, 20000.0f, "float", cmd);
|
||||||
|
TCLAP::ValueArg<float> fromArg("f", "from", "Start frequency of generated sweep in Hz (Default: 0.1)", false, 0.1f, "float", cmd);
|
||||||
|
TCLAP::ValueArg<float> lengthArg("l", "length", "Length of generated sweep in seconds (Default: 200.0)", false, 200.0f, "float", cmd);
|
||||||
|
TCLAP::ValueArg<unsigned> channelArg("c", "channels", "Number of channels of generated sweep (Default: 2)", false, 2, "integer", cmd);
|
||||||
|
|
||||||
|
cmd.parse(argc, argv);
|
||||||
|
|
||||||
|
LogHelper::set(stderr, verboseArg.getValue(), true);
|
||||||
|
|
||||||
|
unsigned sampleRate;
|
||||||
|
unsigned channelCount;
|
||||||
|
unsigned channelMask;
|
||||||
|
unsigned frameCount;
|
||||||
|
float length;
|
||||||
|
float* buf;
|
||||||
|
|
||||||
|
printf("Benchmark %d.%d\n", MAJOR, MINOR);
|
||||||
|
printf("Run \"%s -h\" to show usage info\n", argv[0]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
string input = inputArg.getValue();
|
||||||
|
if(input != "")
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s", sf_strerror(inFile));
|
SF_INFO info;
|
||||||
|
printf("Reading sound data from %s\n", input.c_str());
|
||||||
|
SNDFILE* inFile = sf_open(input.c_str(), SFM_READ, &info);
|
||||||
|
if(inFile == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s", sf_strerror(inFile));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleRate = info.samplerate;
|
||||||
|
channelCount = info.channels;
|
||||||
|
channelMask = 0;
|
||||||
|
frameCount = (unsigned)info.frames;
|
||||||
|
length = float(frameCount) / sampleRate;
|
||||||
|
|
||||||
|
buf = new float[frameCount * channelCount];
|
||||||
|
|
||||||
|
sf_count_t numRead = 0;
|
||||||
|
while(numRead < frameCount)
|
||||||
|
numRead += sf_readf_float(inFile, buf + numRead * channelCount, frameCount - numRead);
|
||||||
|
|
||||||
|
sf_close(inFile);
|
||||||
|
inFile = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sampleRate = rateArg.getValue();
|
||||||
|
channelMask = 0;
|
||||||
|
channelCount = channelArg.getValue();
|
||||||
|
float sweepFrom = fromArg.getValue();
|
||||||
|
float sweepTo = toArg.getValue();
|
||||||
|
float sweepDiff = sweepTo - sweepFrom;
|
||||||
|
length = lengthArg.getValue();
|
||||||
|
frameCount = (unsigned)(length * sampleRate);
|
||||||
|
|
||||||
|
printf("No input file given, so generating linear sine sweep from %g to %g Hz over %g seconds\n", sweepFrom, sweepTo, length);
|
||||||
|
|
||||||
|
buf = new float[frameCount * channelCount];
|
||||||
|
|
||||||
|
for(unsigned i=0;i<frameCount;i++)
|
||||||
|
for(unsigned j=0;j<channelCount;j++)
|
||||||
|
{
|
||||||
|
float t=(i*1.0f / sampleRate);
|
||||||
|
|
||||||
|
buf[i*channelCount + j] = sin(((sweepFrom + sweepDiff*(t/length)/2)*t)*2*(float)M_PI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nProcessing %d frames from %d channel(s)\n", frameCount, channelCount);
|
||||||
|
|
||||||
|
ParametricEQ peq;
|
||||||
|
peq.setDeviceInfo(StringHelper::toWString(devicenameArg.getValue(), CP_ACP),
|
||||||
|
StringHelper::toWString(connectionnameArg.getValue(), CP_ACP),
|
||||||
|
StringHelper::toWString(guidArg.getValue(), CP_ACP));
|
||||||
|
peq.initialize((float)sampleRate, channelCount, channelMask);
|
||||||
|
|
||||||
|
PrecisionTimer timer;
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
unsigned batchsize = batchsizeArg.getValue();
|
||||||
|
for(unsigned i=0; i<frameCount; i+=batchsize)
|
||||||
|
{
|
||||||
|
peq.process(buf + i*channelCount, buf + i*channelCount, min(batchsize, frameCount - i));
|
||||||
|
}
|
||||||
|
|
||||||
|
double time = timer.stop();
|
||||||
|
|
||||||
|
printf("%d samples processed in %f seconds\n", frameCount * channelCount, time);
|
||||||
|
printf("This is equivalent to %.2f%% CPU load (one core) when processing in real time\n", 100.0f * time / length);
|
||||||
|
|
||||||
|
unsigned clipCount = 0;
|
||||||
|
float max = 0;
|
||||||
|
for(unsigned i=0; i<frameCount*channelCount; i++)
|
||||||
|
{
|
||||||
|
float f = fabs(buf[i]);
|
||||||
|
if(f > max)
|
||||||
|
max = f;
|
||||||
|
if(f > 1.0f)
|
||||||
|
clipCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Max output level: %f (%f dB)", max, log10(max) * 20.0f);
|
||||||
|
if(clipCount > 0)
|
||||||
|
printf(" (%d samples clipped!)", clipCount);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
string output = outputArg.getValue();
|
||||||
|
if(output == "")
|
||||||
|
{
|
||||||
|
char temp[255];
|
||||||
|
GetTempPathA(sizeof(temp)/sizeof(wchar_t), temp);
|
||||||
|
|
||||||
|
output = temp;
|
||||||
|
output += "testout.wav";
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nWriting output to %s\n", output.c_str());
|
||||||
|
|
||||||
|
SF_INFO info = {frameCount, sampleRate, channelCount, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 0};
|
||||||
|
SNDFILE* outFile = sf_open(output.c_str(), SFM_WRITE, &info);
|
||||||
|
if(outFile == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s", sf_strerror(outFile));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleRate = info.samplerate;
|
sf_count_t numWritten = 0;
|
||||||
channelCount = info.channels;
|
while(numWritten < frameCount)
|
||||||
channelMask = 0;
|
numWritten += sf_writef_float(outFile, buf + numWritten * channelCount, frameCount - numWritten);
|
||||||
frameCount = (unsigned)info.frames;
|
|
||||||
|
|
||||||
buf = new float[frameCount * channelCount];
|
sf_close(outFile);
|
||||||
|
outFile = NULL;
|
||||||
|
|
||||||
sf_count_t numRead = 0;
|
delete[] buf;
|
||||||
while(numRead < frameCount)
|
|
||||||
numRead += sf_readf_float(inFile, buf + numRead * channelCount, frameCount - numRead);
|
|
||||||
|
|
||||||
sf_close(inFile);
|
if(!noPauseArg.getValue())
|
||||||
inFile = NULL;
|
system("pause");
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
catch(TCLAP::ArgException e)
|
||||||
{
|
{
|
||||||
sampleRate = 44100;
|
printf("Error: %s for arg %s\n", e.error(), e.argId());
|
||||||
channelCount = 1;
|
return -1;
|
||||||
channelMask = 0;
|
|
||||||
float sweepFrom = 0.1f;
|
|
||||||
float sweepTo = 20000;
|
|
||||||
float sweepDiff = sweepTo - sweepFrom;
|
|
||||||
float length = 200;
|
|
||||||
frameCount = (unsigned)(length * sampleRate);
|
|
||||||
|
|
||||||
printf("No input file given, so generating linear sine sweep from %g to %g Hz over %g seconds\n", sweepFrom, sweepTo, length);
|
|
||||||
|
|
||||||
buf = new float[frameCount * channelCount];
|
|
||||||
|
|
||||||
for(unsigned i=0;i<frameCount;i++)
|
|
||||||
for(unsigned j=0;j<channelCount;j++)
|
|
||||||
{
|
|
||||||
float t=(i*1.0f / sampleRate);
|
|
||||||
|
|
||||||
buf[i*channelCount + j] = sin(((sweepFrom + sweepDiff*(t/length)/2)*t)*2*(float)M_PI);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Processing %d frames from %d channel(s)\n", frameCount, channelCount);
|
|
||||||
|
|
||||||
ParametricEQ peq;
|
|
||||||
peq.setDeviceInfo(L"Benchmark", L"File output", L"");
|
|
||||||
peq.initialize((float)sampleRate, channelCount, channelMask);
|
|
||||||
|
|
||||||
PrecisionTimer timer;
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
for(unsigned i=0; i<frameCount; i+=BATCH_SIZE)
|
|
||||||
{
|
|
||||||
peq.process(buf + i*channelCount, buf + i*channelCount, min(BATCH_SIZE, frameCount - i));
|
|
||||||
}
|
|
||||||
|
|
||||||
double time = timer.stop();
|
|
||||||
|
|
||||||
printf("%d samples processed in %f seconds\n", frameCount * channelCount, time);
|
|
||||||
|
|
||||||
string outPath;
|
|
||||||
if(argc >= 3 && strlen(argv[2]) > 0)
|
|
||||||
outPath = argv[2];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char temp[255];
|
|
||||||
GetTempPathA(sizeof(temp)/sizeof(wchar_t), temp);
|
|
||||||
|
|
||||||
outPath = temp;
|
|
||||||
outPath += "testout.wav";
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Writing output to %s\n", outPath.c_str());
|
|
||||||
|
|
||||||
SF_INFO info = {frameCount, sampleRate, channelCount, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 0};
|
|
||||||
SNDFILE* outFile = sf_open(outPath.c_str(), SFM_WRITE, &info);
|
|
||||||
if(outFile == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s", sf_strerror(outFile));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sf_count_t numWritten = 0;
|
|
||||||
while(numWritten < frameCount)
|
|
||||||
numWritten += sf_writef_float(outFile, buf + numWritten * channelCount, frameCount - numWritten);
|
|
||||||
|
|
||||||
sf_close(outFile);
|
|
||||||
outFile = NULL;
|
|
||||||
|
|
||||||
delete[] buf;
|
|
||||||
|
|
||||||
if(argc < 3)
|
|
||||||
system("pause");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
@@ -64,22 +64,22 @@
|
|||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
<IncludePath>C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\Program Files\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\Program Files\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
<IncludePath>C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\Program Files\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\Program Files\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
<IncludePath>C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\Program Files\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\Program Files\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
<IncludePath>C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\Program Files\libsndfile\lib64;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\Program Files\libsndfile\lib64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
|||||||
+31
-9
@@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@@ -30,6 +29,8 @@ using namespace std;
|
|||||||
bool LogHelper::initialized = false;
|
bool LogHelper::initialized = false;
|
||||||
wstring LogHelper::logPath;
|
wstring LogHelper::logPath;
|
||||||
bool LogHelper::enableTrace = false;
|
bool LogHelper::enableTrace = false;
|
||||||
|
FILE* LogHelper::presetFP = NULL;
|
||||||
|
bool LogHelper::compact = false;
|
||||||
|
|
||||||
void LogHelper::log(const char* file, int line, void* caller, bool trace, const wchar_t* format, ...)
|
void LogHelper::log(const char* file, int line, void* caller, bool trace, const wchar_t* format, ...)
|
||||||
{
|
{
|
||||||
@@ -59,14 +60,24 @@ void LogHelper::log(const char* file, int line, void* caller, bool trace, const
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
errno_t err = _wfopen_s(&fp, logPath.c_str(), L"at");
|
if(presetFP == NULL)
|
||||||
if(err != 0)
|
{
|
||||||
return;
|
errno_t err = _wfopen_s(&fp, logPath.c_str(), L"at");
|
||||||
|
if(err != 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fp = presetFP;
|
||||||
|
}
|
||||||
|
|
||||||
SYSTEMTIME ___st;
|
if(!compact)
|
||||||
GetLocalTime(&___st);
|
{
|
||||||
fwprintf(fp, L"%04d-%02d-%02d %02d:%02d:%02d.%03d %08X (%S:%d): ",
|
SYSTEMTIME ___st;
|
||||||
___st.wYear, ___st.wMonth, ___st.wDay, ___st.wHour, ___st.wMinute, ___st.wSecond, ___st.wMilliseconds, caller, file, line);
|
GetLocalTime(&___st);
|
||||||
|
fwprintf(fp, L"%04d-%02d-%02d %02d:%02d:%02d.%03d %08X (%S:%d): ",
|
||||||
|
___st.wYear, ___st.wMonth, ___st.wDay, ___st.wHour, ___st.wMinute, ___st.wSecond, ___st.wMilliseconds, caller, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
if(trace)
|
if(trace)
|
||||||
fwprintf(fp, L"(TRACE) ");
|
fwprintf(fp, L"(TRACE) ");
|
||||||
@@ -77,7 +88,9 @@ void LogHelper::log(const char* file, int line, void* caller, bool trace, const
|
|||||||
va_end(varArgs);
|
va_end(varArgs);
|
||||||
|
|
||||||
fwprintf(fp, L"\n");
|
fwprintf(fp, L"\n");
|
||||||
fclose(fp);
|
|
||||||
|
if(presetFP == NULL)
|
||||||
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogHelper::reset()
|
void LogHelper::reset()
|
||||||
@@ -86,3 +99,12 @@ void LogHelper::reset()
|
|||||||
logPath = L"";
|
logPath = L"";
|
||||||
enableTrace = false;
|
enableTrace = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogHelper::set(FILE* fp, bool enableTrace, bool compact)
|
||||||
|
{
|
||||||
|
LogHelper::initialized = true;
|
||||||
|
|
||||||
|
LogHelper::presetFP = fp;
|
||||||
|
LogHelper::enableTrace = enableTrace;
|
||||||
|
LogHelper::compact = compact;
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
#define TraceF(format, ...) LogHelper::log(__FILE__, __LINE__, this, true, format, __VA_ARGS__);
|
#define TraceF(format, ...) LogHelper::log(__FILE__, __LINE__, this, true, format, __VA_ARGS__);
|
||||||
#define TraceFStatic(format, ...) LogHelper::log(__FILE__, __LINE__, NULL, true, format, __VA_ARGS__);
|
#define TraceFStatic(format, ...) LogHelper::log(__FILE__, __LINE__, NULL, true, format, __VA_ARGS__);
|
||||||
@@ -31,9 +32,12 @@ class LogHelper
|
|||||||
public:
|
public:
|
||||||
static void log(const char* file, int line, void* caller, bool trace, const wchar_t* format, ...);
|
static void log(const char* file, int line, void* caller, bool trace, const wchar_t* format, ...);
|
||||||
static void reset();
|
static void reset();
|
||||||
|
static void set(FILE* fp, bool enableTrace, bool compact);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool initialized;
|
static bool initialized;
|
||||||
static std::wstring logPath;
|
static std::wstring logPath;
|
||||||
static bool enableTrace;
|
static bool enableTrace;
|
||||||
|
static FILE* presetFP;
|
||||||
|
static bool compact;
|
||||||
};
|
};
|
||||||
+58
-25
@@ -35,6 +35,7 @@
|
|||||||
#include "ParametricEQ.h"
|
#include "ParametricEQ.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace stdext;
|
||||||
|
|
||||||
BiQuad::BiQuad(float dbGain, float freq, float srate, float bandwidthOrQ, bool isQ)
|
BiQuad::BiQuad(float dbGain, float freq, float srate, float bandwidthOrQ, bool isQ)
|
||||||
{
|
{
|
||||||
@@ -73,6 +74,19 @@ ParametricEQ::ParametricEQ()
|
|||||||
channelData = NULL;
|
channelData = NULL;
|
||||||
lastInputWasSilent = false;
|
lastInputWasSilent = false;
|
||||||
threadHandle = NULL;
|
threadHandle = NULL;
|
||||||
|
|
||||||
|
channelNameToPosMap[L"L"] = SPEAKER_FRONT_LEFT;
|
||||||
|
channelNameToPosMap[L"R"] = SPEAKER_FRONT_RIGHT;
|
||||||
|
channelNameToPosMap[L"C"] = SPEAKER_FRONT_CENTER;
|
||||||
|
channelNameToPosMap[L"SUB"] = SPEAKER_LOW_FREQUENCY;
|
||||||
|
channelNameToPosMap[L"RL"] = SPEAKER_BACK_LEFT;
|
||||||
|
channelNameToPosMap[L"RR"] = SPEAKER_BACK_RIGHT;
|
||||||
|
channelNameToPosMap[L"RC"] = SPEAKER_BACK_CENTER;
|
||||||
|
channelNameToPosMap[L"SL"] = SPEAKER_SIDE_LEFT;
|
||||||
|
channelNameToPosMap[L"SR"] = SPEAKER_SIDE_RIGHT;
|
||||||
|
|
||||||
|
for(hash_map<wstring, int>::iterator it=channelNameToPosMap.begin(); it!=channelNameToPosMap.end(); it++)
|
||||||
|
channelPosToNameMap[it->second] = it->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParametricEQ::~ParametricEQ()
|
ParametricEQ::~ParametricEQ()
|
||||||
@@ -133,6 +147,24 @@ void ParametricEQ::initialize(float sampleRate, unsigned channelCount, unsigned
|
|||||||
}
|
}
|
||||||
this->channelMask = channelMask;
|
this->channelMask = channelMask;
|
||||||
|
|
||||||
|
wstringstream channelNames;
|
||||||
|
unsigned c=0;
|
||||||
|
for(int i=0; i<31; i++)
|
||||||
|
{
|
||||||
|
int channelPos = 1<<i;
|
||||||
|
if(channelMask & channelPos)
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
if(channelNames.tellp() > 0)
|
||||||
|
channelNames << L" ";
|
||||||
|
if(channelPosToNameMap.find(channelPos) != channelPosToNameMap.end())
|
||||||
|
channelNames << channelPosToNameMap[channelPos];
|
||||||
|
else
|
||||||
|
channelNames << c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TraceF(L"%d channels for this device: %s", channelCount, channelNames.str().c_str());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
configPath = RegistryHelper::readValue(APP_REGPATH, L"ConfigPath");
|
configPath = RegistryHelper::readValue(APP_REGPATH, L"ConfigPath");
|
||||||
@@ -280,7 +312,7 @@ void ParametricEQ::loadConfig(const wstring& path, vector<bool> selectedChannels
|
|||||||
wstring currentWord;
|
wstring currentWord;
|
||||||
for(unsigned i=0; i<value.length(); i++)
|
for(unsigned i=0; i<value.length(); i++)
|
||||||
{
|
{
|
||||||
wchar_t c = towlower(value[i]);
|
wchar_t c = towupper(value[i]);
|
||||||
|
|
||||||
if(c == L' ')
|
if(c == L' ')
|
||||||
{
|
{
|
||||||
@@ -288,7 +320,7 @@ void ParametricEQ::loadConfig(const wstring& path, vector<bool> selectedChannels
|
|||||||
{
|
{
|
||||||
int channelNr = -1;
|
int channelNr = -1;
|
||||||
|
|
||||||
if(currentWord == L"all")
|
if(currentWord == L"ALL")
|
||||||
{
|
{
|
||||||
selectedChannels = vector<bool>(channelCount, true);
|
selectedChannels = vector<bool>(channelCount, true);
|
||||||
}
|
}
|
||||||
@@ -299,24 +331,8 @@ void ParametricEQ::loadConfig(const wstring& path, vector<bool> selectedChannels
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int channelPos = -1;
|
int channelPos = -1;
|
||||||
if(currentWord == L"l")
|
if(channelNameToPosMap.find(currentWord) != channelNameToPosMap.end())
|
||||||
channelPos = SPEAKER_FRONT_LEFT;
|
channelPos = channelNameToPosMap[currentWord];
|
||||||
else if(currentWord == L"r")
|
|
||||||
channelPos = SPEAKER_FRONT_RIGHT;
|
|
||||||
else if(currentWord == L"c")
|
|
||||||
channelPos = SPEAKER_FRONT_CENTER;
|
|
||||||
else if(currentWord == L"sub")
|
|
||||||
channelPos = SPEAKER_LOW_FREQUENCY;
|
|
||||||
else if(currentWord == L"rl")
|
|
||||||
channelPos = SPEAKER_BACK_LEFT;
|
|
||||||
else if(currentWord == L"rr")
|
|
||||||
channelPos = SPEAKER_BACK_RIGHT;
|
|
||||||
else if(currentWord == L"rc")
|
|
||||||
channelPos = SPEAKER_BACK_CENTER;
|
|
||||||
else if(currentWord == L"sl")
|
|
||||||
channelPos = SPEAKER_SIDE_LEFT;
|
|
||||||
else if(currentWord == L"sr")
|
|
||||||
channelPos = SPEAKER_SIDE_RIGHT;
|
|
||||||
else
|
else
|
||||||
LogF(L"Invalid channel position %s", currentWord.c_str());
|
LogF(L"Invalid channel position %s", currentWord.c_str());
|
||||||
|
|
||||||
@@ -338,18 +354,19 @@ void ParametricEQ::loadConfig(const wstring& path, vector<bool> selectedChannels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wstringstream channelStream;
|
wstringstream channelNumbers;
|
||||||
for(unsigned c=0; c<channelCount; c++)
|
for(unsigned c=0; c<channelCount; c++)
|
||||||
{
|
{
|
||||||
if(selectedChannels[c])
|
if(selectedChannels[c])
|
||||||
{
|
{
|
||||||
if(channelStream.tellp() > 0)
|
if(channelNumbers.tellp() > 0)
|
||||||
channelStream << L", ";
|
channelNumbers << L", ";
|
||||||
channelStream << c+1;
|
|
||||||
|
channelNumbers << c+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceF(L"Selecting channel(s) %s", channelStream.str().c_str());
|
TraceF(L"Selecting channel(s) number %s", channelNumbers.str().c_str());
|
||||||
}
|
}
|
||||||
else if(key.find(L"Filter") == 0)
|
else if(key.find(L"Filter") == 0)
|
||||||
{
|
{
|
||||||
@@ -510,6 +527,22 @@ float ParametricEQ::getFreq(const wstring& freqString)
|
|||||||
|
|
||||||
unsigned ParametricEQ::getChannelNumber(unsigned position)
|
unsigned ParametricEQ::getChannelNumber(unsigned position)
|
||||||
{
|
{
|
||||||
|
//Special handling to accept "wrong", but unambiguous positions
|
||||||
|
if(channelMask == KSAUDIO_SPEAKER_5POINT1_SURROUND)
|
||||||
|
{
|
||||||
|
if(position == SPEAKER_BACK_LEFT)
|
||||||
|
return 4;
|
||||||
|
else if(position == SPEAKER_BACK_RIGHT)
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
else if(channelMask == KSAUDIO_SPEAKER_5POINT1)
|
||||||
|
{
|
||||||
|
if(position == SPEAKER_SIDE_LEFT)
|
||||||
|
return 4;
|
||||||
|
else if(position == SPEAKER_SIDE_RIGHT)
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
if((channelMask & position) == 0)
|
if((channelMask & position) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <hash_map>
|
||||||
|
|
||||||
#define IS_DENORMAL(f) (((*(unsigned int *)&(f))&0x7f800000) == 0)
|
#define IS_DENORMAL(f) (((*(unsigned int *)&(f))&0x7f800000) == 0)
|
||||||
|
|
||||||
@@ -106,4 +107,6 @@ private:
|
|||||||
bool lastInputWasSilent;
|
bool lastInputWasSilent;
|
||||||
void* threadHandle;
|
void* threadHandle;
|
||||||
void* shutdownEvent;
|
void* shutdownEvent;
|
||||||
|
stdext::hash_map<std::wstring, int> channelNameToPosMap;
|
||||||
|
stdext::hash_map<int, std::wstring> channelPosToNameMap;
|
||||||
};
|
};
|
||||||
Reference in new issue
Block a user