Created
March 12, 2016 22:06
-
-
Save piercus/b005ed5fbc70761bde96 to your computer and use it in GitHub Desktop.
python lowpass example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import matplotlib.pyplot as plt | |
import numpy as np | |
import wave | |
import sys | |
import math | |
import contextlib | |
fname = 'test.wav' | |
outname = 'filtered.wav' | |
cutOffFrequency = 400.0 | |
# from http://stackoverflow.com/questions/13728392/moving-average-or-running-mean | |
def running_mean(x, windowSize): | |
cumsum = np.cumsum(np.insert(x, 0, 0)) | |
return (cumsum[windowSize:] - cumsum[:-windowSize]) / windowSize | |
# from http://stackoverflow.com/questions/2226853/interpreting-wav-data/2227174#2227174 | |
def interpret_wav(raw_bytes, n_frames, n_channels, sample_width, interleaved = True): | |
if sample_width == 1: | |
dtype = np.uint8 # unsigned char | |
elif sample_width == 2: | |
dtype = np.int16 # signed 2-byte short | |
else: | |
raise ValueError("Only supports 8 and 16 bit audio formats.") | |
channels = np.fromstring(raw_bytes, dtype=dtype) | |
if interleaved: | |
# channels are interleaved, i.e. sample N of channel M follows sample N of channel M-1 in raw data | |
channels.shape = (n_frames, n_channels) | |
channels = channels.T | |
else: | |
# channels are not interleaved. All samples from channel M occur before all samples from channel M-1 | |
channels.shape = (n_channels, n_frames) | |
return channels | |
with contextlib.closing(wave.open(fname,'rb')) as spf: | |
sampleRate = spf.getframerate() | |
ampWidth = spf.getsampwidth() | |
nChannels = spf.getnchannels() | |
nFrames = spf.getnframes() | |
# Extract Raw Audio from multi-channel Wav File | |
signal = spf.readframes(nFrames*nChannels) | |
spf.close() | |
channels = interpret_wav(signal, nFrames, nChannels, ampWidth, True) | |
# get window size | |
# from http://dsp.stackexchange.com/questions/9966/what-is-the-cut-off-frequency-of-a-moving-average-filter | |
freqRatio = (cutOffFrequency/sampleRate) | |
N = int(math.sqrt(0.196196 + freqRatio**2)/freqRatio) | |
# Use moviung average (only on first channel) | |
filtered = running_mean(channels[0], N).astype(channels.dtype) | |
wav_file = wave.open(outname, "w") | |
wav_file.setparams((1, ampWidth, sampleRate, nFrames, spf.getcomptype(), spf.getcompname())) | |
wav_file.writeframes(filtered.tobytes('C')) | |
wav_file.close() |
"channels[0] is the original signal filtered is the low-passed signal" High-pass(signal) = signal - low-passed signal when I try to subtract it gives dimension error
Likely 1 of 2 cases : Your code attempts to subtract channel[i] - filtered[i] but because the channel is a 2d array you needed to do channel[0][i] - filtered[i].
If you've already accounted for this, then you're likely parsing through the entirety of channel[0] when it's not possible because filtered will always be lesser than or equal to channel[0]. A fix is to only parse as far as filtered goes.
for i in range(len(filtered)):
filtered[i] = channels[0][i] - filtered[i]
Depending on how you would like to change it within, you can shift it more-so towards the right. This is implementing the HPass = Signal - LPass
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Did you ever figure out the error? How did you fix it?