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.; }
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.; } }
void aubio_fft_do(aubio_fft_t * s, fvec_t * input, cvec_t * spectrum) { aubio_fft_do_complex(s, input, s->compspec); aubio_fft_get_spectrum(s->compspec, spectrum); }