diff options
author | Thorvald Natvig <slicer@users.sourceforge.net> | 2008-04-04 16:33:30 +0400 |
---|---|---|
committer | Thorvald Natvig <slicer@users.sourceforge.net> | 2008-04-04 16:33:30 +0400 |
commit | 45121cd850deaf3dad08f3f42d7b4de07ffa0eab (patch) | |
tree | 8176620db61bf1683911d7e5889c68726fdbdafb /speexbuild | |
parent | 8438405608f03b4af5d2747202b2525284d7cd2c (diff) |
Work on the speex resampler
git-svn-id: https://mumble.svn.sourceforge.net/svnroot/mumble/trunk@1056 05730e5d-ab1b-0410-a4ac-84af385074fa
Diffstat (limited to 'speexbuild')
-rw-r--r-- | speexbuild/ResampMark.cpp | 206 | ||||
-rw-r--r-- | speexbuild/ResampMark.pro | 11 | ||||
-rw-r--r-- | speexbuild/SpeexMark.cpp | 72 | ||||
-rw-r--r-- | speexbuild/SpeexMark.pro | 9 | ||||
-rw-r--r-- | speexbuild/speexbuild.pro | 2 |
5 files changed, 278 insertions, 22 deletions
diff --git a/speexbuild/ResampMark.cpp b/speexbuild/ResampMark.cpp new file mode 100644 index 000000000..d53e4333b --- /dev/null +++ b/speexbuild/ResampMark.cpp @@ -0,0 +1,206 @@ +#include <QtCore> + +static const float tfreq1 = 48000.f; +static const float tfreq2 = 44100.f; +#define SM_VERIFY +// #define EXACT + +#ifdef Q_OS_WIN +#define _WIN32_IE 0x0600 +#include <windows.h> +#include <shellapi.h> +#define CALLGRIND_START_INSTRUMENTATION +#define CALLGRIND_STOP_INSTRUMENTATION +#define CALLGRIND_ZERO_STATS +#else +#include <valgrind/callgrind.h> +#endif + +#include <math.h> +#include <speex/speex_resampler.h> + +#include "Timer.h" + +int main(int argc, char **argv) { + + CALLGRIND_STOP_INSTRUMENTATION; + CALLGRIND_ZERO_STATS; + + QCoreApplication a(argc, argv); + + QFile f((argc >= 2) ? argv[1] : "wb_male.wav"); + if (! f.open(QIODevice::ReadOnly)) { + qFatal("Failed to open file!"); + } + f.seek(36 + 8); + +#ifdef SM_OUTPUT + QFile o("output.raw"); + if (! o.open(QIODevice::WriteOnly)) + qFatal("Failed to open output!"); +#endif +#ifdef SM_VERIFY + QFile vf((argc >= 3) ? argv[2] : "verify.raw"); + if (! vf.open(QIODevice::ReadOnly)) { + qWarning("Failed to open validate file!"); + } +#endif + + const int iFrameSize = 320; + + QVector<QByteArray> v; + while(1) { + QByteArray qba = f.read(iFrameSize * 2); + if (qba.size() != iFrameSize * 2) + break; + v.append(qba); + } + + int nframes = v.size(); + + + qWarning("Ready to process %d frames of %d samples", nframes, iFrameSize); + + QVector<float *> sv; + + + + short tframe[2048]; + for(int i=0;i<iFrameSize;i++) + tframe[i] = 0; + + for(int i=0;i<nframes;i++) { + float *f = new float[iFrameSize]; + short *s = reinterpret_cast<short *>(v[i].data()); + for(int j=0;j<iFrameSize;j++) + f[j]=s[j]; + sv.append(f); + } + + float resampframe[32768]; + float verifyframe[32768]; + + const float sfraq1 = tfreq1 / 16000.0f; + float fOutSize1 = iFrameSize * sfraq1; + int iOutSize1 = lroundf(fOutSize1); + + const float sfraq2 = tfreq2 / 16000.0f; + float fOutSize2 = iFrameSize * sfraq2; + int iOutSize2 = lroundf(fOutSize2); + + int err; + SpeexResamplerState *srs1 = speex_resampler_init(1, 16000, lroundf(tfreq1), 3, &err); + SpeexResamplerState *srs2 = speex_resampler_init(1, 16000, lroundf(tfreq2), 3, &err); + +#ifdef Q_OS_WIN + if (!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) + qWarning("Application: Failed to set priority!"); +#endif + + int len; + spx_uint32_t inlen; + spx_uint32_t outlen; + + Timer t; + quint64 e; + + if (RUNNING_ON_VALGRIND) { + nframes = qMin(nframes, 10); + } else { + t.restart(); + for(int j=0;j<100;j++) { + for(int i=0;i<100;i++) { + float *in = sv[i]; + inlen = iFrameSize; + outlen = iOutSize1; + speex_resampler_process_float(srs1, 0, in, &inlen, resampframe, &outlen); + } + } + e = t.elapsed(); + qWarning("Direct: %10llu usec", e); + + t.restart(); + for(int j=0;j<100;j++) { + for(int i=0;i<100;i++) { + float *in = sv[i]; + inlen = iFrameSize; + outlen = iOutSize2; + speex_resampler_process_float(srs2, 0, in, &inlen, resampframe, &outlen); + } + } + e = t.elapsed(); + qWarning("Interpolate: %10llu usec", e); + speex_resampler_reset_mem(srs1); + speex_resampler_reset_mem(srs2); + } + + t.restart(); + CALLGRIND_START_INSTRUMENTATION; + + for(int i=0;i<nframes;i++) { + float *in = sv[i]; + + inlen = iFrameSize; + outlen = iOutSize1; + speex_resampler_process_float(srs1, 0, in, &inlen, resampframe, &outlen); + + if (! RUNNING_ON_VALGRIND) { +#ifdef SM_OUTPUT + o.write(reinterpret_cast<const char *>(resampframe), outlen * sizeof(float)); +#endif +#ifdef SM_VERIFY + if (vf.read(reinterpret_cast<char *>(verifyframe), outlen * sizeof(float)) == outlen * sizeof(float)) { + for(int j=0;j<outlen;j++) +#ifdef EXACT + if (verifyframe[j] != resampframe[j]) +#else + if (fabs(verifyframe[j]-resampframe[j]) > fabs(verifyframe[j])*0.2f) +#endif + qFatal("Frame %d, Pos %d: SRS1 %.10g <=> %.10g", i, j, verifyframe[j], resampframe[j]); + } +#endif + } + + inlen = iFrameSize; + outlen = iOutSize2; + speex_resampler_process_float(srs2, 0, in, &inlen, resampframe, &outlen); + + if (! RUNNING_ON_VALGRIND) { +#ifdef SM_OUTPUT + o.write(reinterpret_cast<const char *>(resampframe), outlen * sizeof(float)); +#endif + +#ifdef SM_VERIFY + if (vf.read(reinterpret_cast<char *>(verifyframe), outlen * sizeof(float)) == outlen * sizeof(float)) + for(int j=0;j<outlen;j++) +#ifdef EXACT + if (verifyframe[j] != resampframe[j]) +#else + if (fabs(verifyframe[j]-resampframe[j]) > fabs(verifyframe[j])*0.2f) +#endif + qFatal("Frame %d, Pos %d: SRS2 %.10g <=> %.10g", i, j, verifyframe[j], resampframe[j]); +#endif + +#ifdef SM_VERIFY + if ((inlen != iFrameSize) || (outlen != iOutSize2)) + qWarning("%d!=%d %d!=%d (%f)", inlen, iFrameSize, outlen, iOutSize2, fOutSize2); + } else { + qWarning("%d / %d", i, nframes); + } +#endif + } + CALLGRIND_STOP_INSTRUMENTATION; + + e = t.elapsed(); + +#ifdef Q_OS_WIN + if (!SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS)) + qWarning("Application: Failed to reset priority!"); +#endif + + qWarning("Used %llu usec", e); + qWarning("%.2f times realtime", (20000ULL * nframes) / (e * 1.0)); + return 0; +} + +#include "Timer.cpp" diff --git a/speexbuild/ResampMark.pro b/speexbuild/ResampMark.pro new file mode 100644 index 000000000..e50b9460a --- /dev/null +++ b/speexbuild/ResampMark.pro @@ -0,0 +1,11 @@ +include(../compiler.pri) + +TEMPLATE =app +CONFIG += qt warn_on release console +QT -= gui +TARGET = ResampMark +SOURCES = ResampMark.cpp +HEADERS = Timer.h +INCLUDEPATH = ../src ../speex/include +LIBS += -lspeex +LIBPATH += ../release diff --git a/speexbuild/SpeexMark.cpp b/speexbuild/SpeexMark.cpp index 173970bcc..e03556bd0 100644 --- a/speexbuild/SpeexMark.cpp +++ b/speexbuild/SpeexMark.cpp @@ -1,12 +1,17 @@ - #include <QtCore> +static const float tfreq1 = 48000.f; +static const float tfreq2 = 44100.f; + #ifdef Q_OS_WIN #define _WIN32_IE 0x0600 #include <windows.h> #include <shellapi.h> +#define CALLGRIND_START_INSTRUMENTATION +#define CALLGRIND_STOP_INSTRUMENTATION +#define CALLGRIND_ZERO_STATS #else -#define VALGRIND +#include <valgrind/callgrind.h> #endif #include <math.h> @@ -15,19 +20,14 @@ #include <speex/speex_preprocess.h> #include <speex/speex_echo.h> #include <speex/speex_callbacks.h> +#include <speex/speex_resampler.h> - -#ifdef VALGRIND -#include <valgrind/callgrind.h> -#endif #include "Timer.h" int main(int argc, char **argv) { -#ifdef VALGRIND CALLGRIND_STOP_INSTRUMENTATION; CALLGRIND_ZERO_STATS; -#endif QCoreApplication a(argc, argv); @@ -55,6 +55,10 @@ int main(int argc, char **argv) { int iFrameSize; speex_encoder_ctl(enc, SPEEX_GET_FRAME_SIZE, &iFrameSize); + + void *dec = speex_decoder_init(&speex_wb_mode); + iarg = 1; + speex_decoder_ctl(dec, SPEEX_SET_ENH, &iarg); SpeexPreprocessState *spp = speex_preprocess_state_init(iFrameSize, 16000); iarg = 1; @@ -89,7 +93,23 @@ int main(int argc, char **argv) { for(int i=0;i<nframes;i++) { sv.append(reinterpret_cast<short *>(v[i].data())); } - + + float oframe[2048]; + float resampframe[32768]; + float verifyframe[32768]; + + const float sfraq1 = tfreq1 / 16000.0f; + float fOutSize1 = iFrameSize * sfraq1; + int iOutSize1 = lroundf(fOutSize1); + + const float sfraq2 = tfreq2 / 16000.0f; + float fOutSize2 = iFrameSize * sfraq2; + int iOutSize2 = lroundf(fOutSize2); + + int err; + SpeexResamplerState *srs1 = speex_resampler_init(1, 16000, lroundf(tfreq1), 3, &err); + SpeexResamplerState *srs2 = speex_resampler_init(1, 16000, lroundf(tfreq2), 3, &err); + SpeexBits sb; speex_bits_init(&sb); @@ -98,31 +118,53 @@ int main(int argc, char **argv) { qWarning("Application: Failed to set priority!"); #endif + int len; + char data[4096]; + spx_uint32_t inlen; + spx_uint32_t outlen; + Timer t; t.restart(); -#ifdef VALGRIND + nframes = qMin(nframes, 10); + CALLGRIND_START_INSTRUMENTATION; -#endif + for(int i=0;i<nframes-2;i++) { speex_bits_reset(&sb); + speex_echo_cancellation(ses, sv[i], sv[i+2], tframe); + speex_preprocess_run(spp, tframe); + speex_encode_int(enc, tframe, &sb); + len = speex_bits_nbytes(&sb); + speex_bits_write(&sb, data, len); + + speex_bits_read_from(&sb, data, len); + speex_decode(dec, &sb, oframe); + + inlen = iFrameSize; + outlen = iOutSize1; + speex_resampler_process_float(srs1, 0, oframe, &inlen, resampframe, &outlen); + + inlen = iFrameSize; + outlen = iOutSize2; + speex_resampler_process_float(srs2, 0, oframe, &inlen, resampframe, &outlen); + } -#ifdef VALGRIND CALLGRIND_STOP_INSTRUMENTATION; -#endif + + quint64 e = t.elapsed(); #ifdef Q_OS_WIN if (!SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS)) qWarning("Application: Failed to reset priority!"); #endif - quint64 e = t.elapsed(); - qWarning("Used %llu usec", e); qWarning("%.2f times realtime", (20000ULL * nframes) / (e * 1.0)); + return 0; } #include "Timer.cpp" diff --git a/speexbuild/SpeexMark.pro b/speexbuild/SpeexMark.pro index edc961983..8feac26b2 100644 --- a/speexbuild/SpeexMark.pro +++ b/speexbuild/SpeexMark.pro @@ -1,3 +1,5 @@ +include(../compiler.pri) + TEMPLATE =app CONFIG += qt warn_on release console QT -= gui @@ -7,10 +9,3 @@ HEADERS = Timer.h INCLUDEPATH = ../src ../speex/include LIBS += -lspeex LIBPATH += ../release - -win32 { - QMAKE_CXX = icl - QMAKE_CXXFLAGS += -Qrestrict - QMAKE_CXXFLAGS_RELEASE += -O3 -QxK -Qip -Qipo - QMAKE_LINK = xilink -} diff --git a/speexbuild/speexbuild.pro b/speexbuild/speexbuild.pro index b4e6f2cd6..6341659c9 100644 --- a/speexbuild/speexbuild.pro +++ b/speexbuild/speexbuild.pro @@ -3,6 +3,8 @@ include(../compiler.pri) TEMPLATE = lib CONFIG -= qt CONFIG += staticlib debug_and_release +CONFIG -= warn_on +CONFIG += warn_off VPATH = ../speex/libspeex TARGET = speex DEFINES += NDEBUG HAVE_CONFIG_H |