def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) (mX, pX) = dftAnal(x, w, N) mXfilt = mX.copy() f_bin = math.ceil(N * 70.0 / fs) mXfilt[:f_bin+1] = -120.0 y = dftSynth(mX, pX, w.size) * outputScaleFactor yfilt = dftSynth(mXfilt, pX, w.size) * outputScaleFactor return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ ## Your code here M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) # compute the dft of the sound fragment mX, pX = dftAnal(x, w, N) # compute no-filter y = dftSynth(mX, pX, w.size) * sum(w) # filter magnitude under 70Hz import math bin70 = math.ceil(70.0 * N / fs) mX[:bin70 + 1] = -120 yfilt = dftSynth(mX, pX, w.size) * sum(w) return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) # mX = mag spectrum, pX = phase spectrum mX, pX = dftAnal(x, w, N) # without the filter y = dftSynth(mX, pX, w.size) * outputScaleFactor # https://stackoverflow.com/questions/4364823/how-do-i-obtain-the-frequencies-of-each-value-in-an-fft fil_70 = int(math.ceil(70.0 * N / fs)) mX[:fil_70 + 1] = -120 yfilt = dftSynth(mX, pX, w.size) * outputScaleFactor return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) #smotthing window outputScaleFactor = sum(w) ## Your code here mX, pX = dftAnal(x,w,N) axis = (fs) * np.arange(M)/float(M) belowAxis = sum(axis < 70) mXX = mX.copy() mXX[:belowAxis+1] = -120 #Synthesis y = dftSynth(mX, pX, w.size)*sum(w) yfilt = dftSynth(mXX, pX, w.size)*sum(w) return (y,yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) cutoff = 70 Xmag, Xphase = dftAnal(x, w, N) Xmagfilt = Xmag.copy() y = dftSynth(Xmag, Xphase, M) * outputScaleFactor Xmagfilt[:int(np.ceil(cutoff * N / fs)) + 1] = -120.0 yfilt = dftSynth(Xmagfilt, Xphase, M) * outputScaleFactor return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here (mX, pX) = dftAnal(x, w, N) mX1 = mX.copy() R = fs / N R = int(R) for x in range(R): mX1[x] = 0 y = dftSynth(mX, pX, M) yfilt = dftSynth(mX1, pX, M) return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ ## Your code here M = len(x) w = get_window("hamming", M) outputScaleFactor = sum(w) # compute the dft of the sound fragment mX, pX = dftAnal(x, w, N) # compute no-filter y = dftSynth(mX, pX, w.size) * sum(w) # filter magnitude under 70Hz import math bin70 = math.ceil(70.0 * N / fs) mX[: bin70 + 1] = -120 yfilt = dftSynth(mX, pX, w.size) * sum(w) return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array Outputs:) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here mX, pX = dftAnal(x, w, N) y = dftSynth(mX, pX, w.size) * outputScaleFactor #synthesize the orignial signal first #Manipulate mX and pX to produce yfilt here #get copy of mX and pX mXfilt = mX.copy() pXfilt = pX.copy() #the pin no that corresponding to 70Hz pinResolution = fs/N pin70Hz = int(np.ceil(70/pinResolution)) #Filtering mXfilt[:pin70Hz + 1] = -120 #synthesize yfilt yfilt = dftSynth(mXfilt, pXfilt, w.size) * outputScaleFactor # return y and y filt return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here (mX, pX) = dftAnal(x, w, N) mXfilt = mX.copy() bin_size = fs / N seventy_bin_number = int ( math.ceil(float(70)/bin_size) ) for i in range(seventy_bin_number): mXfilt[i] = -120 yfilt = dftSynth(mXfilt, pX, w.size) * sum(w) y = dftSynth(mX, pX, w.size) * sum(w) return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here mX, pX = dftAnal(x, w, N) mXfilt = np.copy(mX) bin70hz = int(np.ceil(N * 70.0 / fs)) mXfilt[:bin70hz+1] = -120 y = dftSynth(mX, pX, w.size) * outputScaleFactor yfilt = dftSynth(mXfilt, pX, w.size) * outputScaleFactor return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here mX, pX = dftAnal(x, w, N) k = np.ceil(70.0 / fs * N) mX_filt = mX.copy() for n in range(int(k)): mX_filt[n] = -120 y = dftSynth(mX, pX, w.size) * sum(w) yfilt = dftSynth(mX_filt, pX, w.size) * sum(w) tp = (y, yfilt) return (tp)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) (mX, pX) = dftAnal(x, w, N) y = dftSynth(mX, pX, w.size) * outputScaleFactor maxBin = int(np.ceil(70 * (M / fs))) for i in range(maxBin + 1): mX[i] = -120 yfilt = dftSynth(mX, pX, w.size) * outputScaleFactor return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here CutFrec = 70 mX, pX = dftAnal(x, w, N) mXfilt = mX.copy() mXfilt[:int(np.ceil(CutFrec * N / fs)) + 1] = -120 y = outputScaleFactor * dftSynth(mX, pX, M) yfilt = outputScaleFactor * dftSynth(mXfilt, pX, M) return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) mX, pX = dftAnal(x, w, N) y = dftSynth(mX, pX, w.size)*sum(w) freqs = np.arange(N/2) * float(fs) / (N) idx = np.argmax(freqs >= 70) # print(idx) mX[:(idx+1)] = -120 # print(len(freqs), len(mX), sum(freqs <= 70.)) # print (len(mX), len(freqs)) # mX[np.concatenate(([True],(freqs <= 71.)))] = -120 # pX[np.concatenate(([True],(freqs <= 70.)))] = 0 y_filt = dftSynth(mX, pX, w.size)*sum(w) return(y, y_filt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) #N = 2 ** np.ceil(np.log2(M)) mX, pX = dftAnal(x, w, N) # zero magnitude bins <= 70 Hz fft_res = fs / N last_bin = int(np.ceil(70.0 / fft_res)) mX_filtered = mX.copy() for i in range(last_bin + 1): mX_filtered[i] = -120.0 # 10.0 ** (-120.0 / 20.0) y = dftSynth(mX, pX, M) * outputScaleFactor yfilt = dftSynth(mX_filtered, pX, M) * outputScaleFactor return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) mX, pX = dftAnal(x, w, N) # filting mX1 = mX.copy() # fk = fs * k / N, so k = fk(70) * N / fs bin70 = np.ceil(70 * N / fs) mX1[:int(bin70 + 1)] = -120 # without filting y = dftSynth(mX, pX, M) * outputScaleFactor # with filting yfilter = dftSynth(mX1, pX, M) * outputScaleFactor return (y, yfilter)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) #print N ## Your code here dftv = dftAnal(x, w, N) #print dftv[0].shape filterDft = dftv[0].copy() for i in range(len(filterDft)): fz = fs * i / N filterDft[i] = -120 if fz > 70: break #print str(fz) + ' ' + str(i) return (dftSynth(dftv[0], dftv[1], M) * outputScaleFactor, dftSynth(filterDft, dftv[1], M) * outputScaleFactor)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) mx,px = dftAnal(x,w,N) mx2 = mx.copy() mx2[:np.floor(70*N/fs)+1] = -120 yone = dftSynth(mx,px,M)*sum(w) ytwo = dftSynth(mx2,px,M)*sum(w) return yone,ytwo
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) mX, pX = dftAnal(x, w, N) bin_freq=(fs*1.0)/(N*1.0) # print(mX.shape) mX_copy=mX.copy() # print(mX) # print(mX_copy) mX_copy[:int(np.ceil(70.0/bin_freq)+1)]=-120 # plt.plot(mX) # plt.plot(mX_copy) # plt.show() # print(mX) # print(mX_copy) y = dftSynth(mX, pX, w.size)*sum(w) yfilt = dftSynth(mX_copy, pX, w.size)*sum(w) return (y,yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window("hamming", M) outputScaleFactor = sum(w) # get Magnitude and Phase Spectrum mX, pX = dftAnal(x, w, N) # generate output signal without filtering y = dftSynth(mX, pX, M) * outputScaleFactor # get bin number that is nearest to 70 Hz bin_number = int(70.0 / (fs / float(N))) + 1 # do the 'filtering' for i in range(bin_number + 1): mX[i] = -120 # generate the time signal after filtering yfilt = dftSynth(mX, pX, M) * outputScaleFactor return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) mX, pX = dftAnal(x, w, N) freqLim = 70.0 freqBinSize = fs / N binLim = int(np.ceil(freqLim / freqBinSize)) mX2 = mX.copy() mX2[0:binLim + 1] = -120.0 y = dftSynth(mX, pX, M) * outputScaleFactor yFilt = dftSynth(mX2, pX, M) * outputScaleFactor return (y, yFilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) (mX, pX) = dftAnal(x, w, N) mXnew = mX.copy() index = int(np.ceil((70.0 * N) / float(fs))) for i in range(index): if i < N: mXnew[i] = -120 y = dftSynth(mX, pX, M) yFilt = dftSynth(mXnew, pX, M) return outputScaleFactor * y, outputScaleFactor * yFilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here (mX, pX) = dftAnal(x, w, N) # Get FFT for the input signal mXfilt = mX.copy() # Get the magnitude spectrum to be filtered pXfilt = pX.copy() # Get the phase spectrum to be filtered freqs = float(fs) * np.arange(pX.size) / float( N) # Convert bins to frequencies freqsAbove70 = np.where(freqs >= 70) if freqsAbove70[0].size > 0: mXfilt[:freqsAbove70[0][0] + 1] = -120 y = dftSynth( mX, pX, w.size) * outputScaleFactor # synthesize the unfiltered signal yfilt = dftSynth( mXfilt, pXfilt, w.size) * outputScaleFactor # synthesize the filtered signal # plot the sound fragment plt.subplot(4, 1, 1) plt.plot(mX) plt.ylabel('mX') # plot the magnitude spectrum plt.subplot(4, 1, 2) plt.plot(mXfilt) plt.ylabel('mXfilt') # plot the phase spectrum plt.subplot(4, 1, 3) plt.plot(y) plt.ylabel('y') # plot the sound resulting from the inverse dft plt.subplot(4, 1, 4) plt.plot(yfilt) plt.ylabel('yfilt') plt.tight_layout() plt.show() return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window("hamming", M) outputScaleFactor = sum(w) ## Your code here # get a fragment of the input sound of size M sample = 0 if sample + M > x.size or sample < 0: # raise error if time outside of sound raise ValueError("Time outside sound boundaries") x1 = x[sample : sample + M] # compute the dft of the sound fragment mX, pX = dftAnal(x1, w, N) # compute the inverse dft of the spectrum y = dftSynth(mX, pX, w.size) * outputScaleFactor # Now, suppress any buckets representing 70Hz or less (including # the bucket just above 70Hz) # # How do you find the bucket for 70Hz? # # There are N buckets that span the frequency range from 0 to fs. # # (actually, mX only has N/2 buckets for a fs/2 frequency range # because it's symmetric and mX only has the positive part. For # N=1024, fs=10000, mX has 513 buckets.) # # So each bucket covers a range of fs / N frequency. So the # bucket that contains 70Hz is 70 * N / fs. Since we want to zero # out everything starting with the bucket just above this, we do # np.ceil. cutoff = np.ceil(N * 70 / fs) mX[: cutoff + 1] = -120 # compute the inverse dft of the filtered spectrum yfilt = dftSynth(mX, pX, w.size) * outputScaleFactor return (y, yfilt)
def stftFiltering(x, fs, w, N, H, filter): # apply a filter to a sound by using the STFT # x: input sound, w: analysis window, N: FFT size, H: hop size # filter: magnitude response of filter with frequency-magnitude pairs (in dB) # returns y: output sound M = w.size # size of analysis window hM1 = int(math.floor((M+1)/2)) # half analysis window size by rounding hM2 = int(math.floor(M/2)) # half analysis window size by floor x = np.append(np.zeros(hM2),x) # add zeros at beginning to center first window at sample 0 x = np.append(x,np.zeros(hM1)) # add zeros at the end to analyze last sample pin = hM1 # initialize sound pointer in middle of analysis window pend = x.size-hM1 # last sample to start a frame w = w / sum(w) # normalize analysis window y = np.zeros(x.size) # initialize output array while pin<=pend: # while sound pointer is smaller than last sample #-----analysis----- x1 = x[pin-hM1:pin+hM2] # select one frame of input sound mX, pX = DFT.dftAnal(x1, w, N) # compute dft #------transformation----- mY = mX + filter # filter input magnitude spectrum #-----synthesis----- y1 = DFT.dftSynth(mY, pX, M) # compute idft y[pin-hM1:pin+hM2] += H*y1 # overlap-add to generate output sound pin += H # advance sound pointer y = np.delete(y, range(hM2)) # delete half of first window which was added in stftAnal y = np.delete(y, range(y.size-hM1, y.size)) # add zeros at the end to analyze last sample return y
def stft(x, w, N, H): """ Analysis/synthesis of a sound using the short-time Fourier transform x: input sound, w: analysis window, N: FFT size, H: hop size returns y: output sound """ if (H <= 0): # raise error if hop size 0 or negative raise ValueError("Hop size (H) smaller or equal to 0") M = w.size # size of analysis window hM1 = int(math.floor((M + 1) / 2)) # half analysis window size by rounding hM2 = int(math.floor(M / 2)) # half analysis window size by floor x = np.append(np.zeros(hM2), x) # add zeros at beginning to center first window at sample 0 x = np.append(x, np.zeros(hM1)) # add zeros at the end to analyze last sample pin = hM1 # initialize sound pointer in middle of analysis window pend = x.size - hM2 # last sample to start a frame w = w / sum(w) # normalize analysis window y = np.zeros(x.size) # initialize output array while pin <= pend: # while sound pointer is smaller than last sample # -----analysis----- x1 = x[pin - hM1:pin + hM2] # select one frame of input sound mX, pX = DFT.dftAnal(x1, w, N) # compute dft # -----synthesis----- y1 = DFT.dftSynth(mX, pX, M) # compute idft y[pin - hM1:pin + hM2] += H * y1 # overlap-add to generate output sound pin += H # advance sound pointer y = np.delete(y, range(hM2)) # delete half of first window which was added in stftAnal y = np.delete(y, range(y.size - hM1, y.size)) # delete half of the last window which as added in stftAnal return y
def stftSynth(mY, pY, M, H): """ Synthesis of a sound using the short-time Fourier transform mY: magnitude spectra, pY: phase spectra, M: window size, H: hop-size returns y: output sound """ hM1 = int(math.floor((M + 1) / 2)) # half analysis window size by rounding hM2 = int(math.floor(M / 2)) # half analysis window size by floor nFrames = mY[:, 0].size # number of frames y = np.zeros(nFrames * H + hM1 + hM2) # initialize output array pin = hM1 for i in range(nFrames): # iterate over all frames y1 = DFT.dftSynth(mY[i, :], pY[i, :], M) # compute idft y[pin - hM1:pin + hM2] += H * y1 # overlap-add to generate output sound pin += H # advance sound pointer y = np.delete( y, range(hM2)) # delete half of first window which was added in stftAnal y = np.delete(y, range( y.size - hM1, y.size)) # delete the end of the sound that was added in stftAnal return y
def stft(x, w, N, H): """ Analysis/synthesis of a sound using the short-time Fourier transform x: input sound, w: analysis window, N: FFT size, H: hop size returns y: output sound """ if (H <= 0): # raise error if hop size 0 or negative raise ValueError("Hop size (H) smaller or equal to 0") M = w.size # size of analysis window hM1 = int(math.floor((M+1)/2)) # half analysis window size by rounding hM2 = int(math.floor(M/2)) # half analysis window size by floor x = np.append(np.zeros(hM2),x) # add zeros at beginning to center first window at sample 0 x = np.append(x,np.zeros(hM1)) # add zeros at the end to analyze last sample pin = hM1 # initialize sound pointer in middle of analysis window pend = x.size-hM1 # last sample to start a frame w = w / sum(w) # normalize analysis window y = np.zeros(x.size) # initialize output array while pin<=pend: # while sound pointer is smaller than last sample #-----analysis----- x1 = x[pin-hM1:pin+hM2] # select one frame of input sound mX, pX = DFT.dftAnal(x1, w, N) # compute dft #-----synthesis----- y1 = DFT.dftSynth(mX, pX, M) # compute idft y[pin-hM1:pin+hM2] += H*y1 # overlap-add to generate output sound pin += H # advance sound pointer y = np.delete(y, range(hM2)) # delete half of first window which was added in stftAnal y = np.delete(y, range(y.size-hM1, y.size)) # delete half of the last window which as added in stftAnal return y
def onset_test(noise_ffts, noise_phs, ind, mY, pY, M, H, recType, outDir, name, fs): """ Synthesis of a sound using the short-time Fourier transform mY: magnitude spectra, pY: phase spectra, M: window size, H: hop-size returns y: output sound """ for i in ind: mY[i - 3:i + 3, :] = noise_ffts[97:103, :] pY[i - 3:i + 3, :] = noise_phs[97:103, :] hM1 = (M + 1) // 2 # half analysis window size by rounding hM2 = M // 2 # half analysis window size by floor nFrames = mY[:, 0].size # number of frames y = np.zeros(nFrames * H + hM1 + hM2) # initialize output array pin = hM1 for i in range(nFrames): # iterate over all frames y1 = DFT.dftSynth(mY[i, :], pY[i, :], M) # compute idft y[pin - hM1:pin + hM2] += H * y1 # overlap-add to generate output sound pin += H # advance sound pointer y = np.delete( y, range(hM2)) # delete half of first window which was added in stftAnal y = np.delete(y, range( y.size - hM1, y.size)) # delete the end of the sound that was added in stftAnal os.chdir('/home/tgoodall/sms-tools/software/models/Overtone_Arrays/' + recType + '/' + outDir) outputFile = name + '.wav' UF.wavwrite(y, fs, outputFile) return y
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) fr = 70 * N / fs ## Your code here w = get_window('hamming', N) n = np.arange(M) X, P = dftAnal(x, w, N) bin = int(np.ceil(70 * len(x) / fs)) fb = np.zeros(len(X)) - 120 fb[bin:] = X[bin:] yfil = dftSynth(fb, P, N) * outputScaleFactor return X, fb, x, yfil
def stftFiltering(x, fs, w, N, H, filter): """ Apply a filter to a sound by using the STFT x: input sound, w: analysis window, N: FFT size, H: hop size filter: magnitude response of filter with frequency-magnitude pairs (in dB) returns y: output sound """ M = w.size # size of analysis window hM1 = int(math.floor((M+1)/2)) # half analysis window size by rounding hM2 = int(math.floor(M/2)) # half analysis window size by floor x = np.append(np.zeros(hM2),x) # add zeros at beginning to center first window at sample 0 x = np.append(x,np.zeros(hM1)) # add zeros at the end to analyze last sample pin = hM1 # initialize sound pointer in middle of analysis window pend = x.size-hM1 # last sample to start a frame w = w / sum(w) # normalize analysis window y = np.zeros(x.size) # initialize output array while pin<=pend: # while sound pointer is smaller than last sample #-----analysis----- x1 = x[pin-hM1:pin+hM2] # select one frame of input sound mX, pX = DFT.dftAnal(x1, w, N) # compute dft #------transformation----- mY = mX + filter # filter input magnitude spectrum #-----synthesis----- y1 = DFT.dftSynth(mY, pX, M) # compute idft y[pin-hM1:pin+hM2] += H*y1 # overlap-add to generate output sound pin += H # advance sound pointer y = np.delete(y, range(hM2)) # delete half of first window which was added in stftAnal y = np.delete(y, range(y.size-hM1, y.size)) # add zeros at the end to analyze last sample return y
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ ## Your code here M = len(x) bin70 = int(math.ceil(70.0*N/fs)) w = get_window("hamming", M) mX, pX = dftAnal(x, w, N) mX2 = mX.copy() mX2[:bin70 + 1] = -120 """z = 0 while True: if( z <= bin70): mX2[z] = -120 z= z + 1 else: mX2[z] = -120 break""" print M print fs print N print bin70 """plt.plot(mX) plt.plot(mX2) plt.show()""" y = dftSynth(mX, pX, M) * sum(w) yfilt = dftSynth(mX2, pX, M) * sum(w) return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here (mX,pX) = dftAnal(x,w,N) y = dftSynth(mX,pX,M)*outputScaleFactor dHz = 1.*fs/N ''' for i in range((N/2)+1): if mX[i] > -30: print i*dHz, mX[i] ''' thresh = 70.0 + dHz for i in range((N/2)+1): if (i*dHz) >= thresh: break else: mX[i] = -120. ''' for i in range((N/2)+1): if mX[i] > -30: print i*dHz ''' yfilt = dftSynth(mX,pX,M)*outputScaleFactor return y,yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here mX, pX = dftAnal(x, w, N) # get discrete freq index corresponding to 70Hz k = math.ceil(70 * N / fs) # set freqs less than 70Hz to zero mX_filt = mX.copy() mX_filt[:k + 1] = -120 # synthesise signals. y = dftSynth(mX, pX, w.size) * outputScaleFactor y_filt = dftSynth(mX_filt, pX, w.size) * outputScaleFactor # plots t1 = np.arange(len(y)) t2 = np.arange(len(mX)) plt.figure(figsize=(15, 7)) plt.subplot(2, 1, 1) plt.plot(t1, y, label='unfiltered') plt.plot(t1, y_filt, label='filtered') plt.legend() plt.subplot(2, 1, 2) plt.plot(t2, mX, label='unfiltered') plt.plot(t2, mX_filt, label='filtered') plt.legend() plt.show() return y, y_filt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = x.size w = get_window('hamming', M) mX, pX = dftAnal(x, w, N) y = dftSynth(mX, pX, M) * sum(w) mY = np.copy(mX) mY[:int(math.ceil(70.0 * N / fs) + 1)] = -120 yfilt = dftSynth(mY, pX, M) * sum(w) return (y, yfilt)
def stftMorph(x1, x2, fs, w1, N1, w2, N2, H1, smoothf, balancef): """ Morph of two sounds using the STFT x1, x2: input sounds, fs: sampling rate w1, w2: analysis windows, N1, N2: FFT sizes, H1: hop size smoothf: smooth factor of sound 2, bigger than 0 to max of 1, where 1 is no smothing, balancef: balance between the 2 sounds, from 0 to 1, where 0 is sound 1 and 1 is sound 2 returns y: output sound """ if (N2/2*smoothf < 3): # raise exception if decimation factor too small raise ValueError("Smooth factor too small") if (smoothf > 1): # raise exception if decimation factor too big raise ValueError("Smooth factor above 1") if (balancef > 1 or balancef < 0): # raise exception if balancef outside 0-1 raise ValueError("Balance factor outside range") if (H1 <= 0): # raise error if hop size 0 or negative raise ValueError("Hop size (H1) smaller or equal to 0") M1 = w1.size # size of analysis window hM1_1 = int(math.floor((M1+1)/2)) # half analysis window size by rounding hM1_2 = int(math.floor(M1/2)) # half analysis window size by floor L = int(x1.size/H1) # number of frames for x1 x1 = np.append(np.zeros(hM1_2),x1) # add zeros at beginning to center first window at sample 0 x1 = np.append(x1,np.zeros(hM1_1)) # add zeros at the end to analyze last sample pin1 = hM1_1 # initialize sound pointer in middle of analysis window w1 = w1 / sum(w1) # normalize analysis window M2 = w2.size # size of analysis window hM2_1 = int(math.floor((M2+1)/2)) # half analysis window size by rounding hM2_2 = int(math.floor(M2/2)) # half analysis window size by floor2 H2 = int(x2.size/L) # hop size for second sound x2 = np.append(np.zeros(hM2_2),x2) # add zeros at beginning to center first window at sample 0 x2 = np.append(x2,np.zeros(hM2_1)) # add zeros at the end to analyze last sample pin2 = hM2_1 # initialize sound pointer in middle of analysis window y = np.zeros(x1.size) # initialize output array for l in range(L): #-----analysis----- mX1, pX1 = DFT.dftAnal(x1[pin1-hM1_1:pin1+hM1_2], w1, N1) # compute dft mX2, pX2 = DFT.dftAnal(x2[pin2-hM2_1:pin2+hM2_2], w2, N2) # compute dft #-----transformation----- mX2smooth = resample(np.maximum(-200, mX2), (int)(mX2.size*smoothf))# smooth spectrum of second sound <-- fixed mX2 = resample(mX2smooth, mX1.size) # generate back the same size spectrum mY = balancef * mX2 + (1-balancef) * mX1 # generate output spectrum #-----synthesis----- y[pin1-hM1_1:pin1+hM1_2] += H1*DFT.dftSynth(mY, pX1, M1) # overlap-add to generate output sound pin1 += H1 # advance sound pointer pin2 += H2 # advance sound pointer y = np.delete(y, range(hM1_2)) # delete half of first window which was added in stftAnal y = np.delete(y, range(y.size-hM1_1, y.size)) # add zeros at the end to analyze last sample return y
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) # length of x w = get_window('hamming', M) # window outputScaleFactor = sum(w) # outputScaleFactor - ? mX, pX = dftAnal(x,w,N) # dftAnal gets magintude (in dB) and phase y = dftSynth(mX,pX, w.size) * outputScaleFactor # Resynthesize binsToFilter = np.ceil(70.0 * N / fs) # 70Hz * period(second/H) * FFT Size (part of FFT to use) mX[ : binsToFilter + 1 ] = -120 # all parts of FFT become -120dB ( + 1 is because [:something] works with the size and not index ) yfilt = dftSynth(mX,pX, w.size) * outputScaleFactor # resynth with new bin Values return (y,yfilt)
def stftMorph(x1, x2, fs, w1, N1, w2, N2, H1, smoothf, balancef): """ Morph of two sounds using the STFT x1, x2: input sounds, fs: sampling rate w1, w2: analysis windows, N1, N2: FFT sizes, H1: hop size smoothf: smooth factor of sound 2, bigger than 0 to max of 1, where 1 is no smothing, balancef: balance between the 2 sounds, from 0 to 1, where 0 is sound 1 and 1 is sound 2 returns y: output sound """ if (N2/2*smoothf < 3): # raise exception if decimation factor too small raise ValueError("Smooth factor too small") if (smoothf > 1): # raise exception if decimation factor too big raise ValueError("Smooth factor above 1") if (balancef > 1 or balancef < 0): # raise exception if balancef outside 0-1 raise ValueError("Balance factor outside range") if (H1 <= 0): # raise error if hop size 0 or negative raise ValueError("Hop size (H1) smaller or equal to 0") M1 = w1.size # size of analysis window hM1_1 = int(math.floor((M1+1)/2)) # half analysis window size by rounding hM1_2 = int(math.floor(M1/2)) # half analysis window size by floor L = int(x1.size/H1) # number of frames for x1 x1 = np.append(np.zeros(hM1_2),x1) # add zeros at beginning to center first window at sample 0 x1 = np.append(x1,np.zeros(hM1_1)) # add zeros at the end to analyze last sample pin1 = hM1_1 # initialize sound pointer in middle of analysis window w1 = w1 / sum(w1) # normalize analysis window M2 = w2.size # size of analysis window hM2_1 = int(math.floor((M2+1)/2)) # half analysis window size by rounding hM2_2 = int(math.floor(M2/2)) # half analysis window size by floor2 H2 = int(x2.size/L) # hop size for second sound x2 = np.append(np.zeros(hM2_2),x2) # add zeros at beginning to center first window at sample 0 x2 = np.append(x2,np.zeros(hM2_1)) # add zeros at the end to analyze last sample pin2 = hM2_1 # initialize sound pointer in middle of analysis window y = np.zeros(x1.size) # initialize output array for l in range(L): #-----analysis----- mX1, pX1 = DFT.dftAnal(x1[pin1-hM1_1:pin1+hM1_2], w1, N1) # compute dft mX2, pX2 = DFT.dftAnal(x2[pin2-hM2_1:pin2+hM2_2], w2, N2) # compute dft #-----transformation----- mX2smooth = resample(np.maximum(-200, mX2), int(mX2.size*smoothf)) # smooth spectrum of second sound mX2 = resample(mX2smooth, mX1.size) # generate back the same size spectrum mY = balancef * mX2 + (1-balancef) * mX1 # generate output spectrum #-----synthesis----- y[pin1-hM1_1:pin1+hM1_2] += H1*DFT.dftSynth(mY, pX1, M1) # overlap-add to generate output sound pin1 += H1 # advance sound pointer pin2 += H2 # advance sound pointer y = np.delete(y, range(hM1_2)) # delete half of first window which was added in stftAnal y = np.delete(y, range(y.size-hM1_1, y.size)) # add zeros at the end to analyze last sample return y
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) mX, pX = dftAnal(x, w, N) mXfilter = mX.copy(); y = dftSynth(mX, pX, w.size) * outputScaleFactor #f(k) = fs*k/N: frequency in radian per second #70/((fs/2)/511 k = 70 #fk = int(np.ceil(k/((fs/2)/(float(N)/2 -1)))) # print fk #pXfilter[fk] = -120 #for i in range(M): # mXfilter[i] = -120 fk = np.ceil(k*fs/float(N)) for i in range(M): if((i-1)*fs/N <= k): mXfilter[i] = -120.0 yFilter = dftSynth(mXfilter, pX, w.size)*outputScaleFactor return y, yFilter#, mX, mXfilter, fk
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ attenuated_freq = 70.0 attenuation_value = -120 # DB M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) mX1, pX1 = dftAnal(x, w, N) bin_index = asu.calcBinValue(fs, N, attenuated_freq) mX2 = mX1.copy() mX2[:(bin_index + 1)] = attenuation_value """ compute the inverse dft of the spectrum y = DFT.dftSynth(mX, pX, w.size)*sum(w) """ y = dftSynth(mX1, pX1, w.size)*outputScaleFactor yfilt = dftSynth(mX2, pX1, w.size)*outputScaleFactor return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ attenuated_freq = 70.0 attenuation_value = -120 # DB M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) mX1, pX1 = dftAnal(x, w, N) bin_index = asu.calcBinValue(fs, N, attenuated_freq) mX2 = mX1.copy() mX2[:(bin_index + 1)] = attenuation_value """ compute the inverse dft of the spectrum y = DFT.dftSynth(mX, pX, w.size)*sum(w) """ y = dftSynth(mX1, pX1, w.size) * outputScaleFactor yfilt = dftSynth(mX2, pX1, w.size) * outputScaleFactor return (y, yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ print str(fs) + "---" + str(N) + "===" + str(len(x)) M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here # compute the dft of the sound fragment mX, pX = dftAnal(x, w, N) y = dftSynth(mX, pX, M)*outputScaleFactor # Filter - set the bins < 70Hz = 0 or -120dB # Note that DFT.Anal() returns the +ve side of the spectrum only nbin=np.ceil(N*70.0/fs) mX[:nbin+1]=-120 print "Number of Bins = " + str(nbin+1) nbin = 0 for k in range(0,len(mX)): f = np.ceil(k*fs/N) if(f <= 80.0): print "freq: " + str(f) + " Bin Index = " + str(k) nbin = nbin + 1 print "Number of Bins 2x = " + str(nbin) # compute the inverse dft of the spectrum yfilt = dftSynth(mX, pX, M)*outputScaleFactor return(y,yfilt)
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here # get magnitude and phase mX, pX = dftAnal(x, w, N) # systhesis of the original unaltered original signal y = dftSynth(mX, pX, w.size) * outputScaleFactor # calculate the nearset bin sup_freq = 70 num_bin = mX.size - 1 freq_each_bin = (0.5 * fs) / num_bin sup_freq_index = int(np.ceil(sup_freq / freq_each_bin)) # set -120dB lower than 70 hz mX[:sup_freq_index + 1] = -120 # systhesis of the filtered signal yfilt = dftSynth(mX, pX, w.size) * outputScaleFactor return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) ## Your code here mX, pX = dftAnal(x, w, N) y = dftSynth(mX, pX, w.size) * outputScaleFactor binw70 = int(np.ceil((70 * N) / fs)) #applying the filter mF = mX.copy() mF[:binw70 + 1] = -120.0 yfilt = dftSynth(mF, pX, w.size) * outputScaleFactor return y, yfilt
def suppressFreqDFTmodel(x, fs, N): """ Inputs: x (numpy array) = input signal of length M (odd) fs (float) = sampling frequency (Hz) N (positive integer) = FFT size Outputs: The function should return a tuple (y, yfilt) y (numpy array) = Output of the dftSynth() without filtering (M samples long) yfilt (numpy array) = Output of the dftSynth() with filtering (M samples long) The first few lines of the code have been written for you, do not modify it. """ M = len(x) w = get_window('hamming', M) outputScaleFactor = sum(w) div = 70./fs k = int(float(N)*div)+1 mX, pX = dftAnal(x, w, N) mX2 = mX.copy() mX2[:k+1] = -120.0 return outputScaleFactor*dftSynth(mX, pX, M), outputScaleFactor*dftSynth(mX2, pX, M)
def stftSynth(mY, pY, M, H) : # synthesis of a sound using the short-time fourier transform # mY: magnitude spectra, pY: phase spectra, M: window size, H: hop-size # returns y: output sound hM1 = int(math.floor((M+1)/2)) # half analysis window size by rounding hM2 = int(math.floor(M/2)) # half analysis window size by floor nFrames = mY[:,0].size # number of frames y = np.zeros(nFrames*H + hM1 + hM2) # initialize output array pin = hM1 for i in range(nFrames): # iterate over all frames y1 = DFT.dftSynth(mY[i,:], pY[i,:], M) # compute idft y[pin-hM1:pin+hM2] += H*y1 # overlap-add to generate output sound pin += H # advance sound pointer y = np.delete(y, range(hM2)) # delete half of first window which was added in stftAnal y = np.delete(y, range(y.size-hM1, y.size)) # add zeros at the end to analyze last sample return y
def stftMorph(x1, x2, fs, w1, N1, w2, N2, H1, smoothf, balancef): # morph of two sounds using the STFT # x1, x2: input sounds, fs: sampling rate # w1, w2: analysis windows, N1, N2: FFT sizes, H1: hop size # smoothf: smooth factor of sound 2, bigger than 0 to max of 1, where 1 is no smothing, # balancef: balance between the 2 sounds, from 0 to 1, where 0 is sound 1 and 1 is sound 2 # returns y: output sound M1 = w1.size # size of analysis window hM1_1 = int(math.floor((M1+1)/2)) # half analysis window size by rounding hM1_2 = int(math.floor(M1/2)) # half analysis window size by floor L = int(x1.size/H1) # number of frames for x1 x1 = np.append(np.zeros(hM1_2),x1) # add zeros at beginning to center first window at sample 0 x1 = np.append(x1,np.zeros(hM1_1)) # add zeros at the end to analyze last sample pin1 = hM1_1 # initialize sound pointer in middle of analysis window w1 = w1 / sum(w1) # normalize analysis window M2 = w2.size # size of analysis window hM2_1 = int(math.floor((M2+1)/2)) # half analysis window size by rounding hM2_2 = int(math.floor(M2/2)) # half analysis window size by floor2 H2 = int(x2.size/L) # hop size for second sound x2 = np.append(np.zeros(hM2_2),x2) # add zeros at beginning to center first window at sample 0 x2 = np.append(x2,np.zeros(hM2_1)) # add zeros at the end to analyze last sample pin2 = hM2_1 # initialize sound pointer in middle of analysis window y = np.zeros(x1.size) # initialize output array for l in range(L): #-----analysis----- mX1, pX1 = DFT.dftAnal(x1[pin1-hM1_1:pin1+hM1_2], w1, N1) # compute dft mX2, pX2 = DFT.dftAnal(x2[pin2-hM2_1:pin2+hM2_2], w2, N2) # compute dft #-----transformation----- mX2smooth = resample(np.maximum(-200, mX2), mX2.size*smoothf) # smooth spectrum of second sound mX2 = resample(mX2smooth, N2/2) mY = balancef * mX2 + (1-balancef) * mX1 # generate output spectrum #-----synthesis----- y[pin1-hM1_1:pin1+hM1_2] += H1*DFT.dftSynth(mY, pX1, M1) # overlap-add to generate output sound pin1 += H1 # advance sound pointer pin2 += H2 # advance sound pointer y = np.delete(y, range(hM1_2)) # delete half of first window which was added in stftAnal y = np.delete(y, range(y.size-hM1_1, y.size)) # add zeros at the end to analyze last sample return y
def main(inputFile = '../../sounds/piano.wav', window = 'blackman', M = 511, N = 1024, time = .2): # ------- analysis parameters ------------------- # inputFile: input sound file (monophonic with sampling rate of 44100) # window: analysis window type (choice of rectangular, hanning, hamming, blackman, blackmanharris) # M: analysis window size (odd integer value) # N: fft size (power of two, bigger or equal than than M) # time: time to start analysis (in seconds) # --------- computation ----------------- # read input sound (monophonic with sampling rate of 44100) (fs, x) = UF.wavread(inputFile) # compute analysis window w = get_window(window, M) # get a fragment of the input sound x1 = x[int(time*fs):int(time*fs)+M] # compute the dft of the sound fragment mX, pX = DFT.dftAnal(x1, w, N) # compute the inverse dft of the spectrum y = DFT.dftSynth(mX, pX, w.size)*sum(w) # --------- plotting -------------------- # create figure plt.figure(figsize=(9.5, 7)) # plot the sound fragment plt.subplot(4,1,1) plt.plot(time + np.arange(M)/float(fs), x1) plt.axis([time, time + M/float(fs), min(x1), max(x1)]) plt.ylabel('amplitude') plt.xlabel('time (sec)') plt.title('input sound: x') # plot the magnitude spectrum plt.subplot(4,1,2) plt.plot((fs/2.0)*np.arange(N/2)/float(N/2), mX, 'r') plt.axis([0, fs/2.0, min(mX), max(mX)]) plt.title ('magnitude spectrum: mX') plt.ylabel('amplitude (dB)') plt.xlabel('frequency (Hz)') # plot the phase spectrum plt.subplot(4,1,3) plt.plot((fs/2.0)*np.arange(N/2)/float(N/2), pX, 'c') plt.axis([0, fs/2.0, min(pX), max(pX)]) plt.title ('phase spectrum: pX') plt.ylabel('phase (radians)') plt.xlabel('frequency (Hz)') # plot the sound resulting from the inverse dft plt.subplot(4,1,4) plt.plot(time + np.arange(M)/float(fs), y) plt.axis([time, time + M/float(fs), min(y), max(y)]) plt.ylabel('amplitude') plt.xlabel('time (sec)') plt.title('output sound: y') plt.tight_layout() plt.show()
import numpy as np from scipy.signal import get_window import os, sys sys.path.append( os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../software/models/')) import utilFunctions as UF import dftModel as DFT (fs, x) = UF.wavread('../../sounds/piano.wav') M = 511 w = get_window('hamming', M) time = .2 x1 = x[int(time * fs):int(time * fs) + M] N = 1024 mX, pX = DFT.dftAnal(x1, w, N) y = DFT.dftSynth(mX, pX, w.size) * sum(w)
filt[startBin:startBin+nBins] = bandpass mY = mX + filt plt.subplot(323) plt.plot(fs*np.arange(N/2)/float(N/2), mX, 'r', lw=1.5, label = 'mX') plt.plot(fs*np.arange(N/2)/float(N/2), filt+max(mX), 'k', lw=1.5, label='filter') plt.legend(prop={'size':10}) plt.axis([0,fs/4.0,-90,max(mX)+2]) plt.title('mX + filter') plt.subplot(325) plt.plot(fs*np.arange(N/2)/float(N/2), pX, 'c', lw=1.5) plt.axis([0,fs/4.0,min(pX),8]) plt.title('pX') y = DFT.dftSynth(mY, pX, N)*sum(np.hamming(N)) mY1, pY = DFT.dftAnal(y, np.hamming(N), N) plt.subplot(322) plt.plot(np.arange(N)/float(fs), y, 'b') plt.axis([0, float(N)/fs, min(y), max(y)]) plt.title('y') plt.subplot(324) plt.plot(fs*np.arange(N/2)/float(N/2), mY1, 'r', lw=1.5) plt.axis([0,fs/4.0,-90,max(mY1)+2]) plt.title('mY') plt.subplot(326) plt.plot(fs*np.arange(N/2)/float(N/2), pY, 'c', lw=1.5) plt.axis([0,fs/4.0,min(pY),8]) plt.title('pY')
import matplotlib.pyplot as plt import numpy as np import sys sys.path.append('../../../software/models/') import dftModel as DFT import math k0 = 8.5 N = 64 w = np.ones(N) x = np.cos(2*np.pi*k0/N*np.arange(-N/2,N/2)) mX, pX = DFT.dftAnal(x, w, N) y = DFT.dftSynth(mX, pX, N) plt.figure(1, figsize=(9.5, 5)) plt.subplot(311) plt.title('positive freq. magnitude spectrum in dB: mX') plt.plot(np.arange(mX.size), mX, 'r', lw=1.5) plt.axis([0,mX.size, min(mX), max(mX)+1]) plt.subplot(312) plt.title('positive freq. phase spectrum: pX') plt.plot(np.arange(pX.size), pX, 'c', lw=1.5) plt.axis([0, pX.size,-np.pi,np.pi]) plt.subplot(313) plt.title('inverse spectrum: IDFT(X)') plt.plot(np.arange(-N/2, N/2), y,'b', lw=1.5) plt.axis([-N/2,N/2-1,min(y), max(y)])
import numpy as np from scipy.signal import get_window, resample import math import sys, os, time sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../software/models/')) import utilFunctions as UF import dftModel as DFT (fs, x1) = UF.wavread('../sounds/rain.wav') (fs, x2) = UF.wavread('../sounds/soprano-E4.wav') M = N = 512 w = get_window('hanning', M) x1w = x1[10000:10000+M]*w x2w = x2[10000:10000+M]*w mX1, pX1 = DFT.dftAnal(x1w, w, N) mX2, pX2 = DFT.dftAnal(x2w, w, N) smoothf = .2 mX2smooth1 = resample(np.maximum(-200, mX2), mX2.size*smoothf) mX2smooth2 = resample(mX2smooth1, N/2) balancef = .7 mY = balancef * mX2smooth2 + (1-balancef) * mX1 y = DFT.dftSynth(mY, pX1, N)
M2 = w2.size # size of analysis window hM2_1 = int(math.floor((M2+1)/2)) # half analysis window size by rounding hM2_2 = int(math.floor(M2/2)) # half analysis window size by floor2 loc1 = 14843 loc2 = 9294 x1 = x1[loc1-hM1_1:loc1+hM1_2] x2 = x2[loc2-hM2_1:loc2+hM2_2] mX1, pX1 = DFT.dftAnal(x1, w1, N1) # compute dft mX2, pX2 = DFT.dftAnal(x2, w2, N2) # compute dft # morph mX2smooth = resample(np.maximum(-200, mX2), mX2.size*smoothf) # smooth spectrum of second sound mX2 = resample(mX2smooth, mX2.size) mY = balancef * mX2 + (1-balancef) * mX1 # generate output spectrum #-----synthesis----- y = DFT.dftSynth(mY, pX1, M1) * sum(w1) # overlap-add to generate output sound mY1, pY1 = DFT.dftAnal(y, w1, M1) # overlap-add to generate output sound plt.figure(1, figsize=(12, 9)) plt.subplot(321) plt.plot(np.arange(N1)/float(fs), x1*w1, 'b', lw=1.5) plt.axis([0, N1/float(fs), min(x1*w1), max(x1*w1)]) plt.title('x1 (orchestra.wav)') plt.subplot(323) plt.plot(fs*np.arange(mX1.size)/float(mX1.size), mX1-max(mX1), 'r', lw=1.5, label = 'mX1') plt.plot(fs*np.arange(mX2.size)/float(mX2.size), mX2-max(mX2), 'k', lw=1.5, label='mX2') plt.legend(prop={'size':10}) plt.axis([0,fs/4.0,-70,2]) plt.title('mX1 + mX2 (speech-male.wav)')
import numpy as np from scipy.signal import get_window import sys sys.path.append('../../software/models/') from dftModel import dftAnal, dftSynth x = np.arange(10) fs = 100000 M = x.size w = get_window('hamming', M) N = 1024 mX, pX = dftAnal(x, w, N) y = dftSynth(mX, pX, M) * sum(w)
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../../software/models/")) import dftModel as DFT import utilFunctions as UF M = 255 N = 4096 hM = int(M / 2.0) fs = 44100 f0 = 5000 A0 = 0.9 ph = 1.5 t = np.arange(-hM, hM + 1) / float(fs) x = A0 * np.cos(2 * np.pi * f0 * t + ph) w = hamming(255) mX, pX = DFT.dftAnal(x, w, N) y = DFT.dftSynth(mX, pX, M) * sum(w) freqaxis = fs * np.arange(0, N / 2) / float(N) taxis = np.arange(N) / float(fs) plt.figure(1, figsize=(9, 5)) plt.subplot(3, 2, 1) plt.plot(freqaxis, mX, "r", lw=1.5) plt.axis([0, fs / 2, -110, 0]) plt.title("mW1; Hamming") plt.subplot(3, 2, 3) plt.plot(freqaxis, pX, "c", lw=1.5) plt.axis([0, fs / 2, min(pX), max(pX)]) plt.title("pW1; Hamming") plt.subplot(3, 2, 5)
import numpy as np from scipy.signal import get_window, resample import math import sys, os, time sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../software/models/')) import utilFunctions as UF import dftModel as DFT fs, x = UF.wavread('../../sounds/oboe-A4.wav') M = N = 512 w = get_window('hanning', M) xw = x[10000:10000+M]*w filter = get_window('hamming', 30) * -60 mX, pX = DFT.dftAnal(xw, w, N) centerbin = 40 mY = np.copy(mX) mY[centerbin-15:centerbin+15] = mY[centerbin-15:centerbin+15] + filter y = DFT.dftSynth(mY, pX, N) * sum(w)
import numpy as np from scipy.signal import get_window import os, sys sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../software/models')) import utilFunctions as UF import dftModel as DFT (fs, x) = UF.wavread('../sounds/piano.wav') M = 511 w = get_window('hamming', M) time = .2 x1 = x[int(time*fs):int(time*fs)+M] N = 1024 mX, pX = DFT.dftAnal(x1, w, N) y = DFT.dftSynth(mX, pX, w.size) * sum(w)
def main(inputFile = '../../sounds/piano.wav', window = 'blackman', M = 511, N = 1024, time = .2): """ inputFile: input sound file (monophonic with sampling rate of 44100) window: analysis window type (choice of rectangular, hanning, hamming, blackman, blackmanharris) M: analysis window size (odd integer value) N: fft size (power of two, bigger or equal than than M) time: time to start analysis (in seconds) """ # read input sound (monophonic with sampling rate of 44100) fs, x = UF.wavread(inputFile) # compute analysis window w = get_window(window, M) # get a fragment of the input sound of size M sample = int(time*fs) if (sample+M >= x.size or sample < 0): # raise error if time outside of sound raise ValueError("Time outside sound boundaries") x1 = x[sample:sample+M] # compute the dft of the sound fragment mX, pX = DFT.dftAnal(x1, w, N) # compute the inverse dft of the spectrum y = DFT.dftSynth(mX, pX, w.size)*sum(w) # create figure plt.figure(figsize=(12, 9)) # plot the sound fragment plt.subplot(4,1,1) plt.plot(time + np.arange(M)/float(fs), x1) plt.axis([time, time + M/float(fs), min(x1), max(x1)]) plt.ylabel('amplitude') plt.xlabel('time (sec)') plt.title('input sound: x') # plot the magnitude spectrum plt.subplot(4,1,2) plt.plot(float(fs)*np.arange(mX.size)/float(N), mX, 'r') plt.axis([0, fs/2.0, min(mX), max(mX)]) plt.title ('magnitude spectrum: mX') plt.ylabel('amplitude (dB)') plt.xlabel('frequency (Hz)') # plot the phase spectrum plt.subplot(4,1,3) plt.plot(float(fs)*np.arange(pX.size)/float(N), pX, 'c') plt.axis([0, fs/2.0, min(pX), max(pX)]) plt.title ('phase spectrum: pX') plt.ylabel('phase (radians)') plt.xlabel('frequency (Hz)') # plot the sound resulting from the inverse dft plt.subplot(4,1,4) plt.plot(time + np.arange(M)/float(fs), y) plt.axis([time, time + M/float(fs), min(y), max(y)]) plt.ylabel('amplitude') plt.xlabel('time (sec)') plt.title('output sound: y') plt.tight_layout() plt.show()