Переглянути джерело

If no amp_hz is yielded by the Instrument for a voice, set the associated PlayingSample to None.

mitchmindtree 8 роки тому
батько
коміт
b47f945735
1 змінених файлів з 24 додано та 19 видалено
  1. 24 19
      src/sampler.rs

+ 24 - 19
src/sampler.rs

@@ -44,6 +44,8 @@ pub struct PlayingSample<A>
     base_vel: Velocity,
     /// Rate-adjustable interpolation of audio.
     pub rate_converter: sample::rate::Converter<Playhead<A>>,
+    /// The time at which the `PlayingSample` was constructed.
+    pub time_of_note_on: std::time::Instant,
 }
 
 /// An owned iterator that wraps an audio file but does not 
@@ -197,8 +199,8 @@ impl<M, NFG, A> Sampler<M, NFG, A>
     {
         let Sampler { ref mut instrument, ref mut voices, ref map, .. } = *self;
         let hz = note_hz.into();
-        instrument.note_off(hz);
         super::Mode::note_off(&mut instrument.mode, hz, map, &mut voices.map);
+        instrument.note_off(hz);
     }
 
     /// Stop playback and clear the current notes.
@@ -300,6 +302,7 @@ impl<A> PlayingSample<A>
             base_hz: base_hz,
             base_vel: base_vel,
             rate_converter: rate_converter,
+            time_of_note_on: std::time::Instant::now(),
         }
     }
 
@@ -351,26 +354,28 @@ impl<'a, A, NF> Frames<'a, A, NF>
         } = *self;
 
         let frame_per_voice = instrument_frames.next_frame_per_voice();
+        let equilibrium = <A::Frame as Frame>::equilibrium();
         voices.map.iter_mut()
             .zip(frame_per_voice)
-            .filter_map(|(v, amp_hz)| amp_hz.map(|amp_hz| (v, amp_hz)))
-            .fold(<A::Frame as Frame>::equilibrium(), |frame, (voice, (amp, hz))| {
-                match *voice {
-                    None => return frame,
-                    Some(ref mut voice) => {
-                        let playback_hz_scale = hz / voice.base_hz.hz();
-                        voice.rate_converter.set_playback_hz_scale(playback_hz_scale as f64);
-                        match voice.rate_converter.next_frame() {
-                            Some(wave) => {
-                                let amp = amp * voice.base_vel;
-                                let scaled = wave.scale_amp(amp.to_sample());
-                                return frame.zip_map(scaled, |f, s| {
-                                    f.add_amp(s.to_sample::<<<A::Frame as Frame>::Sample as PcmSample>::Signed>())
-                                });
-                            },
-                            None => (),
-                        }
-                    },
+            .fold(equilibrium, |frame, (voice, amp_hz)| {
+                if let Some((amp, hz)) = amp_hz {
+                    match *voice {
+                        None => return frame,
+                        Some(ref mut voice) => {
+                            let playback_hz_scale = hz / voice.base_hz.hz();
+                            voice.rate_converter.set_playback_hz_scale(playback_hz_scale as f64);
+                            match voice.rate_converter.next_frame() {
+                                Some(wave) => {
+                                    let amp = amp * voice.base_vel;
+                                    let scaled = wave.scale_amp(amp.to_sample());
+                                    return frame.zip_map(scaled, |f, s| {
+                                        f.add_amp(s.to_sample::<<<A::Frame as Frame>::Sample as PcmSample>::Signed>())
+                                    });
+                                },
+                                None => return frame,
+                            }
+                        },
+                    }
                 }
 
                 // If we made it this far, the voice has finished playback of the note.