def get_chirp_wave_data(freq, offset, duration=0.1, framerate=40000, noise_ratio=0): signal = thinkdsp.Chirp(start=freq * 0.5, end=1.5, amp=1.0) wave = signal.make_wave(duration=duration, start=0, framerate=framerate) if noise_ratio != 0: wave.ys += numpy.random.standard_normal(wave.ys.shape) * noise_ratio return wave.ys
def get_square_wave_data(freq, offset, duration=0.1, framerate=40000, noise_ratio=0): signal = thinkdsp.SquareSignal(freq=freq, amp=1.0, offset=offset) wave = signal.make_wave(duration=duration, start=0, framerate=framerate) if noise_ratio != 0: wave.ys += numpy.random.standard_normal(wave.ys.shape) * noise_ratio return wave.ys
def rest(duration): """Makes a rest of the given duration. duration: float seconds returns: Wave """ signal = SilentSignal() wave = signal.make_wave(duration) return wave
def get_sawtooth_square_wave(freq, offset, duration=0.1, framerate=40000): signal_sawtooth = thinkdsp.SawtoothSignal(freq=freq, amp=1.0, offset=offset) signal_square = thinkdsp.SquareSignal(freq=freq, amp=1.0, offset=offset + 2 * numpy.pi * 0.2) components = [signal_sawtooth, signal_square] signal = thinkdsp.SumSignal(*components) wave = signal.make_wave(duration=duration, start=0, framerate=40000) wave.ys = wave.ys / len(components) # normalization return wave.ys
def cos_wave(freq, duration=1, offset=0): """Makes a cosine wave with the given parameters. freq: float cycles per second duration: float seconds offset: float radians returns: Wave """ signal = CosSignal(freq, offset=offset) wave = signal.make_wave(duration) return wave
def make_chord(midi_nums, duration, sig_cons=CosSignal, framerate=11025): """Make a chord with the given duration. midi_nums: sequence of int MIDI note numbers duration: float seconds sig_cons: Signal constructor function framerate: int frames per second returns: Wave """ freqs = [midi_to_freq(num) for num in midi_nums] signal = sum(sig_cons(freq) for freq in freqs) wave = signal.make_wave(duration, framerate=framerate) wave.apodize() return wave
def make_note(midi_num, duration, sig_cons=CosSignal, framerate=11025): """Make a MIDI note with the given duration. midi_num: int MIDI note number duration: float seconds sig_cons: Signal constructor function framerate: int frames per second returns: Wave """ freq = midi_to_freq(midi_num) signal = sig_cons(freq) wave = signal.make_wave(duration, framerate=framerate) wave.apodize() return wave
def plot_gaussian(): """Makes a plot showing the effect of convolution with a boxcar window. """ # start with a square signal signal = thinkdsp.SquareSignal(freq=440) wave = signal.make_wave(duration=1, framerate=44100) spectrum = wave.make_spectrum() # and a boxcar window boxcar = numpy.ones(11) boxcar /= sum(boxcar) # and a gaussian window gaussian = scipy.signal.gaussian(M=11, std=2) gaussian /= sum(gaussian) thinkplot.preplot(2) thinkplot.plot(boxcar, label='boxcar') thinkplot.plot(gaussian, label='Gaussian') thinkplot.config(xlabel='index', ylabel='amplitude') thinkplot.save(root='convolution7') ys = numpy.convolve(wave.ys, gaussian, mode='same') smooth = thinkdsp.Wave(ys, framerate=wave.framerate) spectrum2 = smooth.make_spectrum() # plot the ratio of the original and smoothed spectrum amps = spectrum.amps amps2 = spectrum2.amps ratio = amps2 / amps ratio[amps < 560] = 0 # plot the same ratio along with the FFT of the window padded = zero_pad(gaussian, len(wave)) dft_gaussian = numpy.fft.rfft(padded) thinkplot.plot(abs(dft_gaussian), color='0.7', label='Gaussian filter') thinkplot.plot(ratio, label='amplitude ratio') thinkplot.config(xlabel='frequency (Hz)', ylabel='amplitude ratio', xlim=[0, 22050], legend=False) thinkplot.save(root='convolution8')
def plot_gaussian(): """Makes a plot showing the effect of convolution with a boxcar window. """ # start with a square signal signal = thinkdsp.SquareSignal(freq=440) wave = signal.make_wave(duration=1, framerate=44100) spectrum = wave.make_spectrum() # and a boxcar window boxcar = np.ones(11) boxcar /= sum(boxcar) # and a gaussian window gaussian = scipy.signal.gaussian(M=11, std=2) gaussian /= sum(gaussian) thinkplot.preplot(2) thinkplot.plot(boxcar, label='boxcar') thinkplot.plot(gaussian, label='Gaussian') thinkplot.config(xlabel='Index', legend=True) thinkplot.save(root='convolution7') ys = np.convolve(wave.ys, gaussian, mode='same') smooth = thinkdsp.Wave(ys, framerate=wave.framerate) spectrum2 = smooth.make_spectrum() # plot the ratio of the original and smoothed spectrum amps = spectrum.amps amps2 = spectrum2.amps ratio = amps2 / amps ratio[amps<560] = 0 # plot the same ratio along with the FFT of the window padded = thinkdsp.zero_pad(gaussian, len(wave)) dft_gaussian = np.fft.rfft(padded) thinkplot.plot(abs(dft_gaussian), color=GRAY, label='Gaussian filter') thinkplot.plot(ratio, label='amplitude ratio') thinkplot.config(xlabel='Frequency (Hz)', ylabel='Amplitude ratio', xlim=[0, 22050]) thinkplot.save(root='convolution8')
def make_wave(self, duration=1, start=0, framerate=11025): """Makes a Wave object. duration: float seconds start: float seconds framerate: int frames per second returns: Wave """ signal = UncorrelatedUniformNoise() wave = signal.make_wave(duration, start, framerate) spectrum = wave.make_spectrum() spectrum.pink_filter(beta=self.beta) wave2 = spectrum.make_wave() wave2.unbias() wave2.normalize(self.amp) return wave2
def plot_gaussian(): """Makes a plot showing the effect of convolution with a boxcar window. """ # start with a square signal signal = thinkdsp.SquareSignal(freq=440) wave = signal.make_wave(duration=1, framerate=44100) spectrum = wave.make_spectrum() # and a boxcar window boxcar = numpy.ones(11) boxcar /= sum(boxcar) # and a gaussian window gaussian = scipy.signal.gaussian(M=11, std=2) gaussian /= sum(gaussian) thinkplot.preplot(2) thinkplot.plot(boxcar, label="boxcar") thinkplot.plot(gaussian, label="Gaussian") thinkplot.config(xlabel="index", ylabel="amplitude") thinkplot.save(root="convolution7") ys = numpy.convolve(wave.ys, gaussian, mode="same") smooth = thinkdsp.Wave(ys, framerate=wave.framerate) spectrum2 = smooth.make_spectrum() # plot the ratio of the original and smoothed spectrum amps = spectrum.amps amps2 = spectrum2.amps ratio = amps2 / amps ratio[amps < 560] = 0 # plot the same ratio along with the FFT of the window padded = zero_pad(gaussian, len(wave)) dft_gaussian = numpy.fft.rfft(padded) thinkplot.plot(abs(dft_gaussian), color="0.7", label="Gaussian filter") thinkplot.plot(ratio, label="amplitude ratio") thinkplot.config(xlabel="frequency (Hz)", ylabel="amplitude ratio", xlim=[0, 22050], legend=False) thinkplot.save(root="convolution8")
def plot_filter(M=11, std=2): signal = thinkdsp.SquareSignal(freq=440) wave = signal.make_wave(duration=1, framerate=44100) spectrum = wave.make_spectrum() gaussian = scipy.signal.gaussian(M=M, std=std) gaussian /= sum(gaussian) high = gaussian.max() thinkplot.preplot(cols=2) thinkplot.plot(gaussian) thinkplot.config(xlabel='Index', ylabel='Window', xlim=[0, len(gaussian) - 1], ylim=[0, 1.1 * high]) ys = np.convolve(wave.ys, gaussian, mode='same') smooth = thinkdsp.Wave(ys, framerate=wave.framerate) spectrum2 = smooth.make_spectrum() # plot the ratio of the original and smoothed spectrum amps = spectrum.amps amps2 = spectrum2.amps ratio = amps2 / amps ratio[amps < 560] = 0 # plot the same ratio along with the FFT of the window padded = thinkdsp.zero_pad(gaussian, len(wave)) dft_gaussian = np.fft.rfft(padded) thinkplot.subplot(2) thinkplot.plot(abs(dft_gaussian), color=GRAY, label='Gaussian filter') thinkplot.plot(ratio, label='amplitude ratio') thinkplot.show(xlabel='Frequency (Hz)', ylabel='Amplitude ratio', xlim=[0, 22050], ylim=[0, 1.05])
import numpy as np import pandas as pd import scipy.signal np.set_printoptions(precision=3, suppress=True) # In[2]: PI2 = 2 * np.pi GRAY = '0.7' # In[3]: signal = thinkdsp.SquareSignal(freq=440) wave = signal.make_wave(duration=1, framerate=4400) segment = wave.segment(duration=0.01) # In[4]: window = np.ones(11) window /= sum(window) # In[5]: ys = segment.ys N = len(ys) padded = thinkdsp.zero_pad(window, N) # In[6]:
class TromboneGliss(Chirp): def evaluate(self, ts): f1, f2=1.0/self.start,1.0/self.end lengths=np.linspace(f1,f2,len(ts)) freqs=1/lengths dts=np.diff(ts,prepend=0) dphis=PI2*freqs*dts phases=np.cumsum(dphis) ys=self.amp*np.cos(phases) return ys low=262 high=349 signal=TromboneGliss(high,low) wave1=signal.make_wave(duration=1) wave1.apodize() wave1.write(filename="output3-5-1.wav") signal=TromboneGliss(high,low) wave2=signal.make_wave(duration=1) wave2.apodize() wave2.write(filename="output3-5-2.wav") wave=wave1|wave2 wave.write(filename="output3-5-3.wav") sp=wave.make_spectrum(1024) sp.plot(high=1000) plt.title("频率") plt.show()
import thinkdsp import matplotlib.pyplot as plt import numpy as np from scipy import signal import wave plt.rcParams['font.sans-serif'] = ['SimHei'] #图表上可以显示中文 plt.rcParams['axes.unicode_minus'] = False #图表上可以显示负号 PI2 = 2 * np.pi class SawtoothChirp(Chirp): def evaluate(self, ts): freqs = np.linspace(self.start, self.end, len(ts)) dts = np.diff(ts, prepend=0) dphis = PI2 * freqs * dts phases = np.cumsum(dphis) cycles = phases / PI2 frac, _ = np.modf(cycles) ys = normalize(unbias(frac), self.amp) return ys signal = SawtoothChirp(start=2500, end=3000) wave = signal.make_wave(duration=1, framerate=20000) wave.write(filename="output3-3.wav") wave.make_spectrum().plot() plt.title("频率") plt.show()
def plot_boxcar(): """Makes a plot showing the effect of convolution with a boxcar window. """ # start with a square signal signal = thinkdsp.SquareSignal(freq=440) wave = signal.make_wave(duration=1, framerate=44100) # and a boxcar window window = numpy.ones(11) window /= sum(window) # select a short segment of the wave segment = wave.segment(duration=0.01) # and pad with window out to the length of the array padded = zero_pad(window, len(segment)) # compute the first element of the smoothed signal prod = padded * segment.ys print(sum(prod)) # compute the rest of the smoothed signal smoothed = numpy.zeros_like(segment.ys) rolled = padded for i in range(len(segment.ys)): smoothed[i] = sum(rolled * segment.ys) rolled = numpy.roll(rolled, 1) # plot the results segment.plot(color="0.7") smooth = thinkdsp.Wave(smoothed, framerate=wave.framerate) smooth.plot() thinkplot.config(ylim=[-1.05, 1.05], legend=False) thinkplot.save(root="convolution2") # compute the same thing using numpy.convolve segment.plot(color="0.7") ys = numpy.convolve(segment.ys, window, mode="valid") smooth2 = thinkdsp.Wave(ys, framerate=wave.framerate) smooth2.plot() thinkplot.config(ylim=[-1.05, 1.05], legend=False) thinkplot.save(root="convolution3") # plot the spectrum before and after smoothing spectrum = wave.make_spectrum() spectrum.plot(color="0.7") ys = numpy.convolve(wave.ys, window, mode="same") smooth = thinkdsp.Wave(ys, framerate=wave.framerate) spectrum2 = smooth.make_spectrum() spectrum2.plot() thinkplot.config(xlabel="frequency (Hz)", ylabel="amplitude", xlim=[0, 22050], legend=False) thinkplot.save(root="convolution4") # plot the ratio of the original and smoothed spectrum amps = spectrum.amps amps2 = spectrum2.amps ratio = amps2 / amps ratio[amps < 560] = 0 thinkplot.plot(ratio) thinkplot.config(xlabel="frequency (Hz)", ylabel="amplitude ratio", xlim=[0, 22050], legend=False) thinkplot.save(root="convolution5") # plot the same ratio along with the FFT of the window padded = zero_pad(window, len(wave)) dft_window = numpy.fft.rfft(padded) thinkplot.plot(abs(dft_window), color="0.7", label="boxcar filter") thinkplot.plot(ratio, label="amplitude ratio") thinkplot.config(xlabel="frequency (Hz)", ylabel="amplitude ratio", xlim=[0, 22050], legend=False) thinkplot.save(root="convolution6")
def plot_boxcar(): """Makes a plot showing the effect of convolution with a boxcar window. """ # start with a square signal signal = thinkdsp.SquareSignal(freq=440) wave = signal.make_wave(duration=1, framerate=44100) # and a boxcar window window = np.ones(11) window /= sum(window) # select a short segment of the wave segment = wave.segment(duration=0.01) # and pad with window out to the length of the array N = len(segment) padded = thinkdsp.zero_pad(window, N) # compute the first element of the smoothed signal prod = padded * segment.ys print(sum(prod)) # compute the rest of the smoothed signal smoothed = np.zeros(N) rolled = padded for i in range(N): smoothed[i] = sum(rolled * segment.ys) rolled = np.roll(rolled, 1) # plot the results segment.plot(color=GRAY) smooth = thinkdsp.Wave(smoothed, framerate=wave.framerate) smooth.plot() thinkplot.config(xlabel='Time(s)', ylim=[-1.05, 1.05]) thinkplot.save(root='convolution2') # compute the same thing using np.convolve segment.plot(color=GRAY) ys = np.convolve(segment.ys, window, mode='valid') smooth2 = thinkdsp.Wave(ys, framerate=wave.framerate) smooth2.plot() thinkplot.config(xlabel='Time(s)', ylim=[-1.05, 1.05]) thinkplot.save(root='convolution3') # plot the spectrum before and after smoothing spectrum = wave.make_spectrum() spectrum.plot(color=GRAY) ys = np.convolve(wave.ys, window, mode='same') smooth = thinkdsp.Wave(ys, framerate=wave.framerate) spectrum2 = smooth.make_spectrum() spectrum2.plot() thinkplot.config(xlabel='Frequency (Hz)', ylabel='Amplitude', xlim=[0, 22050]) thinkplot.save(root='convolution4') # plot the ratio of the original and smoothed spectrum amps = spectrum.amps amps2 = spectrum2.amps ratio = amps2 / amps ratio[amps<560] = 0 thinkplot.plot(ratio) thinkplot.config(xlabel='Frequency (Hz)', ylabel='Amplitude ratio', xlim=[0, 22050]) thinkplot.save(root='convolution5') # plot the same ratio along with the FFT of the window padded = thinkdsp.zero_pad(window, len(wave)) dft_window = np.fft.rfft(padded) thinkplot.plot(abs(dft_window), color=GRAY, label='DFT(window)') thinkplot.plot(ratio, label='amplitude ratio') thinkplot.config(xlabel='Frequency (Hz)', ylabel='Amplitude ratio', xlim=[0, 22050]) thinkplot.save(root='convolution6')
import wave import thinkdsp import matplotlib.pyplot as plt import numpy as np from scipy import signal from thinkdsp import SinSignal, Spectrum, decorate from thinkdsp import Signal plt.rcParams['font.sans-serif']=['SimHei']#图表上可以显示中文 plt.rcParams['axes.unicode_minus']=False#图表上可以显示负号 signal=SinSignal(freq=440) duration=signal.period*30.25 wave=signal.make_wave(duration) for window_func in [np.bartlett,np.blackman,np.hanning,np.hamming]: wave=signal.make_wave(duration) wave.ys*=window_func(len(wave.ys)) Spectrum=wave.make_spectrum() Spectrum.plot(high=880,label=window_func) plt.title("频率") plt.show()
def get_cosine_wave(freq, offset, duration=0.1, framerate=40000): signal = thinkdsp.CosSignal(freq=freq, amp=1.0, offset=offset) wave = signal.make_wave(duration=duration, start=0, framerate=framerate) return wave.ys
from scipy.signal.spectral import periodogram import thinkdsp import matplotlib.pyplot as plt import numpy as np from scipy import signal plt.rcParams['font.sans-serif'] = ['SimHei'] #图表上可以显示中文 plt.rcParams['axes.unicode_minus'] = False #图表上可以显示负号 signal = thinkdsp.SquareSignal(1100) duration = 0.5 wave = signal.make_wave(duration, framerate=10000) plt.subplot(1, 3, 1) plt.title('1100HZ方波') wave.plot() wave.write(filename='output2-3.wav') spectrum = wave.make_spectrum() #spectrum=spectrum.mak plt.subplot(1, 3, 3) plt.title('采样后频谱') spectrum.plot() plt.show()
def plot_boxcar(): """Makes a plot showing the effect of convolution with a boxcar window. """ # start with a square signal signal = thinkdsp.SquareSignal(freq=440) wave = signal.make_wave(duration=1, framerate=44100) # and a boxcar window window = numpy.ones(11) window /= sum(window) # select a short segment of the wave segment = wave.segment(duration=0.01) # and pad with window out to the length of the array padded = zero_pad(window, len(segment)) # compute the first element of the smoothed signal prod = padded * segment.ys print(sum(prod)) # compute the rest of the smoothed signal smoothed = numpy.zeros_like(segment.ys) rolled = padded for i in range(len(segment.ys)): smoothed[i] = sum(rolled * segment.ys) rolled = numpy.roll(rolled, 1) # plot the results segment.plot(color='0.7') smooth = thinkdsp.Wave(smoothed, framerate=wave.framerate) smooth.plot() thinkplot.config(ylim=[-1.05, 1.05], legend=False) thinkplot.save(root='convolution2') # compute the same thing using numpy.convolve segment.plot(color='0.7') ys = numpy.convolve(segment.ys, window, mode='valid') smooth2 = thinkdsp.Wave(ys, framerate=wave.framerate) smooth2.plot() thinkplot.config(ylim=[-1.05, 1.05], legend=False) thinkplot.save(root='convolution3') # plot the spectrum before and after smoothing spectrum = wave.make_spectrum() spectrum.plot(color='0.7') ys = numpy.convolve(wave.ys, window, mode='same') smooth = thinkdsp.Wave(ys, framerate=wave.framerate) spectrum2 = smooth.make_spectrum() spectrum2.plot() thinkplot.config(xlabel='frequency (Hz)', ylabel='amplitude', xlim=[0, 22050], legend=False) thinkplot.save(root='convolution4') # plot the ratio of the original and smoothed spectrum amps = spectrum.amps amps2 = spectrum2.amps ratio = amps2 / amps ratio[amps < 560] = 0 thinkplot.plot(ratio) thinkplot.config(xlabel='frequency (Hz)', ylabel='amplitude ratio', xlim=[0, 22050], legend=False) thinkplot.save(root='convolution5') # plot the same ratio along with the FFT of the window padded = zero_pad(window, len(wave)) dft_window = numpy.fft.rfft(padded) thinkplot.plot(abs(dft_window), color='0.7', label='boxcar filter') thinkplot.plot(ratio, label='amplitude ratio') thinkplot.config(xlabel='frequency (Hz)', ylabel='amplitude ratio', xlim=[0, 22050], legend=False) thinkplot.save(root='convolution6')
import thinkdsp import matplotlib.pyplot as plt import numpy as np from scipy import signal plt.rcParams['font.sans-serif'] = ['SimHei'] #图表上可以显示中文 plt.rcParams['axes.unicode_minus'] = False #图表上可以显示负号 signal = thinkdsp.TriangleSignal(200) #200HZ的三角波 wave = signal.make_wave(duration=0.5, framerate=10000) #长度0.5,每秒10000次 period = signal.period segment = wave.segment(start=0, duration=period * 3) plt.subplot(2, 2, 1) plt.title('200HZ三角波') segment.plot() spectrum = wave.make_spectrum() plt.subplot(2, 2, 2) plt.title('三角波频谱') spectrum.plot() #锯齿波 signal1 = thinkdsp.SawtoothSignal(200) wave = signal1.make_wave(duration=0.5, framerate=10000) period = signal1.period segment = wave.segment(start=0, duration=period * 3) plt.subplot(2, 2, 3) plt.title('200HZ锯齿波') segment.plot() spectrum = wave.make_spectrum() plt.subplot(2, 2, 4)
PI2 = 2 * np.pi class SawtoothChirp(Chirp): def evaluate(self, ts): freqs = np.linspace(self.start, self.end, len(ts)) dts = np.diff(ts, prepend=0) dphis = PI2 * freqs * dts phases = np.cumsum(dphis) cycles = phases / PI2 frac, _ = np.modf(cycles) ys = normalize(unbias(frac), self.amp) return ys signal = SawtoothChirp(start=220, end=880) wave = signal.make_wave(duration=0.1, framerate=4000) wave.apodize() wave.write(filename="output3-2.wav") plt.subplot(1, 2, 1) plt.title("SawtoothChirp") wave.plot() sp = wave.make_spectrum(256) plt.subplot(1, 2, 2) sp.plot() plt.xlabel("时间") plt.ylabel("频率") plt.title("频谱") plt.show()