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.
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 ()