Introdotto waveletStack con dei metodi un pochino più sensati.

Leonardo Robol [2010-03-13 08:38]
Introdotto waveletStack con dei metodi un pochino più sensati.
Filename
Filtering/Filtering.py
Filtering/dwt
diff --git a/Filtering/Filtering.py b/Filtering/Filtering.py
index 76e57f8..09f94f3 100644
--- a/Filtering/Filtering.py
+++ b/Filtering/Filtering.py
@@ -53,7 +53,7 @@ def UpSample(samples):
     s[::2] = samples
     return array(s)

-class WaveletTransformedSignal():
+class WaveletStack():

     def __init__(self):
         """
@@ -64,7 +64,7 @@ class WaveletTransformedSignal():
         self.low_samples = []
         self.high_samples = []

-    def AddHighSamples(self, samples):
+    def PushHighSamples(self, samples):
         """
         Add a new High Sample
         """
@@ -78,7 +78,7 @@ class WaveletTransformedSignal():
                 self.high_samples.append (samples)
                 self.samples_number = len(samples)

-    def AddLowSamples(self, samples):
+    def PushLowSamples(self, samples):
         """
         Add the Low samples
         """
@@ -87,27 +87,30 @@ class WaveletTransformedSignal():
         else:
             self.low_samples.append(samples)

-    def GetLowSamples(self):
+    def PopLowSamples(self):
         """
         Get the low frequency samples
         """
         try:
             return self.low_samples.pop()
         except:
-            return None
+            raise IndexError("No low samples in the WaveletStack")

-    def GetLowSamplesLength(self):
-        """Get the length of the lowsample array"""
-        try:
-            return len(self.low_samples)
-        except:
-            return None
+    def GetLowSamplesNumber(self):
+        """Get the length of the lowsample array, i.e. how many low
+        samples track do we have pushed."""
+        return len(self.low_samples)
+
+    def GetHighSamplesNumber(self):
+        """Get the length of the lowsample array, i.e. how many low
+        samples track do we have pushed."""
+        return len(self.high_samples)

     def GetNumSamples(self):
-        """Return samples num"""
+        """Get the total number of samples in the WaveletStack."""
         return len(self.low_samples) + len(self.high_samples)

-    def GetSamplesMax(self):
+    def GetSamplesMaxValue(self):
         """Get the maximum abs value of the lowsample and
         high sample array"""
         m = [0]
@@ -117,15 +120,14 @@ class WaveletTransformedSignal():
             m.append(max(abs(high)))
         return max(m)

-    def GetHighSamples(self):
+    def PopHighSamples(self):
         """
         Get the high frequency samples
         """
         try:
-            ret = self.high_samples.pop ()
-            return ret
+            return self.high_samples.pop ()
         except:
-            return None
+            raise IndexError("No more high samples in the stack")


 class FilterBank():
@@ -232,36 +234,39 @@ class FilterBank():
         method.
         """

-        # samplesArray = []
-        samplesArray = WaveletTransformedSignal()
+        samplesStack = WaveletStack()
         low = self._Truncate(samples)

         # Do the real filtering and downsampling. Store the downsampled
         # details in the array.
         for recursion in xrange(0, self.depth):
-            samplesArray.AddHighSamples (DownSample (self.highPassFilter (low)))
+            samplesStack.PushHighSamples (DownSample (self.highPassFilter (low)))
             low = DownSample (self.lowPassFilter (low))

         # In the end append the low downsampled data to the array
-        samplesArray.AddLowSamples (low)
+        samplesStack.PushLowSamples (low)

-        return samplesArray
+        return samplesStack

-    def Rebuild(self, sampleArray):
+    def Rebuild(self, samplesStack):
         """
         Rebuild an array of samples obtained by the Split()
         method.
         """

-        low = sampleArray.GetLowSamples ()
+        low = samplesStack.PopLowSamples ()

         counter = 0

-        high = sampleArray.GetHighSamples ()
-        while(high != None):
+        # high = samplesStack.PopHighSamples ()
+        while(samplesStack.GetHighSamplesNumber() > 0):
+
+            # Otteniamo l'high samples dallo stack
+            high = samplesStack.PopHighSamples ()
+
+            # E li filtriamo insieme ai low samples.
             low = self.lowPassInverseFilter (UpSample (low))
             low += self.highPassInverseFilter (UpSample (high))
-            high = sampleArray.GetHighSamples ()

             # Facciamo shiftare l'array in modo che il delay dei sample
             # ricostruiti non disturbi la ricostruzione dei prossimi.
diff --git a/Filtering/dwt b/Filtering/dwt
index d3d26f8..480dfc3 100755
--- a/Filtering/dwt
+++ b/Filtering/dwt
@@ -109,9 +109,13 @@ class DWT():

             # Se la differenza in norma è più di 10^-8 possiamo preoccuparci.
             a = norm(rebuilt - samples[0:len(rebuilt)])
-            if (a > 1E-8):
-                Output ("Errore while reconstructing. Rebuilt samples differs from original ones")
-                Output ("||rebuilt - samples|| = %f" % a)
+            if (a > 1E-2):
+                Output ("Error while reconstructing. Rebuilt samples differs from original ones")
+                Output ("||rebuilt - samples = %f" % a)
+                Output ("There is likely an error in the code")
+            if (a > 1E-6):
+                Output ("Error while reconstructing. Rebuilt samples differs from original ones")
+                Output ("This is likely an approximation error (the error is quite small)")
             else:
                 Output ("Perfect reconstruction succeeded")
             self.WriteSamples(rebuilt, filewrite)
@@ -142,35 +146,44 @@ class DWT():
         """
         Shows the result of filtering
         """
+
+        # We set the frequency to have seconds (and not samples)
+        # in the x-axis of the plot.
+        frequency = 44100.0
+
+        # We choose a decreasing scale to sync all the samples
+        # because they are recursively downsamples by a factor
+        # of two and we want to plot with the same time-scale.
         scale = pow(2, wavelets.GetNumSamples ())
-        singleOffset = 2 * wavelets.GetSamplesMax()
+
+        singleOffset = 2 * wavelets.GetSamplesMaxValue()
         offset = -3 * singleOffset
+
         # We plot only the first 1000000 samples, to avoid memory
         # being flooded with our data :)
         toPlot = 1000000

         # Stampo i low
         scale = int(0.5 * scale)
-        low = wavelets.GetLowSamples()
+        low = wavelets.PopLowSamples()
         data = low[:toPlot / scale]

-        axes = range(0, len(data) * scale, scale)
+        axes = array(range(0, len(data) * scale, scale)) / frequency

         plot(axes, data + offset)

         offset += singleOffset

-        samples = wavelets.GetHighSamples ()
-        while samples is not None:
+        while (wavelets.GetHighSamplesNumber() > 0):
+
+            samples = wavelets.PopHighSamples ()

             data = samples[0:toPlot / scale]
-            axes = range(0, len(data) * scale , scale)
+            axes = array(range(0, len(data) * scale , scale)) / frequency

             plot (axes, data + offset)
             offset += singleOffset
             scale = int(0.5*scale)
-
-            samples = wavelets.GetHighSamples ()

         show ()
ViewGit