#include static const float tfreq1 = 48000.f; static const float tfreq2 = 44100.f; static const int qual = 3; static const int loops = 2000 / qual; // static const int loops = 1; #define SM_VERIFY // #define EXACT #ifdef Q_OS_WIN #define _WIN32_IE 0x0600 #include #include #include #define CALLGRIND_START_INSTRUMENTATION #define CALLGRIND_STOP_INSTRUMENTATION #define CALLGRIND_ZERO_STATS #define RUNNING_ON_VALGRIND 0 #else #include #include #include #endif #include #include #include #include "Timer.h" template static inline double veccomp(const QVector &a, const QVector &b, const char *n) { long double rms = 0.0; long double gdiff = 0.0; if (a.size() != b.size()) { qFatal("%s: %d <=> %d", n, a.size(), b.size()); } for (int i=0;i gdiff) gdiff = diff; #ifdef EXACT if (a[i] != b[i]) { #else union { T tv; quint32 uv; } v1, v2; v1.uv = v2.uv = 0; v1.tv = a[i]; v2.tv = b[i]; if (fabsf(a[i] - b[i]) > 1) { qWarning("%08x %08x %08x", v1.uv, v2.uv, v1.uv ^ v2.uv); #endif qFatal("%s: Offset %d: %.10g <=> %.10g", n, i, static_cast(a[i]), static_cast(b[i])); } } return gdiff; return sqrt(rms / a.size()); } template QPair confint(const QVector &vecin) { long double avg = 0.0; long double stddev = 0.0; QVector vec = vecin; qSort(vec.begin(), vec.end()); for (int i=0;i(static_cast(avg), static_cast(1.96 * stddev)); } 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); QFile o("output.raw"); if (!(RUNNING_ON_VALGRIND)) if (! o.open(QIODevice::WriteOnly)) qFatal("Failed to open output!"); QFile vf((argc >= 3) ? argv[2] : "verify.raw"); if (! vf.open(QIODevice::ReadOnly)) { qWarning("Failed to open validate file!"); } QDataStream out(&o); QDataStream verify(&vf); const int iFrameSize = 320; QVector 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 qvInShort; QVector qvIn; QVector qvDirect; QVector qvInterpolate; QVector qvInterpolateMC; QVector qvInterpolateShort; QVector qv8; QVector qv96; 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 iOutSize8 = iFrameSize / 2; int iOutSize96 = iFrameSize * 6; if (RUNNING_ON_VALGRIND) nframes = qMin(nframes, 10); QVector fInput(nframes * iFrameSize); QVector fDirect(nframes * iOutSize1); QVector fInterpolate(nframes * iOutSize2); QVector fInterpolateMC(nframes * iOutSize2); QVector sInterpolate(nframes * iOutSize2); QVector f96(nframes * iOutSize96); QVector f8(nframes *iOutSize8); for (int i=0;i(v[i].data()); float *f = fInput.data() + i * iFrameSize; for (int j=0;j qvTimes; QPair ci; for (int j=0;j 8: %8llu +/- %3llu usec (%d)", ci.first, ci.second, qvTimes.count()); qvTimes.clear(); t.restart(); for (int j=0;j 96: %8llu +/- %3llu usec (%d)", ci.first, ci.second, qvTimes.count()); speex_resampler_reset_mem(srs1); speex_resampler_reset_mem(srs2); } t.restart(); CALLGRIND_START_INSTRUMENTATION; for (int i=0;i fMagic; for (int f=0;f<10;f++) { float fbuff[32767]; speex_resampler_set_rate(srs1, 16000, freq[f]); for (int q = 0;q < 10;q++) { speex_resampler_set_quality(srs1, (3*q) % 7); inlen = iFrameSize; outlen = 32767; speex_resampler_process_float(srs1, 0, qvIn[(f*10+q) % nframes], &inlen, fbuff, &outlen); for (int j=0;j vDirect; QVector vInterpolate; QVector vsInterpolate; QVector vMagic; QVector vInterpolateMC; out << fDirect << fInterpolate << sInterpolate << fMagic << fInterpolateMC; if (vf.isOpen()) { verify >> vDirect >> vInterpolate >> vsInterpolate >> vMagic >> vInterpolateMC; double rmsd = veccomp(vDirect, fDirect, "SRS1"); double rmsi = veccomp(vInterpolate, fInterpolate, "SRS2"); veccomp(vsInterpolate, sInterpolate, "SRS2i"); veccomp(vMagic, fMagic, "Magic"); veccomp(vInterpolateMC, fInterpolateMC, "MC"); qWarning("Direct: %g", rmsd); qWarning("Interp: %g", rmsi); } else { qWarning("No verification!"); } } return 0; } #include "Timer.cpp"