void aubio_pitchspecacf_do (aubio_pitchspecacf_t * p, const fvec_t * input, fvec_t * output) { uint_t l, tau; fvec_t *fftout = p->fftout; // window the input for (l = 0; l < input->length; l++) { p->winput->data[l] = p->win->data[l] * input->data[l]; } // get the real / imag parts of its fft aubio_fft_do_complex (p->fft, p->winput, fftout); for (l = 0; l < input->length / 2 + 1; l++) { p->sqrmag->data[l] = SQR(fftout->data[l]); } // get the real / imag parts of the fft of the squared magnitude aubio_fft_do_complex (p->fft, p->sqrmag, fftout); // copy real part to acf for (l = 0; l < fftout->length / 2 + 1; l++) { p->acf->data[l] = fftout->data[l]; } // get the minimum tau = fvec_min_elem (p->acf); // get the interpolated minimum output->data[0] = fvec_quadratic_peak_pos (p->acf, tau) * 2.; }
/* all the above in one */ void aubio_pitchyin_do (aubio_pitchyin_t * o, fvec_t * input, fvec_t * out) { smpl_t tol = o->tol; fvec_t *yin = o->yin; uint_t j, tau = 0; sint_t period; smpl_t tmp = 0., tmp2 = 0.; yin->data[0] = 1.; for (tau = 1; tau < yin->length; tau++) { yin->data[tau] = 0.; for (j = 0; j < yin->length; j++) { tmp = input->data[j] - input->data[j + tau]; yin->data[tau] += SQR (tmp); } tmp2 += yin->data[tau]; yin->data[tau] *= tau / tmp2; period = tau - 3; if (tau > 4 && (yin->data[period] < tol) && (yin->data[period] < yin->data[period + 1])) { out->data[0] = fvec_quadratic_peak_pos (yin, period); goto beach; } } out->data[0] = fvec_quadratic_peak_pos (yin, fvec_min_elem (yin)); beach: return; }
void aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, fvec_t * output) { uint_t tau, l; uint_t halfperiod; smpl_t tmp, sum; cvec_t *res = (cvec_t *) p->res; fvec_t *yin = (fvec_t *) p->yinfft; l = 0; tmp = 0.; sum = 0.; for (l = 0; l < input->length; l++) { p->winput->data[l] = p->win->data[l] * input->data[l]; } aubio_fft_do (p->fft, p->winput, p->fftout); for (l = 0; l < p->fftout->length; l++) { p->sqrmag->data[l] = SQR (p->fftout->norm[l]); p->sqrmag->data[l] *= p->weight->data[l]; } for (l = 1; l < p->fftout->length; l++) { p->sqrmag->data[(p->fftout->length - 1) * 2 - l] = SQR (p->fftout->norm[l]); p->sqrmag->data[(p->fftout->length - 1) * 2 - l] *= p->weight->data[l]; } for (l = 0; l < p->sqrmag->length / 2 + 1; l++) { sum += p->sqrmag->data[l]; } sum *= 2.; aubio_fft_do (p->fft, p->sqrmag, res); yin->data[0] = 1.; for (tau = 1; tau < yin->length; tau++) { yin->data[tau] = sum - res->norm[tau] * COS (res->phas[tau]); tmp += yin->data[tau]; yin->data[tau] *= tau / tmp; } tau = fvec_min_elem (yin); if (yin->data[tau] < p->tol) { /* no interpolation */ //return tau; /* 3 point quadratic interpolation */ //return fvec_quadint_min(yin,tau,1); /* additional check for (unlikely) octave doubling in higher frequencies */ if (tau > 35) { output->data[0] = fvec_quadint (yin, tau); } else { /* should compare the minimum value of each interpolated peaks */ halfperiod = FLOOR (tau / 2 + .5); if (yin->data[halfperiod] < p->tol) output->data[0] = fvec_quadint (yin, halfperiod); else output->data[0] = fvec_quadint (yin, tau); } } else { output->data[0] = 0.; } }
void aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, fvec_t * output) { uint_t tau, l; uint_t length = p->fftout->length; uint_t halfperiod; fvec_t *fftout = p->fftout; fvec_t *yin = p->yinfft; smpl_t tmp = 0., sum = 0.; // window the input for (l = 0; l < input->length; l++) { p->winput->data[l] = p->win->data[l] * input->data[l]; } // get the real / imag parts of its fft aubio_fft_do_complex (p->fft, p->winput, fftout); // get the squared magnitude spectrum, applying some weight p->sqrmag->data[0] = SQR(fftout->data[0]); p->sqrmag->data[0] *= p->weight->data[0]; for (l = 1; l < length / 2; l++) { p->sqrmag->data[l] = SQR(fftout->data[l]) + SQR(fftout->data[length - l]); p->sqrmag->data[l] *= p->weight->data[l]; p->sqrmag->data[length - l] = p->sqrmag->data[l]; } p->sqrmag->data[length / 2] = SQR(fftout->data[length / 2]); p->sqrmag->data[length / 2] *= p->weight->data[length / 2]; // get sum of weighted squared mags for (l = 0; l < length / 2 + 1; l++) { sum += p->sqrmag->data[l]; } sum *= 2.; // get the real / imag parts of the fft of the squared magnitude aubio_fft_do_complex (p->fft, p->sqrmag, fftout); yin->data[0] = 1.; for (tau = 1; tau < yin->length; tau++) { // compute the square differences yin->data[tau] = sum - fftout->data[tau]; // and the cumulative mean normalized difference function tmp += yin->data[tau]; if (tmp != 0) { yin->data[tau] *= tau / tmp; } else { yin->data[tau] = 1.; } } // find best candidates tau = fvec_min_elem (yin); if (yin->data[tau] < p->tol) { // no interpolation, directly return the period as an integer //output->data[0] = tau; //return; // 3 point quadratic interpolation //return fvec_quadratic_peak_pos (yin,tau,1); /* additional check for (unlikely) octave doubling in higher frequencies */ if (tau > p->short_period) { output->data[0] = fvec_quadratic_peak_pos (yin, tau); } else { /* should compare the minimum value of each interpolated peaks */ halfperiod = FLOOR (tau / 2 + .5); if (yin->data[halfperiod] < p->tol) output->data[0] = fvec_quadratic_peak_pos (yin, halfperiod); else output->data[0] = fvec_quadratic_peak_pos (yin, tau); } } else { output->data[0] = 0.; } }