From 168337eebd7faec09b72a3af3541542470b514b7 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Fri, 4 Dec 2009 01:44:41 +0100 Subject: [PATCH] src/pitch: switch to mono --- src/pitch/pitch.c | 94 +++++++++-------------- src/pitch/pitch.h | 7 +- src/pitch/pitchfcomb.c | 99 ++++++++++++------------ src/pitch/pitchfcomb.h | 4 +- src/pitch/pitchmcomb.c | 89 +++++++++++----------- src/pitch/pitchmcomb.h | 4 +- src/pitch/pitchschmitt.c | 10 +-- src/pitch/pitchyin.c | 85 ++++++++++----------- src/pitch/pitchyinfft.c | 158 +++++++++++++++++++-------------------- 9 files changed, 252 insertions(+), 298 deletions(-) diff --git a/src/pitch/pitch.c b/src/pitch/pitch.c index fd1944d7..3861d057 100644 --- a/src/pitch/pitch.c +++ b/src/pitch/pitch.c @@ -113,7 +113,7 @@ freqconvpass (smpl_t f, uint_t srate UNUSED, uint_t bufsize UNUSED) aubio_pitch_t * new_aubio_pitch (char_t * pitch_mode, - uint_t bufsize, uint_t hopsize, uint_t channels, uint_t samplerate) + uint_t bufsize, uint_t hopsize, uint_t samplerate) { aubio_pitch_t *p = AUBIO_NEW (aubio_pitch_t); aubio_pitch_type pitch_type; @@ -141,30 +141,30 @@ new_aubio_pitch (char_t * pitch_mode, p->bufsize = bufsize; switch (p->type) { case aubio_pitcht_yin: - p->buf = new_fvec (bufsize, channels); + p->buf = new_fvec (bufsize); p->yin = new_aubio_pitchyin (bufsize); p->callback = aubio_pitch_do_yin; aubio_pitchyin_set_tolerance (p->yin, 0.15); break; case aubio_pitcht_mcomb: - p->pv = new_aubio_pvoc (bufsize, hopsize, channels); - p->fftgrain = new_cvec (bufsize, channels); - p->mcomb = new_aubio_pitchmcomb (bufsize, hopsize, channels); - p->filter = new_aubio_filter_c_weighting (samplerate, channels); + p->pv = new_aubio_pvoc (bufsize, hopsize); + p->fftgrain = new_cvec (bufsize); + p->mcomb = new_aubio_pitchmcomb (bufsize, hopsize); + p->filter = new_aubio_filter_c_weighting (samplerate); p->callback = aubio_pitch_do_mcomb; break; case aubio_pitcht_fcomb: - p->buf = new_fvec (bufsize, channels); - p->fcomb = new_aubio_pitchfcomb (bufsize, hopsize, channels); + p->buf = new_fvec (bufsize); + p->fcomb = new_aubio_pitchfcomb (bufsize, hopsize); p->callback = aubio_pitch_do_fcomb; break; case aubio_pitcht_schmitt: - p->buf = new_fvec (bufsize, channels); + p->buf = new_fvec (bufsize); p->schmitt = new_aubio_pitchschmitt (bufsize); p->callback = aubio_pitch_do_schmitt; break; case aubio_pitcht_yinfft: - p->buf = new_fvec (bufsize, channels); + p->buf = new_fvec (bufsize); p->yinfft = new_aubio_pitchyinfft (bufsize); p->callback = aubio_pitch_do_yinfft; aubio_pitchyinfft_set_tolerance (p->yinfft, 0.85); @@ -210,17 +210,13 @@ del_aubio_pitch (aubio_pitch_t * p) void aubio_pitch_slideblock (aubio_pitch_t * p, fvec_t * ibuf) { - uint_t i, j = 0, overlap_size = 0; + uint_t j = 0, overlap_size = 0; overlap_size = p->buf->length - ibuf->length; - for (i = 0; i < p->buf->channels; i++) { - for (j = 0; j < overlap_size; j++) { - p->buf->data[i][j] = p->buf->data[i][j + ibuf->length]; - } + for (j = 0; j < overlap_size; j++) { + p->buf->data[j] = p->buf->data[j + ibuf->length]; } - for (i = 0; i < ibuf->channels; i++) { - for (j = 0; j < ibuf->length; j++) { - p->buf->data[i][j + overlap_size] = ibuf->data[i][j]; - } + for (j = 0; j < ibuf->length; j++) { + p->buf->data[j + overlap_size] = ibuf->data[j]; } } @@ -282,41 +278,32 @@ aubio_pitch_set_tolerance (aubio_pitch_t * p, smpl_t tol) void aubio_pitch_do (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf) { - uint_t i; p->callback (p, ibuf, obuf); - for (i = 0; i < obuf->channels; i++) { - p->freqconv (obuf->data[i][0], p->srate, p->bufsize); - } + obuf->data[0] = p->freqconv (obuf->data[0], p->srate, p->bufsize); } void aubio_pitch_do_mcomb (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf) { - uint_t i; aubio_filter_do (p->filter, ibuf); aubio_pvoc_do (p->pv, ibuf, p->fftgrain); aubio_pitchmcomb_do (p->mcomb, p->fftgrain, obuf); - for (i = 0; i < obuf->channels; i++) { - obuf->data[i][0] = aubio_bintofreq (obuf->data[i][0], p->srate, p->bufsize); - } + obuf->data[0] = aubio_bintofreq (obuf->data[0], p->srate, p->bufsize); } void aubio_pitch_do_yin (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf) { smpl_t pitch = 0.; - uint_t i; aubio_pitch_slideblock (p, ibuf); aubio_pitchyin_do (p->yin, p->buf, obuf); - for (i = 0; i < obuf->channels; i++) { - pitch = obuf->data[i][0]; - if (pitch > 0) { - pitch = p->srate / (pitch + 0.); - } else { - pitch = 0.; - } - obuf->data[i][0] = pitch; + pitch = obuf->data[0]; + if (pitch > 0) { + pitch = p->srate / (pitch + 0.); + } else { + pitch = 0.; } + obuf->data[0] = pitch; } @@ -324,45 +311,36 @@ void aubio_pitch_do_yinfft (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf) { smpl_t pitch = 0.; - uint_t i; aubio_pitch_slideblock (p, ibuf); aubio_pitchyinfft_do (p->yinfft, p->buf, obuf); - for (i = 0; i < obuf->channels; i++) { - pitch = obuf->data[i][0]; - if (pitch > 0) { - pitch = p->srate / (pitch + 0.); - } else { - pitch = 0.; - } - obuf->data[i][0] = pitch; + pitch = obuf->data[0]; + if (pitch > 0) { + pitch = p->srate / (pitch + 0.); + } else { + pitch = 0.; } + obuf->data[0] = pitch; } void aubio_pitch_do_fcomb (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * out) { - uint_t i; aubio_pitch_slideblock (p, ibuf); aubio_pitchfcomb_do (p->fcomb, p->buf, out); - for (i = 0; i < out->channels; i++) { - out->data[i][0] = aubio_bintofreq (out->data[i][0], p->srate, p->bufsize); - } + out->data[0] = aubio_bintofreq (out->data[0], p->srate, p->bufsize); } void aubio_pitch_do_schmitt (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * out) { smpl_t period, pitch = 0.; - uint_t i; aubio_pitch_slideblock (p, ibuf); aubio_pitchschmitt_do (p->schmitt, p->buf, out); - for (i = 0; i < out->channels; i++) { - period = out->data[i][0]; - if (period > 0) { - pitch = p->srate / period; - } else { - pitch = 0.; - } - out->data[i][0] = pitch; + period = out->data[0]; + if (period > 0) { + pitch = p->srate / period; + } else { + pitch = 0.; } + out->data[0] = pitch; } diff --git a/src/pitch/pitch.h b/src/pitch/pitch.h index 84270505..b00c45a0 100644 --- a/src/pitch/pitch.h +++ b/src/pitch/pitch.h @@ -40,8 +40,8 @@ typedef struct _aubio_pitch_t aubio_pitch_t; /** execute pitch detection on an input signal frame \param o pitch detection object as returned by new_aubio_pitch() - \param in input signal of size [hop_size x channels] - \param out output pitch candidates of size [1 x channels] + \param in input signal of size [hop_size] + \param out output pitch candidates of size [1] */ void aubio_pitch_do (aubio_pitch_t * o, fvec_t * in, fvec_t * out); @@ -66,12 +66,11 @@ void del_aubio_pitch (aubio_pitch_t * o); \param method set pitch detection algorithm \param buf_size size of the input buffer to analyse \param hop_size step size between two consecutive analysis instant - \param channels number of channels to analyse \param samplerate sampling rate of the signal */ aubio_pitch_t *new_aubio_pitch (char_t * method, - uint_t buf_size, uint_t hop_size, uint_t channels, uint_t samplerate); + uint_t buf_size, uint_t hop_size, uint_t samplerate); /** set the output unit of the pitch detection object diff --git a/src/pitch/pitchfcomb.c b/src/pitch/pitchfcomb.c index 2cf2758c..83bc6b11 100644 --- a/src/pitch/pitchfcomb.c +++ b/src/pitch/pitchfcomb.c @@ -48,15 +48,15 @@ struct _aubio_pitchfcomb_t }; aubio_pitchfcomb_t * -new_aubio_pitchfcomb (uint_t bufsize, uint_t hopsize, uint_t channels) +new_aubio_pitchfcomb (uint_t bufsize, uint_t hopsize) { aubio_pitchfcomb_t *p = AUBIO_NEW (aubio_pitchfcomb_t); p->fftSize = bufsize; p->stepSize = hopsize; - p->winput = new_fvec (bufsize, 1); - p->fftOut = new_cvec (bufsize, 1); - p->fftLastPhase = new_fvec (bufsize, channels); - p->fft = new_aubio_fft (bufsize, 1); + p->winput = new_fvec (bufsize); + p->fftOut = new_cvec (bufsize); + p->fftLastPhase = new_fvec (bufsize); + p->fft = new_aubio_fft (bufsize); p->win = new_aubio_window ("hanning", bufsize); return p; } @@ -65,69 +65,66 @@ new_aubio_pitchfcomb (uint_t bufsize, uint_t hopsize, uint_t channels) void aubio_pitchfcomb_do (aubio_pitchfcomb_t * p, fvec_t * input, fvec_t * output) { - uint_t i, k, l, maxharm = 0; + uint_t k, l, maxharm = 0; smpl_t phaseDifference = TWO_PI * (smpl_t) p->stepSize / (smpl_t) p->fftSize; aubio_fpeak_t peaks[MAX_PEAKS]; - for (i = 0; i < input->channels; i++) { - - for (k = 0; k < MAX_PEAKS; k++) { - peaks[k].db = -200.; - peaks[k].bin = 0.; - } + for (k = 0; k < MAX_PEAKS; k++) { + peaks[k].db = -200.; + peaks[k].bin = 0.; + } - for (k = 0; k < input->length; k++) { - p->winput->data[0][k] = p->win->data[0][k] * input->data[i][k]; - } - aubio_fft_do (p->fft, p->winput, p->fftOut); + for (k = 0; k < input->length; k++) { + p->winput->data[k] = p->win->data[k] * input->data[k]; + } + aubio_fft_do (p->fft, p->winput, p->fftOut); - for (k = 0; k <= p->fftSize / 2; k++) { - smpl_t - magnitude = - 20. * LOG10 (2. * p->fftOut->norm[0][k] / (smpl_t) p->fftSize), - phase = p->fftOut->phas[0][k], tmp, bin; + for (k = 0; k <= p->fftSize / 2; k++) { + smpl_t + magnitude = + 20. * LOG10 (2. * p->fftOut->norm[k] / (smpl_t) p->fftSize), + phase = p->fftOut->phas[k], tmp, bin; - /* compute phase difference */ - tmp = phase - p->fftLastPhase->data[i][k]; - p->fftLastPhase->data[i][k] = phase; + /* compute phase difference */ + tmp = phase - p->fftLastPhase->data[k]; + p->fftLastPhase->data[k] = phase; - /* subtract expected phase difference */ - tmp -= (smpl_t) k *phaseDifference; + /* subtract expected phase difference */ + tmp -= (smpl_t) k *phaseDifference; - /* map delta phase into +/- Pi interval */ - tmp = aubio_unwrap2pi (tmp); + /* map delta phase into +/- Pi interval */ + tmp = aubio_unwrap2pi (tmp); - /* get deviation from bin frequency from the +/- Pi interval */ - tmp = p->fftSize / (smpl_t) p->stepSize * tmp / (TWO_PI); + /* get deviation from bin frequency from the +/- Pi interval */ + tmp = p->fftSize / (smpl_t) p->stepSize * tmp / (TWO_PI); - /* compute the k-th partials' true bin */ - bin = (smpl_t) k + tmp; + /* compute the k-th partials' true bin */ + bin = (smpl_t) k + tmp; - if (bin > 0.0 && magnitude > peaks[0].db) { // && magnitude < 0) { - memmove (peaks + 1, peaks, sizeof (aubio_fpeak_t) * (MAX_PEAKS - 1)); - peaks[0].bin = bin; - peaks[0].db = magnitude; - } + if (bin > 0.0 && magnitude > peaks[0].db) { // && magnitude < 0) { + memmove (peaks + 1, peaks, sizeof (aubio_fpeak_t) * (MAX_PEAKS - 1)); + peaks[0].bin = bin; + peaks[0].db = magnitude; } + } - k = 0; - for (l = 1; l < MAX_PEAKS && peaks[l].bin > 0.0; l++) { - sint_t harmonic; - for (harmonic = 5; harmonic > 1; harmonic--) { - if (peaks[0].bin / peaks[l].bin < harmonic + .02 && - peaks[0].bin / peaks[l].bin > harmonic - .02) { - if (harmonic > (sint_t) maxharm && peaks[0].db < peaks[l].db / 2) { - maxharm = harmonic; - k = l; - } + k = 0; + for (l = 1; l < MAX_PEAKS && peaks[l].bin > 0.0; l++) { + sint_t harmonic; + for (harmonic = 5; harmonic > 1; harmonic--) { + if (peaks[0].bin / peaks[l].bin < harmonic + .02 && + peaks[0].bin / peaks[l].bin > harmonic - .02) { + if (harmonic > (sint_t) maxharm && peaks[0].db < peaks[l].db / 2) { + maxharm = harmonic; + k = l; } } } - output->data[i][0] = peaks[k].bin; - /* quick hack to clean output a bit */ - if (peaks[k].bin > 5000.) - output->data[i][0] = 0.; } + output->data[0] = peaks[k].bin; + /* quick hack to clean output a bit */ + if (peaks[k].bin > 5000.) + output->data[0] = 0.; } void diff --git a/src/pitch/pitchfcomb.h b/src/pitch/pitchfcomb.h index 9880c90d..14c27c96 100644 --- a/src/pitch/pitchfcomb.h +++ b/src/pitch/pitchfcomb.h @@ -56,11 +56,9 @@ void aubio_pitchfcomb_do (aubio_pitchfcomb_t * p, fvec_t * input, \param buf_size size of the input buffer to analyse \param hop_size step size between two consecutive analysis instant - \param channels number of channels to detect pitch on */ -aubio_pitchfcomb_t *new_aubio_pitchfcomb (uint_t buf_size, uint_t hop_size, - uint_t channels); +aubio_pitchfcomb_t *new_aubio_pitchfcomb (uint_t buf_size, uint_t hop_size); /** deletion of the pitch detection object diff --git a/src/pitch/pitchmcomb.c b/src/pitch/pitchmcomb.c index d49625fb..892ad3fc 100644 --- a/src/pitch/pitchmcomb.c +++ b/src/pitch/pitchmcomb.c @@ -103,42 +103,40 @@ struct _aubio_spectralcandidate_t void aubio_pitchmcomb_do (aubio_pitchmcomb_t * p, cvec_t * fftgrain, fvec_t * output) { - uint_t i, j; + uint_t j; smpl_t instfreq; fvec_t *newmag = (fvec_t *) p->newmag; //smpl_t hfc; //fe=instfreq(theta1,theta,ops); //theta1=theta; /* copy incoming grain to newmag */ - for (i = 0; i < fftgrain->channels; i++) { - for (j = 0; j < newmag->length; j++) - newmag->data[0][j] = fftgrain->norm[i][j]; - /* detect only if local energy > 10. */ - //if (fvec_local_energy(newmag)>10.) { - //hfc = fvec_local_hfc(newmag); //not used - aubio_pitchmcomb_spectral_pp (p, newmag); - aubio_pitchmcomb_combdet (p, newmag); - //aubio_pitchmcomb_sort_cand_freq(p->candidates,p->ncand); - //return p->candidates[p->goodcandidate]->ebin; - j = (uint_t) FLOOR (p->candidates[p->goodcandidate]->ebin + .5); - instfreq = aubio_unwrap2pi (fftgrain->phas[i][j] - - p->theta->data[i][j] - j * p->phasediff); - instfreq *= p->phasefreq; - /* store phase for next run */ - for (j = 0; j < p->theta->length; j++) { - p->theta->data[i][j] = fftgrain->phas[i][j]; - } - //return p->candidates[p->goodcandidate]->ebin; - output->data[i][0] = - FLOOR (p->candidates[p->goodcandidate]->ebin + .5) + instfreq; - /*} else { - return -1.; - } */ + for (j = 0; j < newmag->length; j++) + newmag->data[j] = fftgrain->norm[j]; + /* detect only if local energy > 10. */ + //if (fvec_local_energy(newmag)>10.) { + //hfc = fvec_local_hfc(newmag); //not used + aubio_pitchmcomb_spectral_pp (p, newmag); + aubio_pitchmcomb_combdet (p, newmag); + //aubio_pitchmcomb_sort_cand_freq(p->candidates,p->ncand); + //return p->candidates[p->goodcandidate]->ebin; + j = (uint_t) FLOOR (p->candidates[p->goodcandidate]->ebin + .5); + instfreq = aubio_unwrap2pi (fftgrain->phas[j] + - p->theta->data[j] - j * p->phasediff); + instfreq *= p->phasefreq; + /* store phase for next run */ + for (j = 0; j < p->theta->length; j++) { + p->theta->data[j] = fftgrain->phas[j]; } + //return p->candidates[p->goodcandidate]->ebin; + output->data[0] = + FLOOR (p->candidates[p->goodcandidate]->ebin + .5) + instfreq; + /*} else { + return -1.; + } */ } uint_t aubio_pitch_cands (aubio_pitchmcomb_t * p, cvec_t * fftgrain, smpl_t * cands) { - uint_t i = 0, j; + uint_t j; uint_t k; fvec_t *newmag = (fvec_t *) p->newmag; aubio_spectralcandidate_t **scands = @@ -146,7 +144,7 @@ aubio_pitch_cands (aubio_pitchmcomb_t * p, cvec_t * fftgrain, smpl_t * cands) //smpl_t hfc; //fe=instfreq(theta1,theta,ops); //theta1=theta; /* copy incoming grain to newmag */ for (j = 0; j < newmag->length; j++) - newmag->data[i][j] = fftgrain->norm[i][j]; + newmag->data[j] = fftgrain->norm[j]; /* detect only if local energy > 10. */ if (fvec_local_energy (newmag) > 10.) { /* hfc = fvec_local_hfc(newmag); do not use */ @@ -171,17 +169,17 @@ aubio_pitchmcomb_spectral_pp (aubio_pitchmcomb_t * p, fvec_t * newmag) { fvec_t *mag = (fvec_t *) p->scratch; fvec_t *tmp = (fvec_t *) p->scratch2; - uint_t i = 0, j; + uint_t j; uint_t length = mag->length; /* copy newmag to mag (scracth) */ for (j = 0; j < length; j++) { - mag->data[i][j] = newmag->data[i][j]; + mag->data[j] = newmag->data[j]; } fvec_min_removal (mag); /* min removal */ fvec_alpha_normalise (mag, p->alpha); /* alpha normalisation */ /* skipped *//* low pass filtering */ /** \bug fvec_moving_thres may write out of bounds */ - fvec_adapt_thres (mag, tmp, p->win_post, p->win_pre, i); /* adaptative threshold */ + fvec_adapt_thres (mag, tmp, p->win_post, p->win_pre); /* adaptative threshold */ fvec_add (mag, -p->threshold); /* fixed threshold */ { aubio_spectralpeak_t *peaks = (aubio_spectralpeak_t *) p->peaks; @@ -189,7 +187,7 @@ aubio_pitchmcomb_spectral_pp (aubio_pitchmcomb_t * p, fvec_t * newmag) /* return bin and ebin */ count = aubio_pitchmcomb_quadpick (peaks, mag); for (j = 0; j < count; j++) - peaks[j].mag = newmag->data[i][peaks[j].bin]; + peaks[j].mag = newmag->data[peaks[j].bin]; /* reset non peaks */ for (j = count; j < length; j++) peaks[j].mag = 0.; @@ -260,7 +258,7 @@ aubio_pitchmcomb_combdet (aubio_pitchmcomb_t * p, fvec_t * newmag) if (17. * xx < candidate[l]->ecomb[k]) { candidate[l]->ecomb[k] = peaks[position].ebin; candidate[l]->ene += /* ecomb rounded to nearest int */ - POW (newmag->data[0][(uint_t) FLOOR (candidate[l]->ecomb[k] + .5)], + POW (newmag->data[(uint_t) FLOOR (candidate[l]->ecomb[k] + .5)], 0.25); candidate[l]->len += 1. / curlen; } else @@ -289,16 +287,15 @@ aubio_pitchmcomb_combdet (aubio_pitchmcomb_t * p, fvec_t * newmag) uint_t aubio_pitchmcomb_quadpick (aubio_spectralpeak_t * spectral_peaks, fvec_t * X) { - uint_t i, j, ispeak, count = 0; - for (i = 0; i < X->channels; i++) - for (j = 1; j < X->length - 1; j++) { - ispeak = fvec_peakpick (X, j); - if (ispeak) { - count += ispeak; - spectral_peaks[count - 1].bin = j; - spectral_peaks[count - 1].ebin = fvec_quadint (X, j, i) - 1.; - } + uint_t j, ispeak, count = 0; + for (j = 1; j < X->length - 1; j++) { + ispeak = fvec_peakpick (X, j); + if (ispeak) { + count += ispeak; + spectral_peaks[count - 1].bin = j; + spectral_peaks[count - 1].ebin = fvec_quadint (X, j) - 1.; } + } return count; } @@ -363,7 +360,7 @@ aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates, } aubio_pitchmcomb_t * -new_aubio_pitchmcomb (uint_t bufsize, uint_t hopsize, uint_t channels) +new_aubio_pitchmcomb (uint_t bufsize, uint_t hopsize) { aubio_pitchmcomb_t *p = AUBIO_NEW (aubio_pitchmcomb_t); /* bug: should check if size / 8 > post+pre+1 */ @@ -385,13 +382,13 @@ new_aubio_pitchmcomb (uint_t bufsize, uint_t hopsize, uint_t channels) //p->pickerfn = quadpick; //p->biquad = new_biquad(0.1600,0.3200,0.1600, -0.5949, 0.2348); /* allocate temp memory */ - p->newmag = new_fvec (spec_size, 1); + p->newmag = new_fvec (spec_size); /* array for median */ - p->scratch = new_fvec (spec_size, 1); + p->scratch = new_fvec (spec_size); /* array for phase */ - p->theta = new_fvec (spec_size, channels); + p->theta = new_fvec (spec_size); /* array for adaptative threshold */ - p->scratch2 = new_fvec (p->win_post + p->win_pre + 1, 1); + p->scratch2 = new_fvec (p->win_post + p->win_pre + 1); /* array of spectral peaks */ p->peaks = AUBIO_ARRAY (aubio_spectralpeak_t, spec_size); for (i = 0; i < spec_size; i++) { diff --git a/src/pitch/pitchmcomb.h b/src/pitch/pitchmcomb.h index c17b0b02..a183f165 100644 --- a/src/pitch/pitchmcomb.h +++ b/src/pitch/pitchmcomb.h @@ -56,12 +56,10 @@ void aubio_pitchmcomb_do (aubio_pitchmcomb_t * p, cvec_t * fftgrain, \param buf_size size of the input buffer to analyse \param hop_size step size between two consecutive analysis instant - \param channels number of channels to analyse \param samplerate sampling rate of the signal */ -aubio_pitchmcomb_t *new_aubio_pitchmcomb (uint_t buf_size, uint_t hop_size, - uint_t channels); +aubio_pitchmcomb_t *new_aubio_pitchmcomb (uint_t buf_size, uint_t hop_size); /** deletion of the pitch detection object diff --git a/src/pitch/pitchschmitt.c b/src/pitch/pitchschmitt.c index 4aed3145..f061cc8f 100644 --- a/src/pitch/pitchschmitt.c +++ b/src/pitch/pitchschmitt.c @@ -50,13 +50,11 @@ void aubio_pitchschmitt_do (aubio_pitchschmitt_t * p, fvec_t * input, fvec_t * output) { - uint_t i, j; - for (i = 0; i < input->channels; i++) { - for (j = 0; j < input->length; j++) { - p->buf[j] = input->data[i][j] * 32768.; - } - output->data[i][0] = aubio_schmittS16LE (p, input->length, p->buf); + uint_t j; + for (j = 0; j < input->length; j++) { + p->buf[j] = input->data[j] * 32768.; } + output->data[0] = aubio_schmittS16LE (p, input->length, p->buf); } smpl_t diff --git a/src/pitch/pitchyin.c b/src/pitch/pitchyin.c index 73907a93..1d309fac 100644 --- a/src/pitch/pitchyin.c +++ b/src/pitch/pitchyin.c @@ -64,7 +64,7 @@ aubio_pitchyin_t * new_aubio_pitchyin (uint_t bufsize) { aubio_pitchyin_t *o = AUBIO_NEW (aubio_pitchyin_t); - o->yin = new_fvec (bufsize / 2, 1); + o->yin = new_fvec (bufsize / 2); o->tol = 0.15; return o; } @@ -80,17 +80,15 @@ del_aubio_pitchyin (aubio_pitchyin_t * o) void aubio_pitchyin_diff (fvec_t * input, fvec_t * yin) { - uint_t c, j, tau; + uint_t j, tau; smpl_t tmp; - for (c = 0; c < input->channels; c++) { - for (tau = 0; tau < yin->length; tau++) { - yin->data[c][tau] = 0.; - } - for (tau = 1; tau < yin->length; tau++) { - for (j = 0; j < yin->length; j++) { - tmp = input->data[c][j] - input->data[c][j + tau]; - yin->data[c][tau] += SQR (tmp); - } + for (tau = 0; tau < yin->length; tau++) { + yin->data[tau] = 0.; + } + for (tau = 1; tau < yin->length; tau++) { + for (j = 0; j < yin->length; j++) { + tmp = input->data[j] - input->data[j + tau]; + yin->data[tau] += SQR (tmp); } } } @@ -99,28 +97,26 @@ aubio_pitchyin_diff (fvec_t * input, fvec_t * yin) void aubio_pitchyin_getcum (fvec_t * yin) { - uint_t c, tau; + uint_t tau; smpl_t tmp; - for (c = 0; c < yin->channels; c++) { - tmp = 0.; - yin->data[c][0] = 1.; - //AUBIO_DBG("%f\t",yin->data[c][0]); - for (tau = 1; tau < yin->length; tau++) { - tmp += yin->data[c][tau]; - yin->data[c][tau] *= tau / tmp; - //AUBIO_DBG("%f\t",yin->data[c][tau]); - } - //AUBIO_DBG("\n"); + tmp = 0.; + yin->data[0] = 1.; + //AUBIO_DBG("%f\t",yin->data[0]); + for (tau = 1; tau < yin->length; tau++) { + tmp += yin->data[tau]; + yin->data[tau] *= tau / tmp; + //AUBIO_DBG("%f\t",yin->data[tau]); } + //AUBIO_DBG("\n"); } uint_t aubio_pitchyin_getpitch (fvec_t * yin) { - uint_t c = 0, tau = 1; + uint_t tau = 1; do { - if (yin->data[c][tau] < 0.1) { - while (yin->data[c][tau + 1] < yin->data[c][tau]) { + if (yin->data[tau] < 0.1) { + while (yin->data[tau + 1] < yin->data[tau]) { tau++; } return tau; @@ -138,31 +134,28 @@ 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 c, j, tau = 0; + uint_t j, tau = 0; sint_t period; smpl_t tmp = 0., tmp2 = 0.; - for (c = 0; c < input->channels; c++) { - yin->data[c][0] = 1.; - for (tau = 1; tau < yin->length; tau++) { - yin->data[c][tau] = 0.; - for (j = 0; j < yin->length; j++) { - tmp = input->data[c][j] - input->data[c][j + tau]; - yin->data[c][tau] += SQR (tmp); - } - tmp2 += yin->data[c][tau]; - yin->data[c][tau] *= tau / tmp2; - period = tau - 3; - if (tau > 4 && (yin->data[c][period] < tol) && - (yin->data[c][period] < yin->data[c][period + 1])) { - out->data[c][0] = fvec_quadint (yin, period, c); - goto beach; - } + 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_quadint (yin, period); + goto beach; } - out->data[c][0] = fvec_quadint (yin, fvec_min_elem (yin), c); - beach: - continue; } - //return 0; + out->data[0] = fvec_quadint (yin, fvec_min_elem (yin)); +beach: + return; } uint_t diff --git a/src/pitch/pitchyinfft.c b/src/pitch/pitchyinfft.c index 0111f31f..e8c2757e 100644 --- a/src/pitch/pitchyinfft.c +++ b/src/pitch/pitchyinfft.c @@ -55,42 +55,40 @@ aubio_pitchyinfft_t * new_aubio_pitchyinfft (uint_t bufsize) { aubio_pitchyinfft_t *p = AUBIO_NEW (aubio_pitchyinfft_t); - p->winput = new_fvec (bufsize, 1); - p->fft = new_aubio_fft (bufsize, 1); - p->fftout = new_cvec (bufsize, 1); - p->sqrmag = new_fvec (bufsize, 1); - p->res = new_cvec (bufsize, 1); - p->yinfft = new_fvec (bufsize / 2 + 1, 1); + p->winput = new_fvec (bufsize); + p->fft = new_aubio_fft (bufsize); + p->fftout = new_cvec (bufsize); + p->sqrmag = new_fvec (bufsize); + p->res = new_cvec (bufsize); + p->yinfft = new_fvec (bufsize / 2 + 1); p->tol = 0.85; p->win = new_aubio_window ("hanningz", bufsize); - p->weight = new_fvec (bufsize / 2 + 1, 1); - { - uint_t i = 0, j = 1; - smpl_t freq = 0, a0 = 0, a1 = 0, f0 = 0, f1 = 0; - for (i = 0; i < p->weight->length; i++) { - freq = (smpl_t) i / (smpl_t) bufsize *(smpl_t) 44100.; - while (freq > freqs[j]) { - j += 1; - } - a0 = weight[j - 1]; - f0 = freqs[j - 1]; - a1 = weight[j]; - f1 = freqs[j]; - if (f0 == f1) { // just in case - p->weight->data[0][i] = a0; - } else if (f0 == 0) { // y = ax+b - p->weight->data[0][i] = (a1 - a0) / f1 * freq + a0; - } else { - p->weight->data[0][i] = (a1 - a0) / (f1 - f0) * freq + - (a0 - (a1 - a0) / (f1 / f0 - 1.)); - } - while (freq > freqs[j]) { - j += 1; - } - //AUBIO_DBG("%f\n",p->weight->data[0][i]); - p->weight->data[0][i] = DB2LIN (p->weight->data[0][i]); - //p->weight->data[0][i] = SQRT(DB2LIN(p->weight->data[0][i])); + p->weight = new_fvec (bufsize / 2 + 1); + uint_t i = 0, j = 1; + smpl_t freq = 0, a0 = 0, a1 = 0, f0 = 0, f1 = 0; + for (i = 0; i < p->weight->length; i++) { + freq = (smpl_t) i / (smpl_t) bufsize *(smpl_t) 44100.; + while (freq > freqs[j]) { + j += 1; } + a0 = weight[j - 1]; + f0 = freqs[j - 1]; + a1 = weight[j]; + f1 = freqs[j]; + if (f0 == f1) { // just in case + p->weight->data[i] = a0; + } else if (f0 == 0) { // y = ax+b + p->weight->data[i] = (a1 - a0) / f1 * freq + a0; + } else { + p->weight->data[i] = (a1 - a0) / (f1 - f0) * freq + + (a0 - (a1 - a0) / (f1 / f0 - 1.)); + } + while (freq > freqs[j]) { + j += 1; + } + //AUBIO_DBG("%f\n",p->weight->data[i]); + p->weight->data[i] = DB2LIN (p->weight->data[i]); + //p->weight->data[i] = SQRT(DB2LIN(p->weight->data[i])); } return p; } @@ -98,60 +96,58 @@ new_aubio_pitchyinfft (uint_t bufsize) void aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, fvec_t * output) { - uint_t i, tau, l; + 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; - for (i = 0; i < input->channels; i++) { - l = 0; - tmp = 0.; - sum = 0.; - for (l = 0; l < input->length; l++) { - p->winput->data[0][l] = p->win->data[0][l] * input->data[i][l]; - } - aubio_fft_do (p->fft, p->winput, p->fftout); - for (l = 0; l < p->fftout->length; l++) { - p->sqrmag->data[0][l] = SQR (p->fftout->norm[0][l]); - p->sqrmag->data[0][l] *= p->weight->data[0][l]; - } - for (l = 1; l < p->fftout->length; l++) { - p->sqrmag->data[0][(p->fftout->length - 1) * 2 - l] = - SQR (p->fftout->norm[0][l]); - p->sqrmag->data[0][(p->fftout->length - 1) * 2 - l] *= - p->weight->data[0][l]; - } - for (l = 0; l < p->sqrmag->length / 2 + 1; l++) { - sum += p->sqrmag->data[0][l]; - } - sum *= 2.; - aubio_fft_do (p->fft, p->sqrmag, res); - yin->data[0][0] = 1.; - for (tau = 1; tau < yin->length; tau++) { - yin->data[0][tau] = sum - res->norm[0][tau] * COS (res->phas[0][tau]); - tmp += yin->data[0][tau]; - yin->data[0][tau] *= tau / tmp; - } - tau = fvec_min_elem (yin); - if (yin->data[0][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[i][0] = fvec_quadint (yin, tau, i); - } else { - /* should compare the minimum value of each interpolated peaks */ - halfperiod = FLOOR (tau / 2 + .5); - if (yin->data[0][halfperiod] < p->tol) - output->data[i][0] = fvec_quadint (yin, halfperiod, i); - else - output->data[i][0] = fvec_quadint (yin, tau, i); - } + 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 { - output->data[i][0] = 0.; + /* 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.; } } -- 2.26.2