diff options
Diffstat (limited to 'noatun-plugins/nexscope/input.cpp')
-rw-r--r-- | noatun-plugins/nexscope/input.cpp | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/noatun-plugins/nexscope/input.cpp b/noatun-plugins/nexscope/input.cpp new file mode 100644 index 0000000..4c787e7 --- /dev/null +++ b/noatun-plugins/nexscope/input.cpp @@ -0,0 +1,238 @@ + +#include "nex.h" +#include "convolve.h" + +#include <stdlib.h> +#include <unistd.h> +#include <math.h> +#include <noatun/plugin.h> + +Input::Input() +{ + memset(haystack, 0, sizeof(float)*512); + state=new convolve_state; + + float d, *costab, *sintab; + long ul, ndiv2 = 512 / 2; + + for (costab = fhtTab, sintab = fhtTab + 512 / 2 + 1, ul = 0; ul < 512; ul++) + { + d = PI * ul / ndiv2; + *costab = *sintab = ::cos(d); + + costab += 2, sintab += 2; + if (sintab > fhtTab + 512 * 2) + sintab = fhtTab + 1; + } + + notifier=0; + mScope=0; + + connect(); +} + +Input::~Input() +{ + delete mScope; + std::cerr<< "Scope gone"<< std::endl; + delete notifier; +// delete [] audio[2]; +// delete [] audio[3]; +// delete [] audio[4]; +// delete [] audio[5]; +} + +void Input::setConvolve(bool on) +{ + mConvolve=on; +} + +void Input::connect() +{ + do + { + delete notifier; + delete mScope; + ok=true; + mScope=new StereoScope(10, Visualization::noatunPid()); + mScope->setSamples(samples>(512+256) ? samples : samples+256); + + notifier=new QObject; + new BoolNotifier(&ok, new ExitNotifier(Visualization::noatunPid(), notifier), notifier); + } while (!mScope->connected()); +} + +// [0] pcm left +// [1] pcm right +// [2] pcm center +// [3] FFT (FHT) left +// [4] FFT right +// [5] FFT center + +void Input::getAudio(float **audio) +{ + static bool first=true; + if (first) + { + audio[2]=new float[samples]; + audio[3]=new float[fhtsamples]; + audio[4]=new float[fhtsamples]; + audio[5]=new float[fhtsamples]; + first=false; + } + + if (!ok || !mScope->connected()) + { + std::cerr << "reconnect" <<std::endl; + connect(); + return; +// delete mScope; +// ::sleep(7); +// mScope=new StereoScope(10, Visualization::noatunPid()); +// mScope->setSamples(samples); + } + std::vector<float> *left, *right; + mScope->scopeData(left, right); + + register float *inleft=&*left->begin(); + register float *inright=&*right->begin(); + + + int offset=0; + if (mConvolve) + { // find the offset + for (register int i=0; i<512+256; ++i) + temp[i]=inleft[i]+inright[i]; + offset=::convolve_match(haystack, temp, state); + if (offset==-1) offset=0; + inleft+=offset; + inright+=offset; + + for (register int i=0; i<512; ++i) + { + haystack[i]*=.5; + haystack[i]+=temp[i+offset]; + } + } + + memcpy(outleft, inleft, samples*sizeof(float)); + memcpy(outright, inright, samples*sizeof(float)); + + audio[0]=outleft; + audio[1]=outright; + + // center channel + for (int i=0; i<samples; ++i) + audio[2][i]=(audio[0][i]+audio[1][i])*.5; + + // perform the FFT (FHT in this case) + memcpy(audio[3], audio[0], fhtsamples); + memcpy(audio[4], audio[1], fhtsamples); + + fht(audio[3]); + fht(audio[4]); + + for (int i=0; i<fhtsamples; ++i) + { + audio[5][i]=(audio[3][i]+audio[4][i])*.5; + } + + + delete left; + delete right; +} + +void Input::fht(float *p) +{ + long i; + float *q; + transform(p, fhtsamples, 0); + + *p = (*p * *p), *p += *p, p++; + + for (i = 1, q = p + fhtsamples - 2; i < (fhtsamples / 2); i++, --q) + *p++ = (*p * *p) + (*q * *q); + + for (long i = 0; i < (fhtsamples / 2); i++) + *p++ *= .5; +} + +void Input::transform(float *p, long n, long k) +{ + if (n == 8) + { + transform8(p + k); + return; + } + + long i, j, ndiv2 = n / 2; + float a, *t1, *t2, *t3, *t4, *ptab, *pp; + + for (i = 0, t1 = fhtBuf, t2 = fhtBuf + ndiv2, pp = &p[k]; i < ndiv2; i++) + *t1++ = *pp++, *t2++ = *pp++; + + memcpy(p + k, fhtBuf, sizeof(float) * n); + + transform(p, ndiv2, k); + transform(p, ndiv2, k + ndiv2); + + j = 512 / ndiv2 - 1; + t1 = fhtBuf; + t2 = t1 + ndiv2; + t3 = p + k + ndiv2; + ptab = fhtTab; + pp = p + k; + + a = *ptab++ * *t3++; + a += *ptab * *pp; + ptab += j; + + *t1++ = *pp + a; + *t2++ = *pp++ - a; + + for (i = 1, t4 = p + k + n; i < ndiv2; i++, ptab += j) + { + a = *ptab++ * *t3++; + a += *ptab * *--t4; + + *t1++ = *pp + a; + *t2++ = *pp++ - a; + } + + memcpy(p + k, fhtBuf, sizeof(float) * n); + +} + +void Input::transform8(float *p) +{ + float a, b, c, d, e, f, g, h, + b_f2, d_h2, sqrt2 = M_SQRT2, + a_c_eg, a_ce_g, ac_e_g, aceg, + b_df_h, bdfh; + + a = *p++, b = *p++, c = *p++, d = *p++; + e = *p++, f = *p++, g = *p++, h = *p; + b_f2 = (b - f) * sqrt2; + d_h2 = (d - h) * sqrt2; + + a_c_eg = a - c - e + g; + a_ce_g = a - c + e - g; + ac_e_g = a + c - e - g; + aceg = a + c + e + g; + + b_df_h = b - d + f - h; + bdfh = b + d + f + h; + + *p = a_c_eg - d_h2; + *--p = a_ce_g - b_df_h; + *--p = ac_e_g - b_f2; + *--p = aceg - bdfh; + *--p = a_c_eg + d_h2; + *--p = a_ce_g + b_df_h; + *--p = ac_e_g + b_f2; + *--p = aceg + bdfh; +} + + + + |