# Apply FIR filters to Extract Stego from WAV data

I appreciate anyone that takes a moment to help me with this problem. I've been banging my head against the keyboard for a while, searching forums and DSP tutorials and I can't figure this problem out.

Here's a couple links I found very helpful from this forum on the subject: http://www.dspguide.com/ http://wiki.scipy.org/Cookbook/ApplyFIRFilter

So I have a WAV file with a 28 sec song/sound that I am trying to convert to frequency range, apply an FIR filter to isolate the 14.5 - 16kHz range. The WAV has a sampling rate of 32 kHz and contains an intermittent buzz that becomes clearer when I drop out all other frequencies besides the 14.5 -16kHz bands.

I have written this sample of python code, and believe I am close to isolating the signal. Its hard to tell.

# read data from file name fn, using low/high for bandpass
# low and high frequency cutoffs, and a
def filter_frequencies(fn,low=0,high=0):
data = wave.open(fn,'rb'); rate = data.getframerate()
ntap = (rate / 4) + 1; nyq = rate / 2
low,high = low/nyq,high/nyq
chunks = int(data.getnframes()/(rate*4))
ns = b''
if low and high == 0: # lowpass
bp = low; pz = True
elif high and low == 0: # highpass
bp = high; pz = False
else: # bandpass
bp = [low,high]; pz = False

b = firwin(ntap, bp, pass_zero=pz, window='blackman', nyq=nyq)
y = b''
for num in range(chunks):
# read 4 secs of frames from wav file
seg = np.fromstring(data.readframes(rate*4),dtype=np.int8)
#seg = np.fromstring(data.readframes(data.getnframes()),dtype=np.int8)
# convert frame amplitudes to their frequency values
freq = np.fft.rfft(seg)
# perform lowpass, highpass or bandpass filter
cr = fftconvolve(freq,b,mode='valid')
# converts frequencies to binary string
y += cr.tostring()
data.close()
return y


I am a noob to DSP, so again I would really appreciate your help on if I am doing the FFT to inverse FFT correctly.

Below is the code I am using to transform the output from the above function back into WAV bytes format.

def frequency_to_bytes(freq):
# invert the Fast Fourier Transform
nf = np.fft.irfft(freq)
# convert frequencies back to integer values
bs = np.ravel(nf).astype(np.int8)
return bs.tostring()



P.s. if you have seen this problem before, or know what challenge I am trying to solve, please no spoilers. I have been working on this for a week solid.

edit: added some background links I have been using as reference.

## 1 Answer

I never worked with Python or SciPy, but I don't see the sense in the actions you apparently perform in your code. firwin provides you with the time-domain filter coefficients, which are to be convolved with the time-domain signal you wish to filter. What you do in your code, is convolve the time-domain filter coefficients with the frequency-domain signal - which makes absolutely no sense.

What is the point of converting the signal to freq-domain (doing FFT)? Is the stego analysis/decoding performed in time- or frequency-domain?

If your processing chain requires conversion of the signal to freq-domain, for some purpose, then you don't really need the FIR filter, since you can get rid of the undesired frequency elements once you have the signal in the frequency domain, by simply zeroing-out the undesired frequency bins of the signal.

If the only reason for calculating FFT of the signal is to filter it - then there is no need to do it, as you can simply convolve the time-domain filter coefficients with the time-domain signal, as I explained.

• Thanks for clearing that up, I knew I had to be doing something wrong. I thought firwin would generate the frequency-domain parameters instead of time-domain. My thinking behind the FFT was to convert the binary from the WAV file into the frequency domain, then to filter out everything outside the 14.5 - 16 kHz band. Could you clear up the difference between time and frequency domain? The stego message is an intermittent buzz that is heard most clearly in the frequency range described, so would it be in both? – stami Jan 25 '15 at 9:37
• bit.ly/15K9ZkF – Sagie Jan 26 '15 at 10:02