implement key release handler
authorrekado <rekado@elephly.net>
Mon, 14 Jan 2013 14:17:21 +0000 (22:17 +0800)
committerrekado <rekado@elephly.net>
Mon, 14 Jan 2013 14:17:21 +0000 (22:17 +0800)
src/mdaPianoVoice.cpp
src/mdaPianoVoice.h

index 1417056..b229062 100644 (file)
@@ -116,17 +116,31 @@ void mdaPianoVoice::on(unsigned char note, unsigned char velocity)
     // TODO: move the loop to mdaPiano.cpp
     for(v=0; v<NVOICES; v++) if(voice[v].note==note) //any voices playing that note?
     {
-      if(sustain==0)
-      {
-        if(note < 94 || note == SUSTAIN) //no release on highest notes
-          voice[v].dec = (float)exp(-iFs * exp(2.0 + 0.017 * (double)note - 2.0 * param[1]));
-      }
-      else voice[v].note = SUSTAIN;
+      release(0);
     }
   }
 }
 
 
+void mdaPianoVoice::release(unsigned char velocity)
+{
+  if(sustain==0) {
+    //no release on highest notes
+    if(note < 94 || note == SUSTAIN) {
+      dec = (float)exp(-iFs * exp(2.0 + 0.017 * (double)note - 2.0 * *p(p_envelope_release)));
+    }
+  } else {
+    note = SUSTAIN;
+  }
+
+  //Mark the voice to be turned off later. It may not be set to
+  //INVALID_KEY yet, because the release sound still needs to be
+  //rendered.  m_key is finally set to INVALID_KEY by 'render' when
+  //env < SILENCE
+  m_key = SUSTAIN;
+}
+
+
 void mdaPianoVoice::process(float **inputs, float **outputs, uint32_t sampleFrames)
 {
   float* out0 = outputs[0];
index 1cd393f..22f8218 100644 (file)
@@ -56,6 +56,7 @@ class mdaPianoVoice : public LV2::Voice {
     float p_helper(unsigned short, Param);
     void update(Param); // recalculates internal variables
     void on(unsigned char key, unsigned char velocity);
+    void release(unsigned char velocity);
     void reset(void);
     bool is_sustained(void) { return (note == SUSTAIN); }
     unsigned char get_key(void) const { return m_key; }