aubio_onsetdetection_type type; /**< onset detection type */
/** Pointer to aubio_onsetdetection_<type> function */
void (*funcpointer)(aubio_onsetdetection_t *o,
- cvec_t * fftgrain, fvec_t * onset);
+ cvec_t * fftgrain, fvec_t * onset);
smpl_t threshold; /**< minimum norm threshold for phase and specdiff */
fvec_t *oldmag; /**< previous norm vector */
fft_data_t *meas; /**< current onset detection measure complex vector */
/* Energy based onset detection function */
void aubio_onsetdetection_energy (aubio_onsetdetection_t *o UNUSED,
- cvec_t * fftgrain, fvec_t * onset) {
- uint_t i,j;
- for (i=0;i<fftgrain->channels;i++) {
- onset->data[i][0] = 0.;
- for (j=0;j<fftgrain->length;j++) {
- onset->data[i][0] += SQR(fftgrain->norm[i][j]);
- }
- }
+ cvec_t * fftgrain, fvec_t * onset) {
+ uint_t i,j;
+ for (i=0;i<fftgrain->channels;i++) {
+ onset->data[i][0] = 0.;
+ for (j=0;j<fftgrain->length;j++) {
+ onset->data[i][0] += SQR(fftgrain->norm[i][j]);
+ }
+ }
}
/* High Frequency Content onset detection function */
void aubio_onsetdetection_hfc(aubio_onsetdetection_t *o UNUSED,
cvec_t * fftgrain, fvec_t * onset){
- uint_t i,j;
- for (i=0;i<fftgrain->channels;i++) {
- onset->data[i][0] = 0.;
- for (j=0;j<fftgrain->length;j++) {
- onset->data[i][0] += (j+1)*fftgrain->norm[i][j];
- }
- }
+ uint_t i,j;
+ for (i=0;i<fftgrain->channels;i++) {
+ onset->data[i][0] = 0.;
+ for (j=0;j<fftgrain->length;j++) {
+ onset->data[i][0] += (j+1)*fftgrain->norm[i][j];
+ }
+ }
}
/* Complex Domain Method onset detection function */
void aubio_onsetdetection_complex (aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset) {
- uint_t i, j;
- uint_t nbins = fftgrain->length;
- for (i=0;i<fftgrain->channels; i++) {
- onset->data[i][0] = 0.;
- for (j=0;j<nbins; j++) {
- o->dev1->data[i][j] = aubio_unwrap2pi(
- fftgrain->phas[i][j]
- -2.0*o->theta1->data[i][j]+
- o->theta2->data[i][j]);
+ uint_t i, j;
+ uint_t nbins = fftgrain->length;
+ for (i=0;i<fftgrain->channels; i++) {
+ onset->data[i][0] = 0.;
+ for (j=0;j<nbins; j++) {
+ o->dev1->data[i][j] = aubio_unwrap2pi(
+ fftgrain->phas[i][j]
+ -2.0*o->theta1->data[i][j]+
+ o->theta2->data[i][j]);
#ifdef HAVE_COMPLEX_H
- o->meas[j] = fftgrain->norm[i][j]*CEXPC(I*o->dev1->data[i][j]);
- /* sum on all bins */
- onset->data[i][0] += //(fftgrain->norm[i][j]);
- SQRT(SQR( REAL(o->oldmag->data[i][j]-o->meas[j]) )
- + SQR( IMAG(o->oldmag->data[i][j]-o->meas[j]) )
- );
+ o->meas[j] = fftgrain->norm[i][j]*CEXPC(I*o->dev1->data[i][j]);
+ /* sum on all bins */
+ onset->data[i][0] += //(fftgrain->norm[i][j]);
+ SQRT(SQR( REAL(o->oldmag->data[i][j]-o->meas[j]) )
+ + SQR( IMAG(o->oldmag->data[i][j]-o->meas[j]) )
+ );
#else
- o->meas[j] = (fftgrain->norm[i][j])*COS(o->dev1->data[i][j]);
- o->meas[(nbins-1)*2-j] = (fftgrain->norm[i][j])*SIN(o->dev1->data[i][j]);
- /* sum on all bins */
- onset->data[i][0] += //(fftgrain->norm[i][j]);
- SQRT(SQR( (o->oldmag->data[i][j]-o->meas[j]) )
- + SQR( (-o->meas[(nbins-1)*2-j]) )
- );
+ o->meas[j] = (fftgrain->norm[i][j])*COS(o->dev1->data[i][j]);
+ o->meas[(nbins-1)*2-j] = (fftgrain->norm[i][j])*SIN(o->dev1->data[i][j]);
+ /* sum on all bins */
+ onset->data[i][0] += //(fftgrain->norm[i][j]);
+ SQRT(SQR( (o->oldmag->data[i][j]-o->meas[j]) )
+ + SQR( (-o->meas[(nbins-1)*2-j]) )
+ );
#endif
- /* swap old phase data (need to remember 2 frames behind)*/
- o->theta2->data[i][j] = o->theta1->data[i][j];
- o->theta1->data[i][j] = fftgrain->phas[i][j];
- /* swap old magnitude data (1 frame is enough) */
- o->oldmag->data[i][j] = fftgrain->norm[i][j];
- }
- }
+ /* swap old phase data (need to remember 2 frames behind)*/
+ o->theta2->data[i][j] = o->theta1->data[i][j];
+ o->theta1->data[i][j] = fftgrain->phas[i][j];
+ /* swap old magnitude data (1 frame is enough) */
+ o->oldmag->data[i][j] = fftgrain->norm[i][j];
+ }
+ }
}
/* Phase Based Method onset detection function */
void aubio_onsetdetection_phase(aubio_onsetdetection_t *o,
- cvec_t * fftgrain, fvec_t * onset){
- uint_t i, j;
- uint_t nbins = fftgrain->length;
- for (i=0;i<fftgrain->channels; i++) {
- onset->data[i][0] = 0.0f;
- o->dev1->data[i][0]=0.;
- for ( j=0;j<nbins; j++ ) {
- o->dev1->data[i][j] =
- aubio_unwrap2pi(
- fftgrain->phas[i][j]
- -2.0*o->theta1->data[i][j]
- +o->theta2->data[i][j]);
- if ( o->threshold < fftgrain->norm[i][j] )
- o->dev1->data[i][j] = ABS(o->dev1->data[i][j]);
- else
- o->dev1->data[i][j] = 0.0f;
- /* keep a track of the past frames */
- o->theta2->data[i][j] = o->theta1->data[i][j];
- o->theta1->data[i][j] = fftgrain->phas[i][j];
- }
- /* apply o->histogram */
- aubio_hist_dyn_notnull(o->histog,o->dev1);
- /* weight it */
- aubio_hist_weight(o->histog);
- /* its mean is the result */
- onset->data[i][0] = aubio_hist_mean(o->histog);
- //onset->data[i][0] = vec_mean(o->dev1);
- }
+ cvec_t * fftgrain, fvec_t * onset){
+ uint_t i, j;
+ uint_t nbins = fftgrain->length;
+ for (i=0;i<fftgrain->channels; i++) {
+ onset->data[i][0] = 0.0f;
+ o->dev1->data[i][0]=0.;
+ for ( j=0;j<nbins; j++ ) {
+ o->dev1->data[i][j] =
+ aubio_unwrap2pi(
+ fftgrain->phas[i][j]
+ -2.0*o->theta1->data[i][j]
+ +o->theta2->data[i][j]);
+ if ( o->threshold < fftgrain->norm[i][j] )
+ o->dev1->data[i][j] = ABS(o->dev1->data[i][j]);
+ else
+ o->dev1->data[i][j] = 0.0f;
+ /* keep a track of the past frames */
+ o->theta2->data[i][j] = o->theta1->data[i][j];
+ o->theta1->data[i][j] = fftgrain->phas[i][j];
+ }
+ /* apply o->histogram */
+ aubio_hist_dyn_notnull(o->histog,o->dev1);
+ /* weight it */
+ aubio_hist_weight(o->histog);
+ /* its mean is the result */
+ onset->data[i][0] = aubio_hist_mean(o->histog);
+ //onset->data[i][0] = vec_mean(o->dev1);
+ }
}
/* Spectral difference method onset detection function */
void aubio_onsetdetection_specdiff(aubio_onsetdetection_t *o,
- cvec_t * fftgrain, fvec_t * onset){
- uint_t i, j;
- uint_t nbins = fftgrain->length;
- for (i=0;i<fftgrain->channels; i++) {
- onset->data[i][0] = 0.0f;
- for (j=0;j<nbins; j++) {
- o->dev1->data[i][j] = SQRT(
- ABS(SQR( fftgrain->norm[i][j])
- - SQR(o->oldmag->data[i][j])));
- if (o->threshold < fftgrain->norm[i][j] )
- o->dev1->data[i][j] = ABS(o->dev1->data[i][j]);
- else
- o->dev1->data[i][j] = 0.0f;
- o->oldmag->data[i][j] = fftgrain->norm[i][j];
- }
+ cvec_t * fftgrain, fvec_t * onset){
+ uint_t i, j;
+ uint_t nbins = fftgrain->length;
+ for (i=0;i<fftgrain->channels; i++) {
+ onset->data[i][0] = 0.0f;
+ for (j=0;j<nbins; j++) {
+ o->dev1->data[i][j] = SQRT(
+ ABS(SQR( fftgrain->norm[i][j])
+ - SQR(o->oldmag->data[i][j])));
+ if (o->threshold < fftgrain->norm[i][j] )
+ o->dev1->data[i][j] = ABS(o->dev1->data[i][j]);
+ else
+ o->dev1->data[i][j] = 0.0f;
+ o->oldmag->data[i][j] = fftgrain->norm[i][j];
+ }
- /* apply o->histogram (act somewhat as a low pass on the
- * overall function)*/
- aubio_hist_dyn_notnull(o->histog,o->dev1);
- /* weight it */
- aubio_hist_weight(o->histog);
- /* its mean is the result */
- onset->data[i][0] = aubio_hist_mean(o->histog);
+ /* apply o->histogram (act somewhat as a low pass on the
+ * overall function)*/
+ aubio_hist_dyn_notnull(o->histog,o->dev1);
+ /* weight it */
+ aubio_hist_weight(o->histog);
+ /* its mean is the result */
+ onset->data[i][0] = aubio_hist_mean(o->histog);
- }
+ }
}
/* Kullback Liebler onset detection function
* note we use ln(1+Xn/(Xn-1+0.0001)) to avoid
* negative (1.+) and infinite values (+1.e-10) */
void aubio_onsetdetection_kl(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset){
- uint_t i,j;
- for (i=0;i<fftgrain->channels;i++) {
- onset->data[i][0] = 0.;
- for (j=0;j<fftgrain->length;j++) {
- onset->data[i][0] += fftgrain->norm[i][j]
- *LOG(1.+fftgrain->norm[i][j]/(o->oldmag->data[i][j]+1.e-10));
- o->oldmag->data[i][j] = fftgrain->norm[i][j];
- }
- if (isnan(onset->data[i][0])) onset->data[i][0] = 0.;
- }
+ uint_t i,j;
+ for (i=0;i<fftgrain->channels;i++) {
+ onset->data[i][0] = 0.;
+ for (j=0;j<fftgrain->length;j++) {
+ onset->data[i][0] += fftgrain->norm[i][j]
+ *LOG(1.+fftgrain->norm[i][j]/(o->oldmag->data[i][j]+1.e-10));
+ o->oldmag->data[i][j] = fftgrain->norm[i][j];
+ }
+ if (isnan(onset->data[i][0])) onset->data[i][0] = 0.;
+ }
}
/* Modified Kullback Liebler onset detection function
* note we use ln(1+Xn/(Xn-1+0.0001)) to avoid
* negative (1.+) and infinite values (+1.e-10) */
void aubio_onsetdetection_mkl(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset){
- uint_t i,j;
- for (i=0;i<fftgrain->channels;i++) {
- onset->data[i][0] = 0.;
- for (j=0;j<fftgrain->length;j++) {
- onset->data[i][0] += LOG(1.+fftgrain->norm[i][j]/(o->oldmag->data[i][j]+1.e-10));
- o->oldmag->data[i][j] = fftgrain->norm[i][j];
- }
- if (isnan(onset->data[i][0])) onset->data[i][0] = 0.;
- }
+ uint_t i,j;
+ for (i=0;i<fftgrain->channels;i++) {
+ onset->data[i][0] = 0.;
+ for (j=0;j<fftgrain->length;j++) {
+ onset->data[i][0] += LOG(1.+fftgrain->norm[i][j]/(o->oldmag->data[i][j]+1.e-10));
+ o->oldmag->data[i][j] = fftgrain->norm[i][j];
+ }
+ if (isnan(onset->data[i][0])) onset->data[i][0] = 0.;
+ }
}
/* Generic function pointing to the choosen one */
void
aubio_onsetdetection(aubio_onsetdetection_t *o, cvec_t * fftgrain,
- fvec_t * onset) {
- o->funcpointer(o,fftgrain,onset);
+ fvec_t * onset) {
+ o->funcpointer(o,fftgrain,onset);
}
/* Allocate memory for an onset detection
*/
aubio_onsetdetection_t *
new_aubio_onsetdetection (aubio_onsetdetection_type type,
- uint_t size, uint_t channels){
- aubio_onsetdetection_t * o = AUBIO_NEW(aubio_onsetdetection_t);
- uint_t rsize = size/2+1;
+ uint_t size, uint_t channels){
+ aubio_onsetdetection_t * o = AUBIO_NEW(aubio_onsetdetection_t);
+ uint_t rsize = size/2+1;
uint_t i;
- switch(type) {
- /* for both energy and hfc, only fftgrain->norm is required */
- case aubio_onset_energy:
- break;
- case aubio_onset_hfc:
- break;
- /* the other approaches will need some more memory spaces */
- case aubio_onset_complex:
- o->oldmag = new_fvec(rsize,channels);
- /** bug: must be complex array */
- o->meas = AUBIO_ARRAY(fft_data_t,size+1);
- for (i=0; i<size+1; i++) o->meas[i] = 0;
- o->dev1 = new_fvec(rsize,channels);
- o->theta1 = new_fvec(rsize,channels);
- o->theta2 = new_fvec(rsize,channels);
- break;
- case aubio_onset_phase:
- o->dev1 = new_fvec(rsize,channels);
- o->theta1 = new_fvec(rsize,channels);
- o->theta2 = new_fvec(rsize,channels);
- o->histog = new_aubio_hist(0.0f, PI, 10, channels);
- o->threshold = 0.1;
- break;
- case aubio_onset_specdiff:
- o->oldmag = new_fvec(rsize,channels);
- o->dev1 = new_fvec(rsize,channels);
- o->histog = new_aubio_hist(0.0f, PI, 10, channels);
- o->threshold = 0.1;
- break;
- case aubio_onset_kl:
- o->oldmag = new_fvec(rsize,channels);
- break;
- case aubio_onset_mkl:
- o->oldmag = new_fvec(rsize,channels);
- break;
- default:
- break;
- }
-
- /* this switch could be in its own function to change between
- * detections on the fly. this would need getting rid of the switch
- * above and always allocate all the structure */
+ switch(type) {
+ /* for both energy and hfc, only fftgrain->norm is required */
+ case aubio_onset_energy:
+ break;
+ case aubio_onset_hfc:
+ break;
+ /* the other approaches will need some more memory spaces */
+ case aubio_onset_complex:
+ o->oldmag = new_fvec(rsize,channels);
+ /** bug: must be complex array */
+ o->meas = AUBIO_ARRAY(fft_data_t,size+1);
+ for (i=0; i<size+1; i++) o->meas[i] = 0;
+ o->dev1 = new_fvec(rsize,channels);
+ o->theta1 = new_fvec(rsize,channels);
+ o->theta2 = new_fvec(rsize,channels);
+ break;
+ case aubio_onset_phase:
+ o->dev1 = new_fvec(rsize,channels);
+ o->theta1 = new_fvec(rsize,channels);
+ o->theta2 = new_fvec(rsize,channels);
+ o->histog = new_aubio_hist(0.0f, PI, 10, channels);
+ o->threshold = 0.1;
+ break;
+ case aubio_onset_specdiff:
+ o->oldmag = new_fvec(rsize,channels);
+ o->dev1 = new_fvec(rsize,channels);
+ o->histog = new_aubio_hist(0.0f, PI, 10, channels);
+ o->threshold = 0.1;
+ break;
+ case aubio_onset_kl:
+ case aubio_onset_mkl:
+ o->oldmag = new_fvec(rsize,channels);
+ break;
+ default:
+ break;
+ }
- switch(type) {
- case aubio_onset_energy:
- o->funcpointer = aubio_onsetdetection_energy;
- break;
- case aubio_onset_hfc:
- o->funcpointer = aubio_onsetdetection_hfc;
- break;
- case aubio_onset_complex:
- o->funcpointer = aubio_onsetdetection_complex;
- break;
- case aubio_onset_phase:
- o->funcpointer = aubio_onsetdetection_phase;
- break;
- case aubio_onset_specdiff:
- o->funcpointer = aubio_onsetdetection_specdiff;
- break;
- case aubio_onset_kl:
- o->funcpointer = aubio_onsetdetection_kl;
- break;
- case aubio_onset_mkl:
- o->funcpointer = aubio_onsetdetection_mkl;
- break;
- default:
- break;
- }
- o->type = type;
- return o;
+ /* this switch could be in its own function to change between
+ * detections on the fly. this would need getting rid of the switch
+ * above and always allocate all the structure */
+
+ switch(type) {
+ case aubio_onset_energy:
+ o->funcpointer = aubio_onsetdetection_energy;
+ break;
+ case aubio_onset_hfc:
+ o->funcpointer = aubio_onsetdetection_hfc;
+ break;
+ case aubio_onset_complex:
+ o->funcpointer = aubio_onsetdetection_complex;
+ break;
+ case aubio_onset_phase:
+ o->funcpointer = aubio_onsetdetection_phase;
+ break;
+ case aubio_onset_specdiff:
+ o->funcpointer = aubio_onsetdetection_specdiff;
+ break;
+ case aubio_onset_kl:
+ o->funcpointer = aubio_onsetdetection_kl;
+ break;
+ case aubio_onset_mkl:
+ o->funcpointer = aubio_onsetdetection_mkl;
+ break;
+ default:
+ break;
+ }
+ o->type = type;
+ return o;
}
void del_aubio_onsetdetection (aubio_onsetdetection_t *o){
-
- switch(o->type) {
- /* for both energy and hfc, only fftgrain->norm is required */
- case aubio_onset_energy:
- break;
- case aubio_onset_hfc:
- break;
- /* the other approaches will need some more memory spaces */
- case aubio_onset_complex:
- AUBIO_FREE(o->meas);
- del_fvec(o->oldmag);
- del_fvec(o->dev1);
- del_fvec(o->theta1);
- del_fvec(o->theta2);
- break;
- case aubio_onset_phase:
- del_fvec(o->dev1);
- del_fvec(o->theta1);
- del_fvec(o->theta2);
- del_aubio_hist(o->histog);
- break;
- case aubio_onset_specdiff:
- del_fvec(o->oldmag);
- del_fvec(o->dev1);
- del_aubio_hist(o->histog);
- break;
- case aubio_onset_kl:
- del_fvec(o->oldmag);
- break;
- case aubio_onset_mkl:
- del_fvec(o->oldmag);
- break;
- default:
- break;
- }
- AUBIO_FREE(o);
-
+ switch(o->type) {
+ /* for both energy and hfc, only fftgrain->norm is required */
+ case aubio_onset_energy:
+ break;
+ case aubio_onset_hfc:
+ break;
+ /* the other approaches will need some more memory spaces */
+ case aubio_onset_complex:
+ AUBIO_FREE(o->meas);
+ del_fvec(o->oldmag);
+ del_fvec(o->dev1);
+ del_fvec(o->theta1);
+ del_fvec(o->theta2);
+ break;
+ case aubio_onset_phase:
+ del_fvec(o->dev1);
+ del_fvec(o->theta1);
+ del_fvec(o->theta2);
+ del_aubio_hist(o->histog);
+ break;
+ case aubio_onset_specdiff:
+ del_fvec(o->oldmag);
+ del_fvec(o->dev1);
+ del_aubio_hist(o->histog);
+ break;
+ case aubio_onset_kl:
+ del_fvec(o->oldmag);
+ break;
+ case aubio_onset_mkl:
+ del_fvec(o->oldmag);
+ break;
+ default:
+ break;
+ }
+ AUBIO_FREE(o);
}