.. currentmodule:: brian .. index:: pair: example usage; cos pair: example usage; arcsinh pair: example usage; ControlFilterbank pair: example usage; sqrt pair: example usage; FunctionFilterbank pair: example usage; sinh pair: example usage; whitenoise pair: example usage; LinearFilterbank pair: example usage; sin pair: example usage; log .. _example-hears_time_varying_filter1: Example: time_varying_filter1 (hears) ===================================== This example implements a band pass filter whose center frequency is modulated by an Ornstein-Uhlenbeck. The white noise term used for this process is output by a FunctionFilterbank. The bandpass filter coefficients update is an example of how to use a :class:`~brian.hears.ControlFilterbank`. The bandpass filter is a basic biquadratic filter for which the Q factor and the center frequency must be given. The input is a white noise. :: from brian import * from brian.hears import * samplerate = 20*kHz SoundDuration = 300*ms sound = whitenoise(SoundDuration, samplerate).ramp() #number of frequency channel (here it must be one as a spectrogram of the #output is plotted) nchannels = 1 fc_init = 5000*Hz #initial center frequency of the band pass filter Q = 5 #quality factor of the band pass filter update_interval = 4 # the filter coefficients are updated every 4 samples #parameters of the Ornstein-Uhlenbeck process s_i = 1200*Hz tau_i = 100*ms mu_i = fc_init/tau_i sigma_i = sqrt(2)*s_i/sqrt(tau_i) deltaT = defaultclock.dt #this function is used in a FunctionFilterbank. It outputs a noise term that #will be later used by the controler to update the center frequency noise = lambda x: mu_i*deltaT+sigma_i*randn(1)*sqrt(deltaT) noise_generator = FunctionFilterbank(sound, noise) #this class will take as input the output of the noise generator and as target #the bandpass filter center frequency class CoeffController(object): def __init__(self, target): self.target = target self.deltaT = 1./samplerate self.BW = 2*arcsinh(1./2/Q)*1.44269 self.fc = fc_init def __call__(self, input): #the control variables are taken as the last of the buffer noise_term = input[-1,:] #update the center frequency by updateing the OU process self.fc = self.fc-self.fc/tau_i*self.deltaT+noise_term w0 = 2*pi*self.fc/samplerate #update the coefficient of the biquadratic filterbank alpha = sin(w0)*sinh(log(2)/2*self.BW*w0/sin(w0)) self.target.filt_b[:, 0, 0] = sin(w0)/2 self.target.filt_b[:, 1, 0] = 0 self.target.filt_b[:, 2, 0] = -sin(w0)/2 self.target.filt_a[:, 0, 0] = 1+alpha self.target.filt_a[:, 1, 0] = -2*cos(w0) self.target.filt_a[:, 2, 0] = 1-alpha # In the present example the time varying filter is a LinearFilterbank therefore #we must initialise the filter coefficients; the one used for the first buffer computation w0 = 2*pi*fc_init/samplerate BW = 2*arcsinh(1./2/Q)*1.44269 alpha = sin(w0)*sinh(log(2)/2*BW*w0/sin(w0)) filt_b = zeros((nchannels, 3, 1)) filt_a = zeros((nchannels, 3, 1)) filt_b[:, 0, 0] = sin(w0)/2 filt_b[:, 1, 0] = 0 filt_b[:, 2, 0] = -sin(w0)/2 filt_a[:, 0, 0] = 1+alpha filt_a[:, 1, 0] = -2*cos(w0) filt_a[:, 2, 0] = 1-alpha #the filter which will have time varying coefficients bandpass_filter = LinearFilterbank(sound, filt_b, filt_a) #the updater updater = CoeffController(bandpass_filter) #the controller. Remember it must be the last of the chain control = ControlFilterbank(bandpass_filter, noise_generator, bandpass_filter, updater, update_interval) time_varying_filter_mon = control.process() figure(1) pxx, freqs, bins, im = specgram(squeeze(time_varying_filter_mon), NFFT=256, Fs=samplerate, noverlap=240) imshow(flipud(pxx), aspect='auto') show()