Mercurial > hg > cm
view utils.py @ 0:5609fd93e935
First commit.
author | Carl Bussey <c.bussey@se10.qmul.ac.uk> |
---|---|
date | Sat, 25 Jan 2014 20:00:38 +0000 |
parents | |
children | dc43033a2c20 |
line wrap: on
line source
""" A utility module to assist cortical_model.py with general procedures, e.g., file reading and writing. Packaged dependencies: * erb.dat * outMidFir.dat External dependencies: * scipy * numpy * matplotlib """ import numpy as np import scipy.io.wavfile as wave import matplotlib.pyplot as plt import scipy.fftpack as fft def load_erb_data(): """ Loads and returns 39 ERB frequencies and bandwidths Parameters: NONE Returns: * fc (type: numpy array of floats) - a vector of length 39 with elements containing the centre frequencies of each ERB. * bw (type: numpy array of floats) - a vector of length 39 with elements containing the bandwidths of each ERB. Dependencies: * erb.dat (place in the same folder as utils.pyc) """ # read our data from a text file data=np.loadtxt("erb.dat",delimiter=",") # load centre frequencies from the first column into fc fc=np.array(data[:,0]) # load bandwidths from the second column into bw bw=np.array(data[:,1]) return fc,bw def load_outMidFir_coeff(): """ Loads and returns 39 ERB frequencies and bandwidths Parameters: NONE Returns: * b (type: numpy array of floats) - a vector of length 4097 containing the impulse response of the outer middle ear. Dependencies: * outMidFir.dat (place in the same folder as utils.pyc) """ b=np.loadtxt("outMidFir.dat", delimiter=",") return b def exp_sequence(start, stop, n, base=2): """ Creates a linear sequence with n points starting from start and ending at stop. For each element in the sequence, e, the output sequence is 2^e, generating an exponential sequence with base 2. Parameters: * start (type: numerical int) - determines the first element of the sequence, i.e., base^start. (Required) * stop (type: numerical int) - determines the last element of the sequence, i.e., base^stop. (Required) * n (type = numerical int) - determines the number of elements in the sequence. (Required) * base (type: numerical) - determines the exponential base. (Optional; Default = 2) Returns: * seq - the exponential sequence """ seq = [base**x for x in np.linspace(start,stop,n)] return seq def wavread(file): """ Reads the audio data from a wav file and converts it to floating point ranging from -1 to 1. Parameters: * file (type: string) - the name of the wav file to read from. (Required) Returns: * fs (type: numerical) - the sampling frequency of the signal storied in file * data (type: numpy array of floats) - the data of the signal stored in file normalised to an amplitude range of -1 to 1. """ fs,data = wave.read(file) data = np.array(int16_to_nfloat(data)) return fs,data def wavwrite(file, fs, data, precision = 16): """ Unnormalises the audio data to a specified integer precision and converts to an int, then writes the audio data to a wav file. (E.g., if 16-bit precision, then highest amplitude is equal to 2^16). Parameters: * file (type: string) - the name of the wav file to write to. (Required) * fs (type: numerical) - the sampling frequency of the signal. (Required) * data (type: array-like matrix of floats) - the signal data normalised from -1 to 1. The signal will be clipped if not in this range. (Required) * precision (type: numerical int)- the bit precision to store at. Can only be 16 or 32 bit, because that is all scipy allows. Returns: NONE TODO explore WAVE package to be allow for 24bit precision. """ data[data>1] = 1 data[data<-1] = -1 if(precision == 16): dtype = np.int16 elif(precision == 32): dtype = np.int32 else: print "Error: precision can only be 16 or 32 bit due to scipy package." return data = nfloat_to_int(data) wave.write(file, fs, data) return def plot_fft(x, xscale = 'log', yscale = 'log', show = True): """ Plots the fft of signal x. If the figure is not shown, the current plot is held to allow other plots to be added to the same figure. Parameters: * x (type: array-like matrix of floats) - the signal to be analysed. (Required) * xscale (type: string) - the scale of the frequency axis. Values are 'log' or 'linear'. (Optional; Default = 'log') * yscale (type: string) - the scale of the amplitude axis. Values are 'log' or 'linear'. (Optional; Default = 'log') * show (type: boolean) - specifies whether the figure should be shown. If False, the current plot will be held so other plots can be added to the figure. (Optional; Default = True) Returns: NONE """ if(xscale.lower() == "log"): plt.gca().set_xscale('log') if(xscale.lower() == "log"): plt.gca().set_yscale('log') fftx = np.absolute(fft.fft(x)) plt.plot(range(np.shape(x)[0]),fftx) if(show): plt.show() else: plt.hold(True) return def int_to_nfloat(input, type=np.float32): """ Convert integer with to floating point with a range from -1 to 1. Parameters: * input (type: array-like matrix of ints) - a signed integer array. (Required) dtype : the output datatype. (Optional; Default = np.float32) Returns: * y (type: array-like matrix of floats) - a float array normalised to a range of -1 to 1. """ input = np.array(input) assert input.dtype.kind == 'i', "'input' must be an array-like matrix of integers." type = np.dtype(type); inputdtype = np.dtype(type(input[0])) input = input.astype(type) input[input > 0] = input[input > 0] / np.iinfo(inputdtype).max input[input < 0] = input[input < 0] / -np.iinfo(inputdtype).min y = input return y def nfloat_to_int(input, type=np.int16): """ Convert a float array with amplitude ranging from -1 to 1 to a unnormalised signed integer array with specified precision. Parameters: * input (type: array-like matrix of floats) - a float array. (Required) dtype : the output datatype (also determines the precision). (Optional; Default = np.int16) Returns: * y (type: array-like matrix of ints) - an unnormalised to a range of -1 to 1. """ input = np.array(input) assert input.dtype.kind == 'f', "'input' must be an array of floats!" input[input > 0] = input[ input > 0 ] * np.iinfo(np.int16).max input[input < 0] = input[ input < 0 ] * -np.iinfo(np.int16).min y = input.astype(type) return y