ref: 168337eebd7faec09b72a3af3541542470b514b7
parent: fc61225e10b7a6acfcdbda0f4b4a25e2bcb821b4
author: Paul Brossier <piem@piem.org>
date: Thu Dec 3 20:44:41 EST 2009
src/pitch: switch to mono
--- a/src/pitch/pitch.c
+++ b/src/pitch/pitch.c
@@ -113,7 +113,7 @@
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 @@
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 @@
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,23 +278,17 @@
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
@@ -305,18 +295,15 @@
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,29 +311,23 @@
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
@@ -353,16 +334,13 @@
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;
}
--- a/src/pitch/pitch.h
+++ b/src/pitch/pitch.h
@@ -40,8 +40,8 @@
/** 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 @@
\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
--- a/src/pitch/pitchfcomb.c
+++ b/src/pitch/pitchfcomb.c
@@ -48,15 +48,15 @@
};
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 @@
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[k] = p->win->data[k] * input->data[k];
+ }
+ aubio_fft_do (p->fft, p->winput, p->fftOut);
- 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 <= 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;
- 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;
+ /* compute phase difference */
+ tmp = phase - p->fftLastPhase->data[k];
+ p->fftLastPhase->data[k] = phase;
- /* compute phase difference */
- tmp = phase - p->fftLastPhase->data[i][k];
- p->fftLastPhase->data[i][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
--- a/src/pitch/pitchfcomb.h
+++ b/src/pitch/pitchfcomb.h
@@ -56,11 +56,9 @@
\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
--- a/src/pitch/pitchmcomb.c
+++ b/src/pitch/pitchmcomb.c
@@ -103,42 +103,40 @@
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 @@
//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 @@
{
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 @@
/* 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 @@
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 @@
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_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 @@
//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++) {
--- a/src/pitch/pitchmcomb.h
+++ b/src/pitch/pitchmcomb.h
@@ -56,12 +56,10 @@
\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
--- a/src/pitch/pitchschmitt.c
+++ b/src/pitch/pitchschmitt.c
@@ -50,13 +50,11 @@
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
--- a/src/pitch/pitchyin.c
+++ b/src/pitch/pitchyin.c
@@ -64,7 +64,7 @@
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,18 +80,16 @@
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 = 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);
}
- 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);
- }
- }
}
}
@@ -99,28 +97,26 @@
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 @@
{
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);
}
- out->data[c][0] = fvec_quadint (yin, fvec_min_elem (yin), c);
- beach:
- continue;
+ 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;
+ }
}
- //return 0;
+ out->data[0] = fvec_quadint (yin, fvec_min_elem (yin));
+beach:
+ return;
}
uint_t
--- a/src/pitch/pitchyinfft.c
+++ b/src/pitch/pitchyinfft.c
@@ -55,42 +55,40 @@
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 @@
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.;
}
}