return tmp / (smpl_t) (s->length);
}
+smpl_t
+fvec_mean_channel (fvec_t * s, uint_t i)
+{
+ uint_t j;
+ smpl_t tmp = 0.0;
+ for (j = 0; j < s->length; j++)
+ tmp += s->data[i][j];
+ return tmp / (smpl_t) (s->length);
+}
+
smpl_t
fvec_sum (fvec_t * s)
{
}
void fvec_adapt_thres(fvec_t * vec, fvec_t * tmp,
- uint_t post, uint_t pre) {
- uint_t length = vec->length, i=0, j;
+ uint_t post, uint_t pre, uint_t channel) {
+ uint_t length = vec->length, i=channel, j;
for (j=0;j<length;j++) {
- vec->data[i][j] -= fvec_moving_thres(vec, tmp, post, pre, j);
+ vec->data[i][j] -= fvec_moving_thres(vec, tmp, post, pre, j, i);
}
}
smpl_t
fvec_moving_thres (fvec_t * vec, fvec_t * tmpvec,
- uint_t post, uint_t pre, uint_t pos)
+ uint_t post, uint_t pre, uint_t pos, uint_t channel)
{
- smpl_t *medar = (smpl_t *) tmpvec->data[0];
- uint_t k;
+ uint_t i = channel, k;
+ smpl_t *medar = (smpl_t *) tmpvec->data[i];
uint_t win_length = post + pre + 1;
uint_t length = vec->length;
/* post part of the buffer does not exist */
for (k = length - pos + post; k < win_length; k++)
medar[k] = 0.; /* 0-padding at the end */
}
- return fvec_median (tmpvec);
+ return fvec_median_channel (tmpvec, i);
}
-smpl_t fvec_median(fvec_t * input) {
+smpl_t fvec_median_channel (fvec_t * input, uint_t channel) {
uint_t n = input->length;
- smpl_t * arr = (smpl_t *) input->data[0];
+ smpl_t * arr = (smpl_t *) input->data[channel];
uint_t low, high ;
uint_t median;
uint_t middle, ll, hh;
}
}
-smpl_t fvec_quadint(fvec_t * x,uint_t pos, uint_t span) {
+smpl_t fvec_quadint (fvec_t * x, uint_t pos, uint_t i) {
smpl_t s0, s1, s2;
- uint_t x0 = (pos < span) ? pos : pos - span;
- uint_t x2 = (pos + span < x->length) ? pos + span : pos;
- if (x0 == pos) return (x->data[0][pos] <= x->data[0][x2]) ? pos : x2;
- if (x2 == pos) return (x->data[0][pos] <= x->data[0][x0]) ? pos : x0;
- s0 = x->data[0][x0];
- s1 = x->data[0][pos];
- s2 = x->data[0][x2];
+ uint_t x0 = (pos < 1) ? pos : pos - 1;
+ uint_t x2 = (pos + 1 < x->length) ? pos + 1 : pos;
+ if (x0 == pos) return (x->data[i][pos] <= x->data[i][x2]) ? pos : x2;
+ if (x2 == pos) return (x->data[i][pos] <= x->data[i][x0]) ? pos : x0;
+ s0 = x->data[i][x0];
+ s1 = x->data[i][pos];
+ s2 = x->data[i][x2];
return pos + 0.5 * (s2 - s0 ) / (s2 - 2.* s1 + s0);
}
/** compute the mean of a vector
- \param s vector to compute norm from
+ \param s vector to compute mean from
\return the mean of v
*/
smpl_t fvec_mean (fvec_t * s);
+/** compute the mean of a vector channel
+
+ \param s vector to compute mean from
+ \param i channel to compute mean from
+
+ \return the mean of v
+
+*/
+smpl_t fvec_mean_channel (fvec_t * s, uint_t i);
+
/** find the max of a vector
\param s vector to get the max from
*/
smpl_t fvec_moving_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre,
- uint_t pos);
+ uint_t pos, uint_t channel);
/** apply adaptive threshold to a vector
\param pre length of anti-causal part to take after pos
*/
-void fvec_adapt_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre);
+void fvec_adapt_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre,
+ uint_t channel);
/** returns the median of a vector
and in the Public Domain.
\param v vector to get median from
+ \param channel channel to get median from
\return the median of v
*/
-smpl_t fvec_median (fvec_t * v);
+smpl_t fvec_median_channel (fvec_t * v, uint_t channel);
/** finds exact peak index by quadratic interpolation*/
-smpl_t fvec_quadint (fvec_t * x, uint_t pos, uint_t span);
+smpl_t fvec_quadint (fvec_t * x, uint_t pos, uint_t channel);
/** Quadratic interpolation using Lagrange polynomial.
smpl_t threshold; /**< onset peak picking threshold */
smpl_t silence; /**< silence threhsold */
uint_t minioi; /**< minimum inter onset interval */
- uint_t wasonset; /**< number of frames since last onset */
+ fvec_t * wasonset; /**< number of frames since last onset */
uint_t samplerate; /**< sampling rate of the input signal */
};
/* execute onset detection function on iput buffer */
void aubio_onset_do (aubio_onset_t *o, fvec_t * input, fvec_t * onset)
{
- uint_t isonset = 0;
- uint_t wasonset = o->wasonset;
+ smpl_t isonset = 0;
+ smpl_t wasonset = 0;
+ uint_t i;
aubio_pvoc_do (o->pv,input, o->fftgrain);
aubio_onsetdetection_do (o->od,o->fftgrain, o->of);
/*if (usedoubled) {
aubio_onsetdetection_do (o2,fftgrain, onset2);
onset->data[0][0] *= onset2->data[0][0];
}*/
- isonset = aubio_peakpicker_do(o->pp, o->of);
+ aubio_peakpicker_do(o->pp, o->of, onset);
+ for (i = 0; i < input->channels; i++) {
+ isonset = onset->data[i][0];
+ wasonset = o->wasonset->data[i][0];
if (isonset > 0.) {
if (aubio_silence_detection(input, o->silence)==1) {
isonset = 0;
} else {
wasonset++;
}
- o->wasonset = wasonset;
- onset->data[0][0] = isonset;
+ o->wasonset->data[i][0] = wasonset;
+ onset->data[i][0] = isonset;
+ }
return;
}
o->threshold = 0.3;
o->minioi = 4;
o->silence = -70;
- o->wasonset = 0;
+ o->wasonset = new_fvec(1, channels);
o->samplerate = samplerate;
o->pv = new_aubio_pvoc(buf_size, hop_size, channels);
- o->pp = new_aubio_peakpicker(o->threshold);
+ o->pp = new_aubio_peakpicker(channels);
+ aubio_peakpicker_set_threshold (o->pp, o->threshold);
o->od = new_aubio_onsetdetection(onset_mode,buf_size,channels);
o->fftgrain = new_cvec(buf_size,channels);
o->of = new_fvec(1, channels);
del_aubio_peakpicker(o->pp);
del_aubio_pvoc(o->pv);
del_fvec(o->of);
+ del_fvec(o->wasonset);
del_cvec(o->fftgrain);
AUBIO_FREE(o);
}
/** scratch pad for biquad and median */
fvec_t * scratch;
+ /** number of channels to analyse */
+ uint_t channels;
+
/** \bug should be used to calculate filter coefficients */
/* cutoff: low-pass filter cutoff [0.34, 1] */
/* smpl_t cutoff; */
/** modified version for real time, moving mean adaptive threshold this method
* is slightly more permissive than the offline one, and yelds to an increase
* of false positives. best */
-smpl_t aubio_peakpicker_do(aubio_peakpicker_t * p, fvec_t * onset) {
- fvec_t * onset_keep = (fvec_t *)p->onset_keep;
- fvec_t * onset_proc = (fvec_t *)p->onset_proc;
- fvec_t * onset_peek = (fvec_t *)p->onset_peek;
- fvec_t * scratch = (fvec_t *)p->scratch;
- smpl_t mean = 0., median = 0.;
- smpl_t isonset = 0.;
- uint_t length = p->win_post + p->win_pre + 1;
- uint_t i = 0, j;
-
- /* store onset in onset_keep */
- /* shift all elements but last, then write last */
- /* for (i=0;i<channels;i++) { */
- for (j=0;j<length-1;j++) {
- onset_keep->data[i][j] = onset_keep->data[i][j+1];
- onset_proc->data[i][j] = onset_keep->data[i][j];
- }
- onset_keep->data[i][length-1] = onset->data[i][0];
- onset_proc->data[i][length-1] = onset->data[i][0];
- /* } */
-
- /* filter onset_proc */
- /** \bug filtfilt calculated post+pre times, should be only once !? */
- aubio_biquad_do_filtfilt(p->biquad,onset_proc,scratch);
-
- /* calculate mean and median for onset_proc */
- /* for (i=0;i<onset_proc->channels;i++) { */
- mean = fvec_mean(onset_proc);
- /* copy to scratch */
- for (j = 0; j < length; j++)
- scratch->data[i][j] = onset_proc->data[i][j];
- median = p->thresholdfn(scratch);
- /* } */
-
- /* for (i=0;i<onset->channels;i++) { */
- /* shift peek array */
- for (j=0;j<3-1;j++)
- onset_peek->data[i][j] = onset_peek->data[i][j+1];
- /* calculate new peek value */
- onset_peek->data[i][2] =
- onset_proc->data[i][p->win_post] - median - mean * p->threshold;
- /* } */
- //AUBIO_DBG("%f\n", onset_peek->data[0][2]);
- isonset = (p->pickerfn)(onset_peek,1);
- if (isonset) { //(isonset) {
- isonset = fvec_quadint(onset_peek, 1, 1);
+void
+aubio_peakpicker_do (aubio_peakpicker_t * p, fvec_t * onset, fvec_t * out)
+{
+ fvec_t *onset_keep = p->onset_keep;
+ fvec_t *onset_proc = p->onset_proc;
+ fvec_t *onset_peek = p->onset_peek;
+ fvec_t *scratch = p->scratch;
+ smpl_t mean = 0., median = 0.;
+ uint_t length = p->win_post + p->win_pre + 1;
+ uint_t i, j = 0;
+
+ for (i = 0; i < p->channels; i++) {
+ /* store onset in onset_keep */
+ /* shift all elements but last, then write last */
+ for (j = 0; j < length - 1; j++) {
+ onset_keep->data[i][j] = onset_keep->data[i][j + 1];
+ onset_proc->data[i][j] = onset_keep->data[i][j];
+ }
+ onset_keep->data[i][length - 1] = onset->data[i][0];
+ onset_proc->data[i][length - 1] = onset->data[i][0];
+ }
+
+ /* filter onset_proc */
+ /** \bug filtfilt calculated post+pre times, should be only once !? */
+ //aubio_biquad_do_filtfilt(p->biquad,onset_proc,scratch);
+
+ for (i = 0; i < p->channels; i++) {
+ /* calculate mean and median for onset_proc */
+ mean = fvec_mean_channel (onset_proc, i);
+ /* copy to scratch */
+ for (j = 0; j < length; j++)
+ scratch->data[i][j] = onset_proc->data[i][j];
+ median = p->thresholdfn (scratch, i);
+
+ /* shift peek array */
+ for (j = 0; j < 3 - 1; j++)
+ onset_peek->data[i][j] = onset_peek->data[i][j + 1];
+ /* calculate new peek value */
+ onset_peek->data[i][2] =
+ onset_proc->data[i][p->win_post] - median - mean * p->threshold;
+ out->data[i][0] = (p->pickerfn) (onset_peek, 1);
+ if (out->data[i][0]) {
+ out->data[i][0] = fvec_quadint (onset_peek, 1, i);
+ }
}
- return isonset;
}
/** this method returns the current value in the pick peaking buffer
return p->onset_peek->data[0][1];
}
-/** function added by Miguel Ramirez to return the onset detection amplitude in peakval */
uint_t aubio_peakpicker_set_threshold(aubio_peakpicker_t * p, smpl_t threshold) {
- p->threshold = threshold;
+ p->threshold = threshold;
return AUBIO_OK;
}
return (aubio_thresholdfn_t) (p->thresholdfn);
}
-aubio_peakpicker_t * new_aubio_peakpicker(smpl_t threshold) {
+aubio_peakpicker_t * new_aubio_peakpicker(uint_t channels) {
aubio_peakpicker_t * t = AUBIO_NEW(aubio_peakpicker_t);
t->threshold = 0.1; /* 0.0668; 0.33; 0.082; 0.033; */
- if (threshold > 0. && threshold < 10.)
- t->threshold = threshold;
t->win_post = 5;
t->win_pre = 1;
+ //channels = 1;
+ t->channels = channels;
- t->thresholdfn = (aubio_thresholdfn_t)(fvec_median); /* (fvec_mean); */
+ t->thresholdfn = (aubio_thresholdfn_t)(fvec_median_channel); /* (fvec_mean); */
t->pickerfn = (aubio_pickerfn_t)(fvec_peakpick);
- t->scratch = new_fvec(t->win_post+t->win_pre+1,1);
- t->onset_keep = new_fvec(t->win_post+t->win_pre+1,1);
- t->onset_proc = new_fvec(t->win_post+t->win_pre+1,1);
- t->onset_peek = new_fvec(3,1);
+ t->scratch = new_fvec(t->win_post+t->win_pre+1, channels);
+ t->onset_keep = new_fvec(t->win_post+t->win_pre+1, channels);
+ t->onset_proc = new_fvec(t->win_post+t->win_pre+1, channels);
+ t->onset_peek = new_fvec(3, channels);
/* cutoff: low-pass filter cutoff [0.34, 1] */
/* t->cutoff=0.34; */
#endif
/** function pointer to thresholding function */
-typedef smpl_t (*aubio_thresholdfn_t)(fvec_t *input);
+typedef smpl_t (*aubio_thresholdfn_t)(fvec_t *input, uint_t channel);
/** function pointer to peak-picking function */
typedef uint_t (*aubio_pickerfn_t)(fvec_t *input, uint_t pos);
/** peak-picker structure */
typedef struct _aubio_peakpicker_t aubio_peakpicker_t;
/** peak-picker creation function */
-aubio_peakpicker_t * new_aubio_peakpicker(smpl_t threshold);
+aubio_peakpicker_t * new_aubio_peakpicker(uint_t channels);
/** real time peak picking function */
-smpl_t aubio_peakpicker_do(aubio_peakpicker_t * p, fvec_t * DF);
+void aubio_peakpicker_do(aubio_peakpicker_t * p, fvec_t * in, fvec_t * out);
/** get current peak value */
smpl_t aubio_peakpicker_get_thresholded_input(aubio_peakpicker_t * p);
/** destroy peak picker structure */
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); /* adaptative threshold */
+ fvec_adapt_thres(mag,tmp,p->win_post,p->win_pre,i); /* adaptative threshold */
fvec_add(mag,-p->threshold); /* fixed threshold */
{
aubio_spectralpeak_t * peaks = (aubio_spectralpeak_t *)p->peaks;
if (ispeak) {
count += ispeak;
spectral_peaks[count-1].bin = j;
- spectral_peaks[count-1].ebin = fvec_quadint(X, j, 1) - 1.;
+ spectral_peaks[count-1].ebin = fvec_quadint(X, j, i) - 1.;
}
}
return count;
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,1);
+ out->data[c][0] = fvec_quadint(yin,period,c);
goto beach;
}
}
- out->data[c][0] = fvec_quadint(yin,fvec_min_elem(yin),1);
+ out->data[c][0] = fvec_quadint(yin,fvec_min_elem(yin),c);
beach:
continue;
}
//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,1);
+ 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,1);
+ output->data[i][0] = fvec_quadint(yin,halfperiod,i);
else
- output->data[i][0] = fvec_quadint(yin,tau,1);
+ output->data[i][0] = fvec_quadint(yin,tau,i);
}
} else {
output->data[i][0] = 0.;
/* find non-zero Rayleigh period */
maxindex = fvec_max_elem (bt->acfout);
- bt->rp = maxindex ? fvec_quadint (bt->acfout, maxindex, 1) : 1;
+ bt->rp = maxindex ? fvec_quadint (bt->acfout, maxindex, 0) : 1;
//rp = (maxindex==127) ? 43 : maxindex; //rayparam
bt->rp = (maxindex == bt->acfout->length - 1) ? bt->rayparam : maxindex; //rayparam
#endif /* AUBIO_BEAT_WARNINGS */
phase = step - bt->lastbeat;
} else {
- phase = fvec_quadint (bt->phout, maxindex, 1);
+ phase = fvec_quadint (bt->phout, maxindex, 0);
}
/* take back one frame delay */
phase += 1.;
}
}
fvec_weight (acfout, bt->gwv);
- gp = fvec_quadint (acfout, fvec_max_elem (acfout), 1);
+ gp = fvec_quadint (acfout, fvec_max_elem (acfout), 0);
/*
while(gp<32) gp =gp*2;
while(gp>64) gp = gp/2;
aubio_beattracking_get_bpm (aubio_beattracking_t * bt)
{
if (bt->timesig != 0 && bt->counter == 0 && bt->flagstep == 0) {
- return 5168. / fvec_quadint (bt->acfout, bt->bp, 1);
+ return 5168. / fvec_quadint (bt->acfout, bt->bp, 0);
} else {
return 0.;
}
fvec_t * of; /** onset detection function value */
fvec_t * dfframe; /** peak picked detection function buffer */
fvec_t * out; /** beat tactus candidates */
+ fvec_t * onset; /** onset results */
+ fvec_t * peek; /** thresholded onset function */
smpl_t silence; /** silence parameter */
smpl_t threshold; /** peak picking threshold */
sint_t blockpos; /** current position in dfframe */
o->blockpos = -1;
}
o->blockpos++;
- tempo->data[0][1] = aubio_peakpicker_do (o->pp, o->of);
+ aubio_peakpicker_do (o->pp, o->of, o->onset);
+ tempo->data[0][1] = o->onset->data[0][0];
o->dfframe->data[0][winlen - step + o->blockpos] =
aubio_peakpicker_get_thresholded_input(o->pp);
/* end of second level loop */
o->fftgrain = new_cvec(buf_size, channels);
o->out = new_fvec(o->step,channels);
o->pv = new_aubio_pvoc(buf_size, hop_size, channels);
- o->pp = new_aubio_peakpicker(o->threshold);
+ o->pp = new_aubio_peakpicker(channels);
+ aubio_peakpicker_set_threshold (o->pp, o->threshold);
o->od = new_aubio_onsetdetection(onset_mode,buf_size,channels);
o->of = new_fvec(1, channels);
o->bt = new_aubio_beattracking(o->winlen,channels);
+ o->onset = new_fvec(1, channels);
+ o->peek = new_fvec(3, channels);
/*if (usedoubled) {
o2 = new_aubio_onsetdetection(type_onset2,buffer_size,channels);
onset2 = new_fvec(1 , channels);
del_fvec(o->of);
del_cvec(o->fftgrain);
del_fvec(o->dfframe);
+ del_fvec(o->onset);
+ del_fvec(o->peek);
AUBIO_FREE(o);
return;
}
uint_t win_s = 1024; /* window size */
uint_t channels = 1; /* number of channel */
fvec_t * in = new_fvec (win_s, channels); /* input buffer */
- aubio_peakpicker_t * o = new_aubio_peakpicker(0.3);
+ fvec_t * out = new_fvec (1, channels); /* input buffer */
+ aubio_peakpicker_t * o = new_aubio_peakpicker(1);
+ aubio_peakpicker_set_threshold (o, 0.3);
- aubio_peakpicker_do(o, in);
- aubio_peakpicker_do(o, in);
- aubio_peakpicker_do(o, in);
- aubio_peakpicker_do(o, in);
+ aubio_peakpicker_do(o, in, out);
+ aubio_peakpicker_do(o, in, out);
+ aubio_peakpicker_do(o, in, out);
+ aubio_peakpicker_do(o, in, out);
del_aubio_peakpicker(o);
del_fvec(in);