Changeset 3502119


Ignore:
Timestamp:
Apr 5, 2017, 11:49:57 AM (3 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/constantq, feature/pitchshift, feature/pydocstrings, feature/timestretch, master, sampler
Children:
c3b1a7d
Parents:
0eca01f (diff), c82859f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'awhitening'

Files:
3 added
17 edited

Legend:

Unmodified
Added
Removed
  • examples/aubioonset.c

    r0eca01f r3502119  
    4444    aubio_wavetable_stop ( wavetable );
    4545  }
    46   if (mix_input)
     46  if (mix_input) {
    4747    aubio_wavetable_do (wavetable, ibuf, obuf);
    48   else
     48  } else {
    4949    aubio_wavetable_do (wavetable, obuf, obuf);
     50  }
    5051}
    5152
     
    6263  examples_common_init(argc,argv);
    6364
    64   verbmsg ("using source: %s at %dHz\n", source_uri, samplerate);
    65   verbmsg ("onset method: %s, ", onset_method);
    66   verbmsg ("buffer_size: %d, ", buffer_size);
    67   verbmsg ("hop_size: %d, ", hop_size);
    68   verbmsg ("silence: %f, ", silence_threshold);
    69   verbmsg ("threshold: %f\n", onset_threshold);
    70 
    7165  o = new_aubio_onset (onset_method, buffer_size, hop_size, samplerate);
    7266  if (o == NULL) { ret = 1; goto beach; }
     
    7771  if (onset_minioi != 0.)
    7872    aubio_onset_set_minioi_s (o, onset_minioi);
     73
     74  verbmsg ("using source: %s at %dHz\n", source_uri, samplerate);
     75  verbmsg ("onset method: %s, ", onset_method);
     76  verbmsg ("buffer_size: %d, ", buffer_size);
     77  verbmsg ("hop_size: %d, ", hop_size);
     78  verbmsg ("silence: %f, ", aubio_onset_get_silence(o));
     79  verbmsg ("threshold: %f, ", aubio_onset_get_threshold(o));
     80  verbmsg ("awhitening: %f, ", aubio_onset_get_awhitening(o));
     81  verbmsg ("compression: %f\n", aubio_onset_get_compression(o));
    7982
    8083  onset = new_fvec (1);
  • examples/aubiotrack.c

    r0eca01f r3502119  
    4747    aubio_wavetable_stop ( wavetable );
    4848  }
    49   if (mix_input)
     49  if (mix_input) {
    5050    aubio_wavetable_do (wavetable, ibuf, obuf);
    51   else
     51  } else {
    5252    aubio_wavetable_do (wavetable, obuf, obuf);
     53  }
    5354}
    5455
  • python/lib/gen_code.py

    r0eca01f r3502119  
    184184    def gen_code(self):
    185185        out = ""
    186         out += self.gen_struct()
    187         out += self.gen_doc()
    188         out += self.gen_new()
    189         out += self.gen_init()
    190         out += self.gen_del()
    191         out += self.gen_do()
    192         out += self.gen_memberdef()
    193         out += self.gen_set()
    194         out += self.gen_get()
    195         out += self.gen_methodef()
    196         out += self.gen_typeobject()
     186        try:
     187            out += self.gen_struct()
     188            out += self.gen_doc()
     189            out += self.gen_new()
     190            out += self.gen_init()
     191            out += self.gen_del()
     192            out += self.gen_do()
     193            out += self.gen_memberdef()
     194            out += self.gen_set()
     195            out += self.gen_get()
     196            out += self.gen_methodef()
     197            out += self.gen_typeobject()
     198        except Exception as e:
     199            print ("Failed generating code for", self.shortname)
     200            raise
    197201        return out
    198202
  • python/lib/gen_external.py

    r0eca01f r3502119  
    4040  #'sampler',
    4141  'audio_unit',
     42  'spectral_whitening',
    4243  ]
    4344
  • python/tests/test_onset.py

    r0eca01f r3502119  
    2020
    2121    def test_get_delay(self):
    22         assert_equal (self.o.get_delay(), int(4.3 * self.o.hop_size))
     22        self.assertGreater(self.o.get_delay(), 0)
    2323
    2424    def test_get_delay_s(self):
    25         assert_almost_equal (self.o.get_delay_s(), self.o.get_delay() / float(self.samplerate))
     25        self.assertGreater(self.o.get_delay_s(), 0.)
    2626
    2727    def test_get_delay_ms(self):
    28         assert_almost_equal (self.o.get_delay_ms(), self.o.get_delay() * 1000. / self.samplerate, 5)
     28        self.assertGreater(self.o.get_delay_ms(), 0.)
    2929
    3030    def test_get_minioi(self):
    31         assert_almost_equal (self.o.get_minioi(), 0.02 * self.samplerate)
     31        self.assertGreater(self.o.get_minioi(), 0)
    3232
    3333    def test_get_minioi_s(self):
    34         assert_almost_equal (self.o.get_minioi_s(), 0.02)
     34        self.assertGreater(self.o.get_minioi_s(), 0.)
    3535
    3636    def test_get_minioi_ms(self):
    37         assert_equal (self.o.get_minioi_ms(), 20.)
     37        self.assertGreater(self.o.get_minioi_ms(), 0.)
    3838
    3939    def test_get_threshold(self):
    40         assert_almost_equal (self.o.get_threshold(), 0.3)
     40        self.assertGreater(self.o.get_threshold(), 0.)
    4141
    4242    def test_set_delay(self):
  • src/aubio.h

    r0eca01f r3502119  
    188188#include "spectral/mfcc.h"
    189189#include "spectral/specdesc.h"
     190#include "spectral/awhitening.h"
    190191#include "spectral/tss.h"
    191192#include "pitch/pitch.h"
  • src/cvec.c

    r0eca01f r3502119  
    140140  cvec_phas_zeros(s);
    141141}
     142
     143void cvec_logmag(cvec_t *s, smpl_t lambda) {
     144  uint_t j;
     145  for (j=0; j< s->length; j++) {
     146    s->norm[j] = LOG(lambda * s->norm[j] + 1);
     147  }
     148}
  • src/cvec.h

    r0eca01f r3502119  
    231231void cvec_zeros(cvec_t *s);
    232232
     233/** take logarithmic magnitude
     234
     235  \param s input cvec to compress
     236  \param lambda value to use for normalisation
     237
     238  \f$ S_k = log( \lambda * S_k + 1 ) \f$
     239
     240*/
     241void cvec_logmag(cvec_t *s, smpl_t lambda);
     242
    233243#ifdef __cplusplus
    234244}
  • src/mathutils.c

    r0eca01f r3502119  
    290290}
    291291
     292void fvec_push(fvec_t *in, smpl_t new_elem) {
     293  uint_t i;
     294  for (i = 0; i < in->length - 1; i++) {
     295    in->data[i] = in->data[i + 1];
     296  }
     297  in->data[in->length - 1] = new_elem;
     298}
     299
     300void fvec_clamp(fvec_t *in, smpl_t absmax) {
     301  uint_t i;
     302  for (i = 0; i < in->length; i++) {
     303    if (in->data[i] > 0 && in->data[i] > ABS(absmax)) {
     304      in->data[i] = absmax;
     305    } else if (in->data[i] < 0 && in->data[i] < -ABS(absmax)) {
     306      in->data[i] = -absmax;
     307    }
     308  }
     309}
     310
    292311smpl_t
    293312aubio_level_lin (const fvec_t * f)
  • src/mathutils.h

    r0eca01f r3502119  
    117117*/
    118118void fvec_ishift (fvec_t * v);
     119
     120/** push a new element to the end of a vector, erasing the first element and
     121 * sliding all others
     122
     123  \param in vector to push to
     124  \param new_elem new_element to add at the end of the vector
     125
     126  In numpy words, this is equivalent to: in = np.concatenate([in, [new_elem]])[1:]
     127
     128*/
     129void fvec_push(fvec_t *in, smpl_t new_elem);
    119130
    120131/** compute the sum of all elements of a vector
  • src/musicutils.h

    r0eca01f r3502119  
    157157smpl_t aubio_level_detection (const fvec_t * v, smpl_t threshold);
    158158
     159/** clamp the values of a vector within the range [-abs(max), abs(max)]
     160
     161  \param in vector to clamp
     162  \param absmax maximum value over which input vector elements should be clamped
     163
     164*/
     165void fvec_clamp(fvec_t *in, smpl_t absmax);
     166
    159167#ifdef __cplusplus
    160168}
  • src/onset/onset.c

    r0eca01f r3502119  
    2424#include "spectral/specdesc.h"
    2525#include "spectral/phasevoc.h"
     26#include "spectral/awhitening.h"
    2627#include "onset/peakpicker.h"
    2728#include "mathutils.h"
    2829#include "onset/onset.h"
     30
     31void aubio_onset_default_parameters (aubio_onset_t *o, const char_t * method);
    2932
    3033/** structure to store object state */
     
    4346  uint_t total_frames;          /**< total number of frames processed since the beginning */
    4447  uint_t last_onset;            /**< last detected onset location, in frames */
     48
     49  uint_t apply_compression;
     50  smpl_t lambda_compression;
     51  uint_t apply_awhitening;      /**< apply adaptive spectral whitening */
     52  aubio_spectral_whitening_t *spectral_whitening;
    4553};
    4654
     
    5058  smpl_t isonset = 0;
    5159  aubio_pvoc_do (o->pv,input, o->fftgrain);
     60  /*
     61  if (apply_filtering) {
     62  }
     63  */
     64  if (o->apply_awhitening) {
     65    aubio_spectral_whitening_do(o->spectral_whitening, o->fftgrain);
     66  }
     67  if (o->apply_compression) {
     68    cvec_logmag(o->fftgrain, o->lambda_compression);
     69  }
    5270  aubio_specdesc_do (o->od, o->fftgrain, o->desc);
    5371  aubio_peakpicker_do(o->pp, o->desc, onset);
     
    5876      isonset  = 0;
    5977    } else {
     78      // we have an onset
    6079      uint_t new_onset = o->total_frames + (uint_t)ROUND(isonset * o->hop_size);
     80      // check if last onset time was more than minioi ago
    6181      if (o->last_onset + o->minioi < new_onset) {
    62         //AUBIO_DBG ("accepted detection, marking as onset\n");
    63         o->last_onset = new_onset;
     82        // start of file: make sure (new_onset - delay) >= 0
     83        if (o->last_onset > 0 && o->delay > new_onset) {
     84          isonset = 0;
     85        } else {
     86          //AUBIO_DBG ("accepted detection, marking as onset\n");
     87          o->last_onset = MAX(o->delay, new_onset);
     88        }
    6489      } else {
    6590        //AUBIO_DBG ("doubled onset, not marking as onset\n");
     
    100125}
    101126
     127uint_t aubio_onset_set_awhitening (aubio_onset_t *o, uint_t enable)
     128{
     129  o->apply_awhitening = enable == 1 ? 1 : 0;
     130  return AUBIO_OK;
     131}
     132
     133smpl_t aubio_onset_get_awhitening (aubio_onset_t *o)
     134{
     135  return o->apply_awhitening;
     136}
     137
     138uint_t aubio_onset_set_compression (aubio_onset_t *o, smpl_t lambda)
     139{
     140  if (lambda < 0.) {
     141    return AUBIO_FAIL;
     142  }
     143  o->lambda_compression = lambda;
     144  o->apply_compression = (o->lambda_compression > 0.) ? 1 : 0;
     145  return AUBIO_OK;
     146}
     147
     148smpl_t aubio_onset_get_compression (aubio_onset_t *o)
     149{
     150  return o->apply_compression ? o->lambda_compression : 0;
     151}
     152
    102153uint_t aubio_onset_set_silence(aubio_onset_t * o, smpl_t silence) {
    103154  o->silence = silence;
     
    209260  o->fftgrain = new_cvec(buf_size);
    210261  o->desc = new_fvec(1);
    211 
    212   /* set some default parameter */
    213   aubio_onset_set_threshold (o, 0.3);
    214   aubio_onset_set_delay(o, 4.3 * hop_size);
    215   aubio_onset_set_minioi_ms(o, 20.);
    216   aubio_onset_set_silence(o, -70.);
     262  o->spectral_whitening = new_aubio_spectral_whitening(buf_size, hop_size, samplerate);
    217263
    218264  /* initialize internal variables */
    219   o->last_onset = 0;
    220   o->total_frames = 0;
     265  aubio_onset_set_default_parameters (o, onset_mode);
     266
     267  aubio_onset_reset(o);
    221268  return o;
    222269
     
    229276}
    230277
     278void aubio_onset_reset (aubio_onset_t *o) {
     279  o->last_onset = 0;
     280  o->total_frames = 0;
     281}
     282
     283uint_t aubio_onset_set_default_parameters (aubio_onset_t * o, const char_t * onset_mode)
     284{
     285  uint_t ret = AUBIO_OK;
     286  /* set some default parameter */
     287  aubio_onset_set_threshold (o, 0.3);
     288  aubio_onset_set_delay (o, 4.3 * o->hop_size);
     289  aubio_onset_set_minioi_ms (o, 50.);
     290  aubio_onset_set_silence (o, -70.);
     291  // disable spectral whitening
     292  aubio_onset_set_awhitening (o, 0);
     293  // disable logarithmic magnitude
     294  aubio_onset_set_compression (o, 0.);
     295
     296  /* method specific optimisations */
     297  if (strcmp (onset_mode, "energy") == 0) {
     298  } else if (strcmp (onset_mode, "hfc") == 0 || strcmp (onset_mode, "default") == 0) {
     299    aubio_onset_set_threshold (o, 0.058);
     300    aubio_onset_set_compression (o, 1.);
     301  } else if (strcmp (onset_mode, "complexdomain") == 0
     302             || strcmp (onset_mode, "complex") == 0) {
     303    aubio_onset_set_delay (o, 4.6 * o->hop_size);
     304    aubio_onset_set_threshold (o, 0.15);
     305    aubio_onset_set_awhitening(o, 1);
     306    aubio_onset_set_compression (o, 1.);
     307  } else if (strcmp (onset_mode, "phase") == 0) {
     308    o->apply_compression = 0;
     309    aubio_onset_set_awhitening (o, 0);
     310  } else if (strcmp (onset_mode, "mkl") == 0) {
     311    aubio_onset_set_threshold (o, 0.05);
     312    aubio_onset_set_awhitening(o, 1);
     313    aubio_onset_set_compression (o, 0.02);
     314  } else if (strcmp (onset_mode, "kl") == 0) {
     315    aubio_onset_set_threshold (o, 0.35);
     316    aubio_onset_set_awhitening(o, 1);
     317    aubio_onset_set_compression (o, 0.02);
     318  } else if (strcmp (onset_mode, "specflux") == 0) {
     319    aubio_onset_set_threshold (o, 0.18);
     320    aubio_onset_set_awhitening(o, 1);
     321    aubio_spectral_whitening_set_relax_time(o->spectral_whitening, 100);
     322    aubio_spectral_whitening_set_floor(o->spectral_whitening, 1.);
     323    aubio_onset_set_compression (o, 10.);
     324  } else if (strcmp (onset_mode, "specdiff") == 0) {
     325  } else if (strcmp (onset_mode, "old_default") == 0) {
     326    // used to reproduce results obtained with the previous version
     327    aubio_onset_set_threshold (o, 0.3);
     328    aubio_onset_set_minioi_ms (o, 20.);
     329    aubio_onset_set_compression (o, 0.);
     330  } else {
     331    AUBIO_WRN("onset: unknown spectral descriptor type %s, "
     332               "using default parameters.\n", onset_mode);
     333    ret = AUBIO_FAIL;
     334  }
     335  return ret;
     336}
     337
    231338void del_aubio_onset (aubio_onset_t *o)
    232339{
     340  del_aubio_spectral_whitening(o->spectral_whitening);
    233341  del_aubio_specdesc(o->od);
    234342  del_aubio_peakpicker(o->pp);
  • src/onset/onset.h

    r0eca01f r3502119  
    118118smpl_t aubio_onset_get_last_ms (const aubio_onset_t *o);
    119119
     120/** set onset detection adaptive whitening
     121
     122  \param o onset detection object as returned by new_aubio_onset()
     123  \param enable 1 to enable, 0 to disable
     124
     125  \return 0 if successful, 1 otherwise
     126
     127*/
     128uint_t aubio_onset_set_awhitening(aubio_onset_t * o, uint_t enable);
     129
     130/** get onset detection adaptive whitening
     131
     132  \param o onset detection object as returned by new_aubio_onset()
     133
     134  \return 1 if enabled, 0 otherwise
     135
     136*/
     137smpl_t aubio_onset_get_awhitening(aubio_onset_t * o);
     138
     139/** set or disable log compression
     140
     141  \param o onset detection object as returned by new_aubio_onset()
     142  \param lambda logarithmic compression factor, 0 to disable
     143
     144  \return 0 if successful, 1 otherwise
     145
     146 */
     147uint_t aubio_onset_set_compression(aubio_onset_t *o, smpl_t lambda);
     148
     149/** get onset detection log compression
     150
     151  \param o onset detection object as returned by new_aubio_onset()
     152
     153  \returns 0 if disabled, compression factor otherwise
     154
     155 */
     156smpl_t aubio_onset_get_compression(aubio_onset_t *o);
     157
    120158/** set onset detection silence threshold
    121159
     
    274312*/
    275313smpl_t aubio_onset_get_threshold(const aubio_onset_t * o);
     314
     315/** set default parameters
     316
     317  \param o onset detection object as returned by new_aubio_onset()
     318  \param onset_mode detection mode to adjust
     319
     320  This function is called at the end of new_aubio_onset().
     321
     322 */
     323uint_t aubio_onset_set_default_parameters (aubio_onset_t * o, const char_t * onset_mode);
     324
     325/** reset onset detection
     326
     327  \param o onset detection object as returned by new_aubio_onset()
     328
     329  Reset current time and last onset to 0.
     330
     331  This function is called at the end of new_aubio_onset().
     332
     333 */
     334void aubio_onset_reset(aubio_onset_t * o);
    276335
    277336/** delete onset detection object
  • src/onset/peakpicker.c

    r0eca01f r3502119  
    9393  fvec_t *scratch = p->scratch;
    9494  smpl_t mean = 0., median = 0.;
    95   uint_t length = p->win_post + p->win_pre + 1;
    9695  uint_t j = 0;
    9796
    98   /* store onset in onset_keep */
    99   /* shift all elements but last, then write last */
    100   for (j = 0; j < length - 1; j++) {
    101     onset_keep->data[j] = onset_keep->data[j + 1];
    102     onset_proc->data[j] = onset_keep->data[j];
    103   }
    104   onset_keep->data[length - 1] = onset->data[0];
    105   onset_proc->data[length - 1] = onset->data[0];
     97  /* push new novelty to the end */
     98  fvec_push(onset_keep, onset->data[0]);
     99  /* store a copy */
     100  fvec_copy(onset_keep, onset_proc);
    106101
    107   /* filter onset_proc */
    108   /** \bug filtfilt calculated post+pre times, should be only once !? */
     102  /* filter this copy */
    109103  aubio_filter_do_filtfilt (p->biquad, onset_proc, scratch);
    110104
    111105  /* calculate mean and median for onset_proc */
    112106  mean = fvec_mean (onset_proc);
    113   /* copy to scratch */
    114   for (j = 0; j < length; j++)
    115     scratch->data[j] = onset_proc->data[j];
     107
     108  /* copy to scratch and compute its median */
     109  fvec_copy(onset_proc, scratch);
    116110  median = p->thresholdfn (scratch);
    117111
  • src/spectral/specdesc.c

    r0eca01f r3502119  
    3131void aubio_specdesc_complex(aubio_specdesc_t *o, const cvec_t * fftgrain, fvec_t * onset);
    3232void aubio_specdesc_phase(aubio_specdesc_t *o, const cvec_t * fftgrain, fvec_t * onset);
     33void aubio_specdesc_wphase(aubio_specdesc_t *o, const cvec_t * fftgrain, fvec_t * onset);
    3334void aubio_specdesc_specdiff(aubio_specdesc_t *o, const cvec_t * fftgrain, fvec_t * onset);
    3435void aubio_specdesc_kl(aubio_specdesc_t *o, const cvec_t * fftgrain, fvec_t * onset);
     
    5859        aubio_onset_complex,        /**< complex domain */       
    5960        aubio_onset_phase,          /**< phase fast */           
     61        aubio_onset_wphase,         /**< weighted phase */
    6062        aubio_onset_kl,             /**< Kullback Liebler */
    6163        aubio_onset_mkl,            /**< modified Kullback Liebler */
     
    158160  onset->data[0] = aubio_hist_mean(o->histog); 
    159161  //onset->data[0] = fvec_mean(o->dev1);
     162}
     163
     164/* weighted phase */
     165void
     166aubio_specdesc_wphase(aubio_specdesc_t *o,
     167    const cvec_t *fftgrain, fvec_t *onset) {
     168  uint_t i;
     169  aubio_specdesc_phase(o, fftgrain, onset);
     170  for (i = 0; i < fftgrain->length; i++) {
     171    o->dev1->data[i] *= fftgrain->norm[i];
     172  }
     173  /* apply o->histogram */
     174  aubio_hist_dyn_notnull(o->histog,o->dev1);
     175  /* weight it */
     176  aubio_hist_weight(o->histog);
     177  /* its mean is the result */
     178  onset->data[0] = aubio_hist_mean(o->histog);
    160179}
    161180
     
    251270  else if (strcmp (onset_mode, "phase") == 0)
    252271      onset_type = aubio_onset_phase;
     272  else if (strcmp (onset_mode, "wphase") == 0)
     273      onset_type = aubio_onset_wphase;
    253274  else if (strcmp (onset_mode, "mkl") == 0)
    254275      onset_type = aubio_onset_mkl;
     
    271292  else if (strcmp (onset_mode, "rolloff") == 0)
    272293      onset_type = aubio_specmethod_rolloff;
     294  else if (strcmp (onset_mode, "old_default") == 0)
     295      onset_type = aubio_onset_default;
    273296  else if (strcmp (onset_mode, "default") == 0)
    274297      onset_type = aubio_onset_default;
     
    292315      break;
    293316    case aubio_onset_phase:
     317    case aubio_onset_wphase:
    294318      o->dev1   = new_fvec(rsize);
    295319      o->theta1 = new_fvec(rsize);
     
    326350      o->funcpointer = aubio_specdesc_phase;
    327351      break;
     352    case aubio_onset_wphase:
     353      o->funcpointer = aubio_specdesc_wphase;
     354      break;
    328355    case aubio_onset_specdiff:
    329356      o->funcpointer = aubio_specdesc_specdiff;
     
    379406      break;
    380407    case aubio_onset_phase:
     408    case aubio_onset_wphase:
    381409      del_fvec(o->dev1);
    382410      del_fvec(o->theta1);
  • src/spectral/specdesc.h

    r0eca01f r3502119  
    6060  Hong-Kong, 2003.
    6161
     62  \b \p wphase : Weighted Phase Deviation onset detection function
     63
     64  S. Dixon. Onset detection revisited. In Proceedings of the 9th International
     65  Conference on Digital Audio Ef- fects (DAFx) , pages 133–137, 2006.
     66
     67  http://www.eecs.qmul.ac.uk/~simond/pub/2006/dafx.pdf
     68
    6269  \b \p specdiff : Spectral difference method onset detection function
    6370
     
    175182  The parameter \p method is a string that can be any of:
    176183
    177     - `energy`, `hfc`, `complex`, `phase`, `specdiff`, `kl`, `mkl`, `specflux`
    178     - `centroid`, `spread`, `skewness`, `kurtosis`, `slope`, `decrease`, `rolloff`
     184    - onset novelty functions: `complex`, `energy`, `hfc`, `kl`, `mkl`,
     185    `phase`, `specdiff`, `specflux`, `wphase`,
     186
     187    - spectral descriptors: `centroid`, `decrease`, `kurtosis`, `rolloff`,
     188    `skewness`, `slope`, `spread`.
    179189
    180190*/
  • src/synth/wavetable.c

    r0eca01f r3502119  
    104104      output->data[i] += input->data[i];
    105105    }
     106    fvec_clamp(output, 1.);
    106107  }
    107108}
Note: See TracChangeset for help on using the changeset viewer.