Ignore:
Timestamp:
Sep 15, 2009, 5:02:45 PM (15 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master, pitchshift, sampler, timestretch, yinfft+
Children:
06cae6c
Parents:
6f1727f
Message:

src/tempo/beattracking.c: no changes, indent

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/tempo/beattracking.c

    r6f1727f r7bf3dcb  
    11/*
    2          Copyright (C) 2005 Matthew Davies and Paul Brossier
    3 
    4          This program is free software; you can redistribute it and/or modify
    5          it under the terms of the GNU General Public License as published by
    6          the Free Software Foundation; either version 2 of the License, or
    7          (at your option) any later version.
    8 
    9          This program is distributed in the hope that it will be useful,
    10          but WITHOUT ANY WARRANTY; without even the implied warranty of
    11          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12          GNU General Public License for more details.
    13 
    14          You should have received a copy of the GNU General Public License
    15          along with this program; if not, write to the Free Software
    16          Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     2   Copyright (C) 2005 Matthew Davies and Paul Brossier
     3
     4   This program is free software; you can redistribute it and/or modify
     5   it under the terms of the GNU General Public License as published by
     6   the Free Software Foundation; either version 2 of the License, or
     7   (at your option) any later version.
     8
     9   This program is distributed in the hope that it will be useful,
     10   but WITHOUT ANY WARRANTY; without even the implied warranty of
     11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12   GNU General Public License for more details.
     13
     14   You should have received a copy of the GNU General Public License
     15   along with this program; if not, write to the Free Software
     16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    1717         
    1818*/
     
    2323#include "tempo/beattracking.h"
    2424
    25 uint_t fvec_gettimesig(fvec_t * acf, uint_t acflen, uint_t gp);
    26 void aubio_beattracking_checkstate(aubio_beattracking_t * bt);
    27 
    28 struct _aubio_beattracking_t {
    29         fvec_t * rwv;    /** rayleigh weighting for beat period in general model */
    30         fvec_t * dfwv;   /** exponential weighting for beat alignment in general model */
    31         fvec_t * gwv;    /** gaussian weighting for beat period in context dependant model */
    32         fvec_t * phwv;   /** gaussian weighting for beat alignment in context dependant model */
    33         fvec_t * dfrev;  /** reversed onset detection function */
    34         fvec_t * acf;    /** vector for autocorrelation function (of current detection function frame) */
    35         fvec_t * acfout; /** store result of passing acf through s.i.c.f.b. */
    36         fvec_t * phout;
    37         uint_t timesig;  /** time signature of input, set to zero until context dependent model activated */
    38         uint_t step;
    39         uint_t rayparam; /** Rayleigh parameter */
    40         smpl_t lastbeat;
    41         sint_t counter;
    42         uint_t flagstep;
    43         smpl_t g_var;
    44         smpl_t gp;
    45         smpl_t bp;
    46         smpl_t rp;
    47         smpl_t rp1;
    48         smpl_t rp2;
     25uint_t fvec_gettimesig (fvec_t * acf, uint_t acflen, uint_t gp);
     26void aubio_beattracking_checkstate (aubio_beattracking_t * bt);
     27
     28struct _aubio_beattracking_t
     29{
     30  fvec_t *rwv;           /** rayleigh weighting for beat period in general model */
     31  fvec_t *dfwv;          /** exponential weighting for beat alignment in general model */
     32  fvec_t *gwv;           /** gaussian weighting for beat period in context dependant model */
     33  fvec_t *phwv;          /** gaussian weighting for beat alignment in context dependant model */
     34  fvec_t *dfrev;         /** reversed onset detection function */
     35  fvec_t *acf;           /** vector for autocorrelation function (of current detection function frame) */
     36  fvec_t *acfout;        /** store result of passing acf through s.i.c.f.b. */
     37  fvec_t *phout;
     38  uint_t timesig;        /** time signature of input, set to zero until context dependent model activated */
     39  uint_t step;
     40  uint_t rayparam;       /** Rayleigh parameter */
     41  smpl_t lastbeat;
     42  sint_t counter;
     43  uint_t flagstep;
     44  smpl_t g_var;
     45  smpl_t gp;
     46  smpl_t bp;
     47  smpl_t rp;
     48  smpl_t rp1;
     49  smpl_t rp2;
    4950};
    5051
    51 aubio_beattracking_t * new_aubio_beattracking(uint_t winlen,
    52                 uint_t channels) {
    53 
    54         aubio_beattracking_t * p = AUBIO_NEW(aubio_beattracking_t);
    55         uint_t i        = 0;
    56         /* parameter for rayleigh weight vector - sets preferred tempo to
    57          * 120bpm [43] */
    58         smpl_t rayparam = 48./512. * winlen;
    59         smpl_t dfwvnorm = EXP((LOG(2.0)/rayparam)*(winlen+2));
    60         /** length over which beat period is found [128] */
    61         uint_t laglen   = winlen/4;
    62         /** step increment - both in detection function samples -i.e. 11.6ms or
    63          * 1 onset frame [128] */
    64         uint_t step     = winlen/4; /* 1.5 seconds */
    65 
    66         p->lastbeat = 0;
    67         p->counter = 0;
    68         p->flagstep = 0;
    69         p->g_var = 3.901; // constthresh empirically derived!
    70         p->rp = 1;
    71         p->gp = 0;
    72 
    73         p->rayparam = rayparam;
    74         p->step    = step;
    75         p->rwv     = new_fvec(laglen,1);
    76         p->gwv     = new_fvec(laglen,1);
    77         p->dfwv    = new_fvec(winlen,1);
    78         p->dfrev   = new_fvec(winlen,channels);
    79         p->acf     = new_fvec(winlen,channels);
    80         p->acfout  = new_fvec(laglen,channels);
    81         p->phwv    = new_fvec(2*laglen,1);
    82         p->phout   = new_fvec(winlen,channels);
    83 
    84         p->timesig = 0;
    85 
    86         /* exponential weighting, dfwv = 0.5 when i =  43 */
    87         for (i=0;i<winlen;i++) {
    88                 p->dfwv->data[0][i] = (EXP((LOG(2.0)/rayparam)*(i+1)))
    89                         / dfwvnorm;
    90         }
    91 
    92         for (i=0;i<(laglen);i++){
    93                 p->rwv->data[0][i] = ((smpl_t)(i+1.) / SQR((smpl_t)rayparam)) *
    94                         EXP((-SQR((smpl_t)(i+1.)) / (2.*SQR((smpl_t)rayparam))));
     52aubio_beattracking_t *
     53new_aubio_beattracking (uint_t winlen, uint_t channels)
     54{
     55
     56  aubio_beattracking_t *p = AUBIO_NEW (aubio_beattracking_t);
     57  uint_t i = 0;
     58  /* parameter for rayleigh weight vector - sets preferred tempo to
     59   * 120bpm [43] */
     60  smpl_t rayparam = 48. / 512. * winlen;
     61  smpl_t dfwvnorm = EXP ((LOG (2.0) / rayparam) * (winlen + 2));
     62  /* length over which beat period is found [128] */
     63  uint_t laglen = winlen / 4;
     64  /* step increment - both in detection function samples -i.e. 11.6ms or
     65   * 1 onset frame [128] */
     66  uint_t step = winlen / 4;     /* 1.5 seconds */
     67
     68  p->lastbeat = 0;
     69  p->counter = 0;
     70  p->flagstep = 0;
     71  p->g_var = 3.901;             // constthresh empirically derived!
     72  p->rp = 1;
     73  p->gp = 0;
     74
     75  p->rayparam = rayparam;
     76  p->step = step;
     77  p->rwv = new_fvec (laglen, 1);
     78  p->gwv = new_fvec (laglen, 1);
     79  p->dfwv = new_fvec (winlen, 1);
     80  p->dfrev = new_fvec (winlen, channels);
     81  p->acf = new_fvec (winlen, channels);
     82  p->acfout = new_fvec (laglen, channels);
     83  p->phwv = new_fvec (2 * laglen, 1);
     84  p->phout = new_fvec (winlen, channels);
     85
     86  p->timesig = 0;
     87
     88  /* exponential weighting, dfwv = 0.5 when i =  43 */
     89  for (i = 0; i < winlen; i++) {
     90    p->dfwv->data[0][i] = (EXP ((LOG (2.0) / rayparam) * (i + 1)))
     91        / dfwvnorm;
     92  }
     93
     94  for (i = 0; i < (laglen); i++) {
     95    p->rwv->data[0][i] = ((smpl_t) (i + 1.) / SQR ((smpl_t) rayparam)) *
     96        EXP ((-SQR ((smpl_t) (i + 1.)) / (2. * SQR ((smpl_t) rayparam))));
     97  }
     98
     99  return p;
     100
     101}
     102
     103void
     104del_aubio_beattracking (aubio_beattracking_t * p)
     105{
     106  del_fvec (p->rwv);
     107  del_fvec (p->gwv);
     108  del_fvec (p->dfwv);
     109  del_fvec (p->dfrev);
     110  del_fvec (p->acf);
     111  del_fvec (p->acfout);
     112  del_fvec (p->phwv);
     113  del_fvec (p->phout);
     114  AUBIO_FREE (p);
     115}
     116
     117
     118void
     119aubio_beattracking_do (aubio_beattracking_t * bt, fvec_t * dfframe,
     120    fvec_t * output)
     121{
     122
     123  uint_t i, k;
     124  uint_t step = bt->step;
     125  uint_t laglen = bt->rwv->length;
     126  uint_t winlen = bt->dfwv->length;
     127  uint_t maxindex = 0;
     128  //number of harmonics in shift invariant comb filterbank
     129  uint_t numelem = 4;
     130
     131  smpl_t phase;                 // beat alignment (step - lastbeat)
     132  smpl_t beat;                  // beat position
     133  smpl_t bp;                    // beat period
     134  uint_t a, b;                  // used to build shift invariant comb filterbank
     135  uint_t kmax;                  // number of elements used to find beat phase
     136
     137  /* copy dfframe, apply detection function weighting, and revert */
     138  fvec_copy (dfframe, bt->dfrev);
     139  fvec_weight (bt->dfrev, bt->dfwv);
     140  fvec_rev (bt->dfrev);
     141
     142  /* compute autocorrelation function */
     143  aubio_autocorr (dfframe, bt->acf);
     144
     145  /* if timesig is unknown, use metrically unbiased version of filterbank */
     146  if (!bt->timesig) {
     147    numelem = 4;
     148  } else {
     149    numelem = bt->timesig;
     150  }
     151
     152  /* first and last output values are left intentionally as zero */
     153  fvec_zeros (bt->acfout);
     154
     155  /* compute shift invariant comb filterbank */
     156  for (i = 1; i < laglen - 1; i++) {
     157    for (a = 1; a <= numelem; a++) {
     158      for (b = (1 - a); b < a; b++) {
     159        bt->acfout->data[0][i] += bt->acf->data[0][a * (i + 1) + b - 1]
     160            * 1. / (2. * a - 1.);
     161      }
     162    }
     163  }
     164  /* apply Rayleigh weight */
     165  fvec_weight (bt->acfout, bt->rwv);
     166
     167  /* find non-zero Rayleigh period */
     168  maxindex = vec_max_elem (bt->acfout);
     169  bt->rp = maxindex ? vec_quadint (bt->acfout, maxindex, 1) : 1;
     170  //rp = (maxindex==127) ? 43 : maxindex; //rayparam
     171  bt->rp = (maxindex == bt->acfout->length - 1) ? bt->rayparam : maxindex;      //rayparam
     172
     173  /* activate biased filterbank */
     174  aubio_beattracking_checkstate (bt);
     175#if 0                           // debug metronome mode
     176  bt->bp = 36.9142;
     177#endif
     178  bp = bt->bp;
     179  /* end of biased filterbank */
     180
     181
     182  /* deliberate integer operation, could be set to 3 max eventually */
     183  kmax = FLOOR (winlen / bp);
     184
     185  /* initialize output */
     186  fvec_zeros (bt->phout);
     187  for (i = 0; i < bp; i++) {
     188    for (k = 0; k < kmax; k++) {
     189      bt->phout->data[0][i] += bt->dfrev->data[0][i + (uint_t) ROUND (bp * k)];
     190    }
     191  }
     192  fvec_weight (bt->phout, bt->phwv);
     193
     194  /* find Rayleigh period */
     195  maxindex = vec_max_elem (bt->phout);
     196  if (maxindex == winlen)
     197    maxindex = 0;
     198  phase = 1. + vec_quadint (bt->phout, maxindex, 1);
     199#if 0                           // debug metronome mode
     200  phase = step - bt->lastbeat;
     201#endif
     202
     203  /* reset output */
     204  fvec_zeros (output);
     205
     206  i = 1;
     207  beat = bp - phase;
     208  /* start counting the beats */
     209  if (beat >= 0) {
     210    output->data[0][i] = beat;
     211    i++;
     212  }
     213
     214  while (beat + bp <= step) {
     215    beat += bp;
     216    output->data[0][i] = beat;
     217    i++;
     218  }
     219
     220  bt->lastbeat = beat;
     221  /* store the number of beat found in this frame as the first element */
     222  output->data[0][0] = i;
     223}
     224
     225uint_t
     226fvec_gettimesig (fvec_t * acf, uint_t acflen, uint_t gp)
     227{
     228  sint_t k = 0;
     229  smpl_t three_energy = 0., four_energy = 0.;
     230  if (acflen > 6 * gp + 2) {
     231    for (k = -2; k < 2; k++) {
     232      three_energy += acf->data[0][3 * gp + k];
     233      four_energy += acf->data[0][4 * gp + k];
     234    }
     235  } else {
     236    /*Expanded to be more accurate in time sig estimation */
     237    for (k = -2; k < 2; k++) {
     238      three_energy += acf->data[0][3 * gp + k] + acf->data[0][6 * gp + k];
     239      four_energy += acf->data[0][4 * gp + k] + acf->data[0][2 * gp + k];
     240    }
     241  }
     242  return (three_energy > four_energy) ? 3 : 4;
     243}
     244
     245void
     246aubio_beattracking_checkstate (aubio_beattracking_t * bt)
     247{
     248  uint_t i, j, a, b;
     249  uint_t flagconst = 0;
     250  sint_t counter = bt->counter;
     251  uint_t flagstep = bt->flagstep;
     252  smpl_t gp = bt->gp;
     253  smpl_t bp = bt->bp;
     254  smpl_t rp = bt->rp;
     255  smpl_t rp1 = bt->rp1;
     256  smpl_t rp2 = bt->rp2;
     257  uint_t laglen = bt->rwv->length;
     258  uint_t acflen = bt->acf->length;
     259  uint_t step = bt->step;
     260  fvec_t *acf = bt->acf;
     261  fvec_t *acfout = bt->acfout;
     262
     263  if (gp) {
     264    // doshiftfbank again only if context dependent model is in operation
     265    //acfout = doshiftfbank(acf,gwv,timesig,laglen,acfout);
     266    //don't need acfout now, so can reuse vector
     267    // gwv is, in first loop, definitely all zeros, but will have
     268    // proper values when context dependent model is activated
     269    fvec_zeros (acfout);
     270    for (i = 1; i < laglen - 1; i++) {
     271      for (a = 1; a <= bt->timesig; a++) {
     272        for (b = (1 - a); b < a; b++) {
     273          acfout->data[0][i] += acf->data[0][a * (i + 1) + b - 1];
    95274        }
    96 
    97         return p;
    98 
    99 }
    100 
    101 void del_aubio_beattracking(aubio_beattracking_t * p) {
    102         del_fvec(p->rwv);
    103         del_fvec(p->gwv);
    104         del_fvec(p->dfwv);
    105         del_fvec(p->dfrev);
    106         del_fvec(p->acf);
    107         del_fvec(p->acfout);
    108         del_fvec(p->phwv);
    109         del_fvec(p->phout);
    110         AUBIO_FREE(p);
    111 }
    112 
    113 
    114 void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframe, fvec_t * output) {
    115 
    116         uint_t i,k;
    117         uint_t step     = bt->step;
    118         uint_t laglen   = bt->rwv->length;
    119         uint_t winlen   = bt->dfwv->length;
    120         uint_t maxindex = 0;
    121         //number of harmonics in shift invariant comb filterbank
    122         uint_t numelem  = 4;
    123 
    124         smpl_t phase; // beat alignment (step - lastbeat)
    125         smpl_t beat;  // beat position
    126         smpl_t bp;    // beat period
    127         uint_t a,b;   // used to build shift invariant comb filterbank
    128         uint_t kmax;  // number of elements used to find beat phase
    129 
    130         /* copy dfframe, apply detection function weighting, and revert */
    131         fvec_copy(dfframe, bt->dfrev);
    132         fvec_weight(bt->dfrev, bt->dfwv);
    133         fvec_rev(bt->dfrev);
    134 
    135         /* compute autocorrelation function */
    136         aubio_autocorr(dfframe,bt->acf);
    137 
    138         /* if timesig is unknown, use metrically unbiased version of filterbank */
    139         if(!bt->timesig) {
    140                 numelem = 4;
    141         } else {
    142                 numelem = bt->timesig;
    143         }
    144 
    145         /* first and last output values are left intentionally as zero */
    146         fvec_zeros(bt->acfout);
    147 
    148         /* compute shift invariant comb filterbank */
    149         for(i=1;i<laglen-1;i++){
    150                 for (a=1; a<=numelem; a++){
    151                         for(b=(1-a); b<a; b++){
    152                                 bt->acfout->data[0][i] += bt->acf->data[0][a*(i+1)+b-1]
    153                                         * 1./(2.*a-1.);
    154                         }
    155                 }
    156         }
    157         /* apply Rayleigh weight */
    158         fvec_weight(bt->acfout, bt->rwv);
    159 
    160         /* find non-zero Rayleigh period */
    161         maxindex = vec_max_elem(bt->acfout);
    162         bt->rp = maxindex ? vec_quadint(bt->acfout, maxindex, 1) : 1;
    163         //rp = (maxindex==127) ? 43 : maxindex; //rayparam
    164         bt->rp = (maxindex==bt->acfout->length-1) ? bt->rayparam : maxindex; //rayparam
    165 
    166         /* activate biased filterbank */
    167         aubio_beattracking_checkstate(bt);
    168 #if 0 // debug metronome mode
    169         bt->bp = 36.9142;
    170 #endif
    171         bp = bt->bp;
    172         /* end of biased filterbank */
    173 
    174 
    175         /* deliberate integer operation, could be set to 3 max eventually */
    176         kmax = FLOOR(winlen/bp);
    177 
    178         /* initialize output */
    179         fvec_zeros(bt->phout);
    180         for(i=0;i<bp;i++){
    181                 for(k=0;k<kmax;k++){
    182                         bt->phout->data[0][i] += bt->dfrev->data[0][i+(uint_t)ROUND(bp*k)];
    183                 }
    184         }
    185         fvec_weight(bt->phout, bt->phwv);
    186 
    187         /* find Rayleigh period */
    188         maxindex = vec_max_elem(bt->phout);
    189         if (maxindex == winlen) maxindex = 0;
    190         phase =  1. + vec_quadint(bt->phout, maxindex, 1);
    191 #if 0 // debug metronome mode
    192         phase = step - bt->lastbeat;
    193 #endif
    194 
    195         /* reset output */
    196         fvec_zeros(output);
    197 
    198         i = 1;
    199         beat = bp - phase;
    200         /* start counting the beats */
    201         if(beat >= 0) {
    202                 output->data[0][i] = beat;
    203                 i++;
    204         }
    205 
    206         while( beat + bp <= step) {
    207                 beat += bp;
    208                 output->data[0][i] = beat;
    209                 i++;
    210         }
    211 
    212         bt->lastbeat = beat;
    213         /* store the number of beat found in this frame as the first element */
    214         output->data[0][0] = i;
    215 }
    216 
    217 uint_t fvec_gettimesig(fvec_t * acf, uint_t acflen, uint_t gp){
    218         sint_t k = 0;
    219         smpl_t three_energy = 0., four_energy = 0.;
    220         if( acflen > 6 * gp + 2 ){
    221                 for(k=-2;k<2;k++){
    222                         three_energy += acf->data[0][3*gp+k];
    223                         four_energy += acf->data[0][4*gp+k];
    224                 }
    225         }
    226         else{ /*Expanded to be more accurate in time sig estimation*/
    227                 for(k=-2;k<2;k++){
    228                         three_energy += acf->data[0][3*gp+k]+acf->data[0][6*gp+k];
    229                         four_energy += acf->data[0][4*gp+k]+acf->data[0][2*gp+k];
    230                 }
    231         }
    232         return (three_energy > four_energy) ? 3 : 4;
    233 }
    234 
    235 void aubio_beattracking_checkstate(aubio_beattracking_t * bt) {
    236         uint_t i,j,a,b;
    237         uint_t flagconst  = 0;
    238         sint_t counter  = bt->counter;
    239         uint_t flagstep = bt->flagstep;
    240         smpl_t gp       = bt->gp;
    241         smpl_t bp       = bt->bp;
    242         smpl_t rp       = bt->rp;
    243         smpl_t rp1      = bt->rp1;
    244         smpl_t rp2      = bt->rp2;
    245         uint_t laglen   = bt->rwv->length;
    246         uint_t acflen   = bt->acf->length;
    247         uint_t step     = bt->step;
    248         fvec_t * acf    = bt->acf;
    249         fvec_t * acfout = bt->acfout;
    250 
    251         if (gp) {
    252                 // doshiftfbank again only if context dependent model is in operation
    253                 //acfout = doshiftfbank(acf,gwv,timesig,laglen,acfout);
    254                 //don't need acfout now, so can reuse vector
    255                 // gwv is, in first loop, definitely all zeros, but will have
    256                 // proper values when context dependent model is activated
    257                 fvec_zeros(acfout);
    258                 for(i=1;i<laglen-1;i++){
    259                         for (a=1;a<=bt->timesig;a++){
    260                                 for(b=(1-a);b<a;b++){
    261                                         acfout->data[0][i] += acf->data[0][a*(i+1)+b-1];
    262                                 }
    263                         }
    264                 }
    265                 fvec_weight(acfout, bt->gwv);
    266                 gp = vec_quadint(acfout, vec_max_elem(acfout), 1);
    267                 /*
    268                 while(gp<32) gp =gp*2;
    269                 while(gp>64) gp = gp/2;
    270                 */
    271         } else {
    272                 //still only using general model
    273                 gp = 0; 
    274         }
    275 
    276         //now look for step change - i.e. a difference between gp and rp that
    277         // is greater than 2*constthresh - always true in first case, since gp = 0
    278         if(counter == 0){
    279                 if(ABS(gp - rp) > 2.*bt->g_var) {
    280                         flagstep = 1; // have observed  step change.
    281                         counter  = 3; // setup 3 frame counter
    282                 } else {
    283                         flagstep = 0;
    284                 }
    285         }
    286 
    287         //i.e. 3rd frame after flagstep initially set
    288         if (counter==1 && flagstep==1) {
    289                 //check for consistency between previous beatperiod values
    290                 if(ABS(2.*rp - rp1 -rp2) < bt->g_var) {
    291                         //if true, can activate context dependent model
    292                         flagconst = 1;
    293                         counter   = 0; // reset counter and flagstep
    294                 } else {
    295                         //if not consistent, then don't flag consistency!
    296                         flagconst = 0;
    297                         counter   = 2; // let it look next time
    298                 }
    299         } else if (counter > 0) {
    300                 //if counter doesn't = 1,
    301                 counter = counter-1;
    302         }
    303 
    304         rp2 = rp1; rp1 = rp;
    305 
    306         if (flagconst) {
    307                 /* first run of new hypothesis */
    308                 gp = rp;
    309                 bt->timesig = fvec_gettimesig(acf,acflen, gp);
    310                 for(j=0;j<laglen;j++)
    311                         bt->gwv->data[0][j] = EXP(-.5*SQR((smpl_t)(j+1.-gp))/SQR(bt->g_var));
    312                 flagconst = 0;
    313                 bp = gp;
    314                 /* flat phase weighting */
    315                 fvec_ones(bt->phwv);
    316         } else if (bt->timesig) {
    317                 /* context dependant model */
    318                 bp = gp;
    319                 /* gaussian phase weighting */
    320                 if (step > bt->lastbeat) {
    321                         for(j=0;j<2*laglen;j++)  {
    322                                 bt->phwv->data[0][j] = EXP(-.5*SQR((smpl_t)(1.+j-step+bt->lastbeat))/(bp/8.));
    323                         }
    324                 } else {
    325                         //AUBIO_DBG("NOT using phase weighting as step is %d and lastbeat %d \n",
    326                         //                step,bt->lastbeat);
    327                         fvec_ones(bt->phwv);
    328                 }
    329         } else {
    330                 /* initial state */
    331                 bp = rp;
    332                 /* flat phase weighting */
    333                 fvec_ones(bt->phwv);
    334         }
    335 
    336         /* do some further checks on the final bp value */
    337 
    338         /* if tempo is > 206 bpm, half it */
    339         while (bp < 25) {
    340                 //AUBIO_DBG("warning, doubling the beat period from %d\n", bp);
    341                 //AUBIO_DBG("warning, halving the tempo from %f\n", 60.*samplerate/hopsize/bp);
    342                 bp = bp*2;
    343         }
    344        
    345         //AUBIO_DBG("tempo:\t%3.5f bpm | ", 5168./bp);
    346 
    347         /* smoothing */
    348         //bp = (uint_t) (0.8 * (smpl_t)bp + 0.2 * (smpl_t)bp2);
    349         //AUBIO_DBG("tempo:\t%3.5f bpm smoothed | bp2 %d | bp %d | ", 5168./bp, bp2, bp);
    350         //bp2 = bp;
    351         //AUBIO_DBG("time signature: %d \n", bt->timesig);
    352         bt->counter = counter;
    353         bt->flagstep = flagstep;
    354         bt->gp = gp;
    355         bt->bp = bp;
    356         bt->rp1 = rp1;
    357         bt->rp2 = rp2;
    358 
    359 }
    360 
    361 smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt) {
    362         if (bt->timesig != 0 && bt->counter == 0 && bt->flagstep == 0) {
    363           return 5168. / vec_quadint(bt->acfout, bt->bp, 1);
    364         } else {
    365           return 0.;
    366         }
    367 }
    368 
    369 smpl_t aubio_beattracking_get_confidence(aubio_beattracking_t * bt) {
    370         if (bt->gp) return vec_max(bt->acfout);
    371         else return 0.;
    372 }
     275      }
     276    }
     277    fvec_weight (acfout, bt->gwv);
     278    gp = vec_quadint (acfout, vec_max_elem (acfout), 1);
     279    /*
     280       while(gp<32) gp =gp*2;
     281       while(gp>64) gp = gp/2;
     282     */
     283  } else {
     284    //still only using general model
     285    gp = 0;
     286  }
     287
     288  //now look for step change - i.e. a difference between gp and rp that
     289  // is greater than 2*constthresh - always true in first case, since gp = 0
     290  if (counter == 0) {
     291    if (ABS (gp - rp) > 2. * bt->g_var) {
     292      flagstep = 1;             // have observed  step change.
     293      counter = 3;              // setup 3 frame counter
     294    } else {
     295      flagstep = 0;
     296    }
     297  }
     298  //i.e. 3rd frame after flagstep initially set
     299  if (counter == 1 && flagstep == 1) {
     300    //check for consistency between previous beatperiod values
     301    if (ABS (2. * rp - rp1 - rp2) < bt->g_var) {
     302      //if true, can activate context dependent model
     303      flagconst = 1;
     304      counter = 0;              // reset counter and flagstep
     305    } else {
     306      //if not consistent, then don't flag consistency!
     307      flagconst = 0;
     308      counter = 2;              // let it look next time
     309    }
     310  } else if (counter > 0) {
     311    //if counter doesn't = 1,
     312    counter = counter - 1;
     313  }
     314
     315  rp2 = rp1;
     316  rp1 = rp;
     317
     318  if (flagconst) {
     319    /* first run of new hypothesis */
     320    gp = rp;
     321    bt->timesig = fvec_gettimesig (acf, acflen, gp);
     322    for (j = 0; j < laglen; j++)
     323      bt->gwv->data[0][j] =
     324          EXP (-.5 * SQR ((smpl_t) (j + 1. - gp)) / SQR (bt->g_var));
     325    flagconst = 0;
     326    bp = gp;
     327    /* flat phase weighting */
     328    fvec_ones (bt->phwv);
     329  } else if (bt->timesig) {
     330    /* context dependant model */
     331    bp = gp;
     332    /* gaussian phase weighting */
     333    if (step > bt->lastbeat) {
     334      for (j = 0; j < 2 * laglen; j++) {
     335        bt->phwv->data[0][j] =
     336            EXP (-.5 * SQR ((smpl_t) (1. + j - step +
     337                    bt->lastbeat)) / (bp / 8.));
     338      }
     339    } else {
     340      //AUBIO_DBG("NOT using phase weighting as step is %d and lastbeat %d \n",
     341      //                step,bt->lastbeat);
     342      fvec_ones (bt->phwv);
     343    }
     344  } else {
     345    /* initial state */
     346    bp = rp;
     347    /* flat phase weighting */
     348    fvec_ones (bt->phwv);
     349  }
     350
     351  /* do some further checks on the final bp value */
     352
     353  /* if tempo is > 206 bpm, half it */
     354  while (bp < 25) {
     355    //AUBIO_DBG("warning, doubling the beat period from %d\n", bp);
     356    //AUBIO_DBG("warning, halving the tempo from %f\n", 60.*samplerate/hopsize/bp);
     357    bp = bp * 2;
     358  }
     359
     360  //AUBIO_DBG("tempo:\t%3.5f bpm | ", 5168./bp);
     361
     362  /* smoothing */
     363  //bp = (uint_t) (0.8 * (smpl_t)bp + 0.2 * (smpl_t)bp2);
     364  //AUBIO_DBG("tempo:\t%3.5f bpm smoothed | bp2 %d | bp %d | ", 5168./bp, bp2, bp);
     365  //bp2 = bp;
     366  //AUBIO_DBG("time signature: %d \n", bt->timesig);
     367  bt->counter = counter;
     368  bt->flagstep = flagstep;
     369  bt->gp = gp;
     370  bt->bp = bp;
     371  bt->rp1 = rp1;
     372  bt->rp2 = rp2;
     373}
     374
     375smpl_t
     376aubio_beattracking_get_bpm (aubio_beattracking_t * bt)
     377{
     378  if (bt->timesig != 0 && bt->counter == 0 && bt->flagstep == 0) {
     379    return 5168. / vec_quadint (bt->acfout, bt->bp, 1);
     380  } else {
     381    return 0.;
     382  }
     383}
     384
     385smpl_t
     386aubio_beattracking_get_confidence (aubio_beattracking_t * bt)
     387{
     388  if (bt->gp) {
     389    return vec_max (bt->acfout);
     390  } else {
     391    return 0.;
     392  }
     393}
Note: See TracChangeset for help on using the changeset viewer.