void printall() { for (int i = 0; i < 65536; i++) { float f = h2f(i); printf("0x%x -> %g 0x%x\n", i, f, floatToBits(f)); } for (int e = -10; e < 10; e++) { double f = pow(10.0, e); int i = f2h(f); printf("%g -> 0x%x ->%g\n", f, i, h2f(i)); } }
void h2ftimingtest() { float total = 0; for (int j = 0; j < 30*1024; j++) { for (int i = 1024; i < 31740; i++) total += h2f(i); } printf("%g\n", total); }
int spotcheck(int i, float f) { float f2 = h2f(i); if (fabs((f-f2)/f) > 1e-6) { printf("error: 0x%x->%.7g, expected ->%.7g, \n", i, f2, f); return 1; } return 0; }
int testconvert(int i) { float f = h2f(i); int i2 = f2h(f); if (i != i2) { printf("error: 0x%x -> %g -> 0x%x\n", i, f, i2); return 1; } return 0; }
OneDataMultiplierMHT::OneDataMultiplierMHT(double AFreq, int dataBySecond, double rep, double win_factor, int minHT, int maxHT) : m_rep(int(rep)) { int nbHT = maxHT - minHT + 1; m_components.resize(nbHT); m_convolutions.resize(nbHT); for(int h=minHT; h<=maxHT; h++) m_convolutions[h-minHT] = new SingleHalfTone(AFreq, dataBySecond, rep, win_factor, h); // m_length = int(dataBySecond * 1.0/h2f(minHT, AFreq)); m_length = int(rep/FACTOR * dataBySecond * 1.0/h2f(minHT, AFreq)); m_size = int(rep * dataBySecond * 1.0/h2f(minHT, AFreq)); m_fwd_plan = rfftw_create_plan(m_size, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_OUT_OF_PLACE | FFTW_USE_WISDOM); m_bck_plan = rfftw_create_plan(m_size, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE | FFTW_OUT_OF_PLACE | FFTW_USE_WISDOM); m_in = new fftw_real[m_size]; m_out = new fftw_real[m_size]; }
int overflowtest(float f) { uint32_t fi = floatToBits(f); int i = f2h(f); int e = 0x7c00 | ((fi>>16)&0x8000); if (i != e) { printf("error: %g->0x%x->%g, expected 0x%x->%sinf\n", f, i, h2f(i), e, (e&0x8000) ? "-" : ""); return 1; } return 0; }
int excheck(uint32_t val) { float f = bitsToFloat(val); int i = f2h(f); float f2 = h2f(i); if (memcmp(&f, &f2, 4)) { printf("error: %g(0x%0x)->0x%x->%g(0x%0x)\n", f, floatToBits(f), i, f2, floatToBits(f2)); return 1; } return 0; }
void f2htimingtest() { int total = 0; float f[65536]; for (int i = 0; i < 65536; i++) { f[i] = h2f(i); if (!isfinite(f[i])) f[i] = 1; } for (int j = 0; j < 30*1024; j++) { for (int i = 1024; i < 31740; i++) total += f2h(f[i]); } printf("%d\n", total); }
int testround(float val) { int i = f2h(val); float f = fabs(h2f(i)-val); float f1 = fabs(h2f(i-1)-val); float f2 = fabs(h2f(i+1)-val); if (f1 < f) { printf("error: %g->0x%x->%g, expected ->0x%x->%g\n", val, i, h2f(i), i-1, h2f(i-1)); return 1; } if (f2 < f) { printf("error: %g->0x%x->%g, expected ->0x%x->%g\n", val, i, h2f(i), i+1, h2f(i+1)); return 1; } return 0; }
void AutocorrelationAlgo::init() { setMinMaxLength(int(GetSamplingRate()/h2f(GetSemitoneMax())), int(GetSamplingRate()/h2f(GetSemitoneMin()))); }
/* * on peut imaginer des cas qui mettent en échec cette procédure: * on selectionne un zéro qui n'en n'est pas un une periode plus * tard et si un autre zéro se trouve dans la zone de tolérance la longeur * ainsi calculée entre ces deux zéro (qui ne se correspondent donc pas) sera fausse. * example: une fréquence très basse avec une seule harmonique très très * haute. * - il faut utiliser des zéros significatifs ... et ... et ... et voilà . * - ou encore écarter les solutions trop élognées de la moyenne */ double GetAveragePeriodFromApprox(const std::deque<double>& queue, int approx, int n) { if(GetAFreq()<=0.0 || GetSamplingRate()<=0.0 || int(queue.size())<approx) return 0.0; deque<int> ups; // the upper peeks // parse the whole buffer, for n zeros for(int i=0; int(ups.size())<n && i+1<int(queue.size()); i++) if(queue[i]<0 && queue[i+1]>0) // if it cross the axis ups.push_back(i); // cout << "approx=" << approx << " ups.size()=" << ups.size(); if(ups.empty()) return 0.0; double ht = f2hf(double(GetSamplingRate())/approx); int period_low_bound = int(GetSamplingRate()/h2f(ht+1))-2; int period_high_bound = int(GetSamplingRate()/h2f(ht-1))+2; // cout << " ht=" << ht << " lb=" << period_low_bound << " rb=" << period_high_bound; // cout << " periods=("; double period = 0.0; int count = 0; for(int i=0; i<int(ups.size()) && count<n; i++) { int i_seek = ups[i] + approx; int lower_i_seek = i_seek; int low_bound = ups[i] + period_low_bound; int higher_i_seek = i_seek; int high_bound = std::min(int(queue.size())-1, ups[i]+period_high_bound); // cout << "{" << low_bound << ":" << i_seek << ":" << high_bound << "}"; if(low_bound+1>=int(queue.size())) i = ups.size(); // stop loop else { if(!(queue[i_seek]<=0.0 && queue[i_seek+1]>0.0)) { while(lower_i_seek>low_bound && !(queue[lower_i_seek]<=0.0 && queue[lower_i_seek+1]>0.0)) lower_i_seek--; while(higher_i_seek<high_bound && !(queue[higher_i_seek]<=0.0 && queue[higher_i_seek+1]>0.0)) higher_i_seek++; if(i_seek-lower_i_seek < higher_i_seek-i_seek) // take the nearest to i_seek i_seek = lower_i_seek; else i_seek = higher_i_seek; } // cout << i_seek << "=>"; if(low_bound<i_seek && i_seek<high_bound) { double per = InterpolatedPeriod(queue, ups[i], i_seek); // cout << "f=" << GetSamplingRate()/per << " "; period += per; count++; } } } if(count==0) return 0.0; period /= count; // cout << ")=" << GetSamplingRate()/period << "(" << count << ")" << endl; return period; }