def getpeaks(self, sample): from numarray import nonzero from numarray.fft import real_fft fft = abs(real_fft(sample)) # We compare each point to the point on either side - we must be # greater than both. # To do this, we left-shift and right-shift the array by one to # compare. peaks = nonzero((fft[1:-1] > fft[:-2]) * (fft[1:-1] > fft[2:])) if not len(peaks) or not len(peaks[0]): return () # Avoiding 'zip; sort; reverse' will give a big speedup. try: peakvals = zip(fft[1:-1].take(peaks)[0], peaks[0]) except: print("pppp", peaks) raise peakvals.sort(); peakvals.reverse() if len(peakvals) > 2: (val1,ind1),(val2,ind2),(val3,ind3) = peakvals[:3] # Peak 3 should be no more than 2/3 the size of peak 2 # For GSM/Speex mangled audio, peak3 is about 0.55 * peak2 # at the worst case. if val2 > 1.5*val3: # Add one to the index because we took [1:-1] before return (ind2+1,ind1+1) else: return () elif len(peakvals) == 2: (val2,ind2),(val1,ind1) = peakvals # Add one to the index because we took [1:-1] before return (ind2+1,ind1+1) else: (val1,ind1), = peakvals return (ind1,0)
def getpeaks(self, sample): from numarray import nonzero from numarray.fft import real_fft fft = abs(real_fft(sample)) # We compare each point to the point on either side - we must be # greater than both. # To do this, we left-shift and right-shift the array by one to # compare. peaks = nonzero((fft[1:-1] > fft[:-2]) * (fft[1:-1] > fft[2:])) if not len(peaks) or not len(peaks[0]): return () # Avoiding 'zip; sort; reverse' will give a big speedup. try: peakvals = zip(fft[1:-1].take(peaks)[0], peaks[0]) except: print "pppp", peaks raise peakvals.sort(); peakvals.reverse() if len(peakvals) > 2: (val1,ind1),(val2,ind2),(val3,ind3) = peakvals[:3] # Peak 3 should be no more than 2/3 the size of peak 2 # For GSM/Speex mangled audio, peak3 is about 0.55 * peak2 # at the worst case. if val2 > 1.5*val3: # Add one to the index because we took [1:-1] before return (ind2+1,ind1+1) else: return () elif len(peakvals) == 2: (val2,ind2),(val1,ind1) = peakvals # Add one to the index because we took [1:-1] before return (ind2+1,ind1+1) else: (val1,ind1), = peakvals return (ind1,0)
def multispec(data, doxs=1): """Compute power and cross spectra. power, cross = multispec(data[, doxs=1]) data is expected to be a numeric sequence, representing a binned light curve. If doxs is false or data is one-dimensional, the cross spectra will not be calculated as described below, and only the power spectra will be returned. If data is one-dimensional, its periodogram will be calculated. If data is two-dimensional, it will be interpreted as an array of one-dimensional curves. The periodogram will be calculated for each, and the cross spectra of all but the first relative to the first. If data has more than two dimensions, it will be interpreted as an array of two-dimensional sets, and each will be treated as described above.""" # Figure out what we've got. data = num.asarray(data) npoints = data.shape[-1] if len(data.shape) < 2: doxs = 0 # crunch transform = None if num.__name__ == 'numarray': transform = FFT.real_fft(data) else: transform = FFT.fft(data) conj = num.conjugate(transform) # Get the periodogram. power = transform * conj power = num.array(power.real) if doxs: # Calculate the cross spectrum. cross = transform[..., :1, :] * conj[..., 1:, :] return power, cross else: return power