Ora sembra andare (mancava uno shift). Dovrò implementare una

Leonardo Robol [2010-03-02 12:53]
Ora sembra andare (mancava uno shift). Dovrò implementare una
classe FilterBank che automatizzi il procedimento per poterlo
usare in maniera più organica.
Filename
Filtering/Filtering.py
Filtering/Splitting.py
diff --git a/Filtering/Filtering.py b/Filtering/Filtering.py
index 833fc2b..fe0ed71 100644
--- a/Filtering/Filtering.py
+++ b/Filtering/Filtering.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 #

-from numpy import array, zeros, convolve
+from numpy import array, zeros, convolve, dot

 class AbstractFilter():

@@ -19,21 +19,33 @@ class AbstractFilter():

 class FIR(AbstractFilter):

-    def __init__(self, coefficients):
+    def __init__(self, coefficients, inverse = False):

         self.coefficients = coefficients
+        self.inverse = inverse

     def __call__(self, samples):
         """Apply the FIR to samples"""
-        return convolve (self.coefficients,
-                         samples, 'same')
+        if not self.inverse:
+            return convolve (self.coefficients,
+                             samples, 'same')
+        else:
+            s = samples
+            # Questa è un po' una grezzata e trascuriamo i bordi,
+            # ma per ora voglio vedere se funziona.
+            for i in xrange(0,len(s) - len(self.coefficients)):
+                s[i] = dot(self.coefficients,
+                           samples[i:i+len(self.coefficients)])
+            return s
+
+

 def DownSample(samples):

-    return samples[::2]
+    return array(samples[::2])

 def UpSample(samples):

     s = zeros(2 * len(samples))
     s[::2] = samples
-    return s
+    return array(s)
diff --git a/Filtering/Splitting.py b/Filtering/Splitting.py
index 2d0e98e..14488b5 100644
--- a/Filtering/Splitting.py
+++ b/Filtering/Splitting.py
@@ -3,29 +3,28 @@
 #

 import Filtering, pylab
-from numpy import array, sqrt, memmap
+from numpy import array, sqrt, memmap, roll

 class SplittingExample():

     def __init__(self):

         # Numero di ricorsioni della filter bank
-        self.depth = 2
+        self.depth = 4

         # Creo i filtri che userò in maniera arguta
         # in seguito. Questo filtro è ortogonale, nel
         # senso che posso ottenere la filter bank inversa
         # invertendo semplicemente la matrice.
         # h0 = 0.125 * array([1+sqrt(3), 3+sqrt(3), 3-sqrt(3), 1-sqrt(3)])
-        #h1 = 0.125 * array([1-sqrt(3), -3+sqrt(3), 3+sqrt(3),-1-sqrt(3)])
-
-        #f0 = 0.25 * array([1-sqrt(3), 3-sqrt(3), 3+sqrt(3), 1+sqrt(3)])
-        #f1 = 0.25 * array([-1-sqrt(3),3+sqrt(3),-3-sqrt(3), 1-sqrt(3)])
+        # h1 = 0.125 * array([1-sqrt(3), -3+sqrt(3), 3+sqrt(3),-1-sqrt(3)])
+        # f0 = 0.25 * array([1-sqrt(3), 3-sqrt(3), 3+sqrt(3), 1+sqrt(3)])
+        # f1 = 0.25 * array([-1-sqrt(3),3+sqrt(3),-3-sqrt(3), 1-sqrt(3)])
         h0 = array([0.5 , 0.5])
         h1 = array([-0.5, 0.5])

-        f0 = array([0.5, 0.5])
-        f1 = array([-0.5, 0.5])
+        f0 = array([1, 1])
+        f1 = array([1, -1])

         self.lowpass  = Filtering.FIR (h0)
         self.highpass = Filtering.FIR (h1)
@@ -33,13 +32,16 @@ class SplittingExample():
         self.f0 = Filtering.FIR (f0)
         self.f1 = Filtering.FIR (f1)

-        self.LoadSamples ()
+        self.samples = self.LoadSamples ("sunny.pcm")
+        print self.samples
         self.TruncateSamples ()
         self.Split ()

         self.Rebuild ()
         self.WriteSamples(self.samples , "rebuilt.pcm")

+        print self.LoadSamples("rebuilt.pcm")
+
         # self.Show ()

     def TruncateSamples(self):
@@ -48,16 +50,22 @@ class SplittingExample():
         of 2^self.depth so that I can apply recursive filtering
         without any problem. If not, just truncate :)
         """
-        self.samples = self.samples[:-1*(len(self.samples) % (pow(2,self.depth)))]
+        to_remove = len(self.samples) % (pow(2,self.depth))
+        # Se non c'è niente da rimuovere l'istruzione che segue
+        # portebbe produrre casini.
+        if to_remove is 0:
+            return
+        self.samples = self.samples[:-1*to_remove]

     def LoadSamples(self, filename = "sunny.pcm"):
         """
         Load the samples from an audio file
         """
+        print " => Loading samples from %s" % filename
         samples = memmap (filename,
                           dtype="<h",
                           mode="r")
-        self.samples = samples
+        return samples

     def WriteSamples(self, samples, filename):
         data = memmap (filename,
@@ -78,8 +86,9 @@ class SplittingExample():

         self.low_d = Filtering.DownSample(self.low)
         self.high_d = Filtering.DownSample(self.high)
-

+        print self.low_d
+        print self.high_d

         self.WriteSamples(self.high_d, "high_" + suffix + ".pcm")

@@ -106,17 +115,23 @@ class SplittingExample():

         if(suffix == None):
             suffix = self.depth * "d"
-            self.LoadSamples("low_" + suffix + ".pcm")
+            low = self.LoadSamples("low_" + suffix + ".pcm")
+            low = Filtering.UpSample(low)
+        else:
+            low = Filtering.UpSample(self.samples)

-        print " => Rebuild called with suffix = %s" % suffix
+        high = self.LoadSamples("high_" + suffix + ".pcm")
+        high = Filtering.UpSample(high)

-        low = Filtering.UpSample(self.samples)
+        print " => Upsampled"

-        self.LoadSamples("high_" + suffix + ".pcm")
-        high = Filtering.UpSample(self.samples)
+        # print " => Rebuild called with suffix = %s" % suffix
+        # print "    shape = (%d, %d)" % (len(low), len(high))
+        self.samples = roll(self.f0(low) + self.f1(high), -1)
+        print self.samples

-        self.samples = self.f0(low) + self.f1(high)
         if (len(suffix) > 1):
+            self.WriteSamples(self.samples, "prova.pcm")
             self.Rebuild (suffix[:-1])

ViewGit