src/notes/notes.c: emit note-off earlier (see #203)
authorPaul Brossier <piem@piem.org>
Tue, 2 Oct 2018 12:56:52 +0000 (14:56 +0200)
committerPaul Brossier <piem@piem.org>
Tue, 2 Oct 2018 12:56:52 +0000 (14:56 +0200)
 - emit note-off when the level drops by a given threshold after onset
 - default drop threshold is set to 10dB

src/notes/notes.c

index 343e5a0..f475090 100644 (file)
@@ -25,6 +25,7 @@
 #include "notes/notes.h"
 
 #define AUBIO_DEFAULT_NOTES_SILENCE -70.
+#define AUBIO_DEFAULT_NOTES_LEVEL_DROP 10.
 // increase to 10. for .1  cent precision
 //      or to 100. for .01 cent precision
 #define AUBIO_DEFAULT_CENT_PRECISION 1.
@@ -56,6 +57,9 @@ struct _aubio_notes_t {
   smpl_t silence_threshold;
 
   uint_t isready;
+
+  smpl_t last_onset_level;
+  smpl_t level_delta_db;
 };
 
 aubio_notes_t * new_aubio_notes (const char_t * method,
@@ -101,6 +105,9 @@ aubio_notes_t * new_aubio_notes (const char_t * method,
   aubio_notes_set_silence(o, AUBIO_DEFAULT_NOTES_SILENCE);
   aubio_notes_set_minioi_ms (o, AUBIO_DEFAULT_NOTES_MINIOI_MS);
 
+  o->last_onset_level = AUBIO_DEFAULT_NOTES_SILENCE;
+  o->level_delta_db = AUBIO_DEFAULT_NOTES_LEVEL_DROP;
+
   return o;
 
 fail:
@@ -184,6 +191,7 @@ void aubio_notes_do (aubio_notes_t *o, const fvec_t * input, fvec_t * notes)
       //send_noteon(o->curnote,0);
       //notes->data[0] = o->curnote;
       //notes->data[1] = 0.;
+      //AUBIO_WRN("notes: sending note-off at onset, not enough level\n");
       notes->data[2] = o->curnote;
     } else {
       if (o->median) {
@@ -191,6 +199,7 @@ void aubio_notes_do (aubio_notes_t *o, const fvec_t * input, fvec_t * notes)
       } else {
         /* kill old note */
         //send_noteon(o->curnote,0, o->samplerate);
+        //AUBIO_WRN("notes: sending note-off at onset, new onset detected\n");
         notes->data[2] = o->curnote;
         /* get and send new one */
         //send_noteon(new_pitch,127+(int)floor(curlevel), o->samplerate);
@@ -198,16 +207,33 @@ void aubio_notes_do (aubio_notes_t *o, const fvec_t * input, fvec_t * notes)
         notes->data[1] = 127 + (int)floor(curlevel);
         o->curnote = new_pitch;
       }
+      o->last_onset_level = curlevel;
     }
   } else {
-    if (o->median) {
+    if (curlevel < o->last_onset_level - o->level_delta_db)
+    {
+      // send note off
+      //AUBIO_WRN("notes: sending note-off, release detected\n");
+      notes->data[0] = 0;
+      notes->data[1] = 0;
+      notes->data[2] = o->curnote;
+      // reset last_onset_level to silence_threshold
+      o->last_onset_level = o->silence_threshold;
+      o->curnote = 0;
+    }
+    else if (o->median)
+    {
       if (o->isready > 0)
         o->isready++;
       if (o->isready == o->median)
       {
         /* kill old note */
         //send_noteon(curnote,0);
-        notes->data[2] = o->curnote;
+        if (o->curnote != 0)
+        {
+          //AUBIO_WRN("notes: sending note-off, new note detected\n");
+          notes->data[2] = o->curnote;
+        }
         o->newnote = aubio_notes_get_latest_note(o);
         o->curnote = o->newnote;
         /* get and send new one */