Fix derivative which wasn't working correctly; add silence threshold
1 files changed, 42 insertions(+), 19 deletions(-)

M blockstream-fn.sml
M blockstream-fn.sml +42 -19
@@ 920,13 920,16 @@ end
 
 
 (** Apply a normalisation method and/or derivative to a real block
-    stream.
+    stream. If silenceThreshold is provided, any block whose sum
+    magnitude is below that threshold will be rounded down to all
+    zeros before normalisation and derivative are applied.
  *)
 functor NormalisingBlockStreamFn (S : REAL_BLOCK_STREAM) :
         sig
             include REAL_BLOCK_STREAM
             val wrap : { normalisation : Normalise.normalisation,
-                         derivative : SampleStreamTypes.derivative
+                         derivative : SampleStreamTypes.derivative,
+                         silenceThreshold : real option
                        } * S.stream -> stream
         end
 = struct

          
@@ 936,13 939,15 @@ functor NormalisingBlockStreamFn (S : RE
     type stream = {
         normalisation : Normalise.normalisation,
         derivative : SampleStreamTypes.derivative,
+        silenceThreshold : real option,
         blockRate : SignalTypes.rate,
         previous : S.SampleMatrix.matrix option,
         upstream : S.stream
     }
 
     type new_args = { normalisation : Normalise.normalisation,
-                      derivative : SampleStreamTypes.derivative
+                      derivative : SampleStreamTypes.derivative,
+                      silenceThreshold : real option
                     } * S.new_args
 
     fun rate ({ upstream, ... } : stream) = S.rate upstream

          
@@ 951,32 956,45 @@ functor NormalisingBlockStreamFn (S : RE
     fun time ({ upstream, ... } : stream) = S.time upstream
     fun seekable ({ upstream, ... } : stream) = S.seekable upstream
 
-    fun condition { normalisation, derivative, previous }
+    fun condition { normalisation, derivative, silenceThreshold }
                   (v : RealVector.vector, prev : RealVector.vector option)
         : RealVector.vector =
-        let val v' = 
-                case (derivative, prev) of
-                    (SampleStreamTypes.NO_DERIVATIVE, _) => v
-                  | (_, NONE) => v
-                  | (SampleStreamTypes.RECTIFIED_DERIVATIVE, SOME pv) =>
-                    VecMisc.clamp (BqVec.subtract (v, pv), 0.0, Real.posInf)
-                  | (SampleStreamTypes.DERIVATIVE, SOME pv) =>
-                    BqVec.subtract (v, pv)
-        in
-            Normalise.normalise normalisation v
-        end
+        case silenceThreshold of
+            SOME threshold =>
+            if BqVec.sum (BqVec.abs v) < threshold
+            then BqVec.zeros (RealVector.length v)
+            else condition { normalisation = normalisation,
+                             derivative = derivative,
+                             silenceThreshold = NONE
+                           }
+                           (v, prev)
+          | NONE =>
+            let val scaleFactor = Normalise.scaleFactor normalisation v
+                val v' = 
+                    case (derivative, prev) of
+                        (SampleStreamTypes.NO_DERIVATIVE, _) => v
+                      | (_, NONE) => v
+                      | (SampleStreamTypes.RECTIFIED_DERIVATIVE, SOME pv) =>
+                        VecMisc.clamp (BqVec.subtract (v, pv), 0.0, Real.posInf)
+                      | (SampleStreamTypes.DERIVATIVE, SOME pv) =>
+                        BqVec.subtract (v, pv)
+            in
+                BqVec.scale (v', scaleFactor)
+            end
                                                            
-    fun read ({ normalisation, derivative, blockRate, previous, upstream }
+    fun read ({ normalisation, derivative, silenceThreshold,
+                blockRate, previous, upstream }
               : stream) =
         let val conditioner = condition { normalisation = normalisation,
                                           derivative = derivative,
-                                          previous = previous
+                                          silenceThreshold = silenceThreshold
                                         }
         in
             Option.map
                 (fn (upstream', m) =>
                     ({ normalisation = normalisation,
                        derivative = derivative,
+                       silenceThreshold = silenceThreshold,
                        blockRate = blockRate,
                        previous = SOME m,
                        upstream = upstream'

          
@@ 1000,7 1018,8 @@ functor NormalisingBlockStreamFn (S : RE
    
     structure RateHelper = BlockStreamRateHelperFn (S)
 
-    fun seek ({ normalisation, derivative, blockRate, previous, upstream }
+    fun seek ({ normalisation, derivative, silenceThreshold,
+                blockRate, previous, upstream }
               : stream,
               mode, t) =
         let val prior = RealTime.- (t, RealTime.fromFrame

          
@@ 1010,6 1029,7 @@ functor NormalisingBlockStreamFn (S : RE
                 SOME s' =>
                 (case read { normalisation = normalisation,
                              derivative = derivative,
+                             silenceThreshold = silenceThreshold,
                              blockRate = blockRate,
                              previous = NONE,
                              upstream = s'

          
@@ 1020,6 1040,7 @@ functor NormalisingBlockStreamFn (S : RE
                 (case S.seek (upstream, mode, t) of
                      SOME s' => SOME { normalisation = normalisation,
                                        derivative = derivative,
+                                       silenceThreshold = silenceThreshold,
                                        blockRate = blockRate,
                                        previous = NONE,
                                        upstream = s'

          
@@ 1028,11 1049,13 @@ functor NormalisingBlockStreamFn (S : RE
         end
                 
     fun wrap ({ normalisation,
-                derivative
+                derivative,
+                silenceThreshold
               },
               upstream) : stream = {
         normalisation = normalisation,
         derivative = derivative,
+        silenceThreshold = silenceThreshold,
         blockRate = RateHelper.deduceBlockRate upstream,
         previous = NONE,
         upstream = upstream