def TakeBF(self, time, show=False, saveIm=False): """ Call signature example: BF = M.TakeBF(70) ----------------------------------------- Return the beat frequencia of signal to the given instant (time). Also is considered a mean of power spectrum of ten sweeps, to avoid some resolution problems. """ S_mean_K = 0.; S_mean_KA = 0.; i1 = self.NearSweep(time); i2 = i1 + int(self.SD.st * 1E-6 * self.SD.rate); # time elapsed to next sweep in milliseconds T_elapse = (self.SD.st + self.SD.si) * 1E-3; # mean of 10 spectrograms. for j in range(10): # K band S, f, t = mlab.specgram(self.SD.K[i1:i2], NFFT=self.nfft, Fs=self.SD.rate, noverlap=self.nfft-self.fft_step, pad_to=2**12); S_mean_K += S / 10; # Ka band S, f, t = mlab.specgram(self.SD.KA[i1:i2], NFFT=self.nfft, Fs=self.SD.rate, noverlap=self.nfft-self.fft_step, pad_to=2**12); S_mean_KA += S / 10; # update indexes to next sweep. i1 = self.NearSweep(time + T_elapse); i2 = i1 + int(self.SD.st * 1E-6 * self.SD.rate); T_elapse += (self.SD.st + self.SD.si) * 1E-3; # avoid useles frequency depends on the case if time < 10: limSup = np.where(f > 1.65E7)[0].min(); limInf = np.where(f < 0.65E7)[0].max(); else: limSup = np.where(f > 1.55E7)[0].min(); limInf = np.where(f < 0.35E7)[0].max(); # Take max line in spectrum. freqIndexK = S_mean_K[limInf:limSup].argmax(axis=0) + limInf; freqIndexKA = S_mean_KA[limInf:limSup].argmax(axis=0) + limInf; # return to default image inferior limite limSup = np.where(f > 1.55E7)[0].min(); limInf = np.where(f < 0.35E7)[0].max(); # Take frequency of max line. BF_K = f[freqIndexK]; BF_KA = f[freqIndexKA]; # remove overlap if it has. BF = np.concatenate([BF_K, BF_KA]); if (saveIm or show): S_K = S_mean_K[limInf:limSup]; S_KA = S_mean_KA[limInf:limSup]; f1 = f[limInf]; # Inferior figure limit f2 = f[limSup]; # superior figure limit self.__DrawImage(S_K, S_KA, time, f1, f2, BF, show, saveIm); return BF;
def test_specgram(self): for y, fstims in zip(self.y, self.fstimsall): Pxx1, freqs1, t1 = mlab.specgram(y, NFFT=self.NFFT, Fs=self.Fs, noverlap=self.noverlap, pad_to=self.pad_to, sides='default') Pxx1m = np.mean(Pxx1, axis=1) np.testing.assert_array_equal(freqs1, self.freqss) np.testing.assert_array_equal(t1, self.t) # since we are using a single freq, all time slices should be # about the same np.testing.assert_allclose(np.diff(Pxx1, axis=1).max(), 0, atol=1e-08) for fstim in fstims: i = np.abs(freqs1 - fstim).argmin() self.assertTrue(Pxx1m[i] > Pxx1m[i+1]) self.assertTrue(Pxx1m[i] > Pxx1m[i-1]) Pxx2, freqs2, t2 = mlab.specgram(y, NFFT=self.NFFT, Fs=self.Fs, noverlap=self.noverlap, pad_to=self.pad_to, sides='onesided') Pxx2m = np.mean(Pxx2, axis=1) np.testing.assert_array_equal(freqs2, self.freqss) np.testing.assert_array_equal(t2, self.t) np.testing.assert_allclose(np.diff(Pxx2, axis=1).max(), 0, atol=1e-08) for fstim in fstims: i = np.abs(freqs2 - fstim).argmin() self.assertTrue(Pxx2m[i] > Pxx2m[i+1]) self.assertTrue(Pxx2m[i] > Pxx2m[i-1]) Pxx3, freqs3, t3 = mlab.specgram(y, NFFT=self.NFFT, Fs=self.Fs, noverlap=self.noverlap, pad_to=self.pad_to, sides='twosided') Pxx3m = np.mean(Pxx3, axis=1) np.testing.assert_array_equal(freqs3, self.freqsd) np.testing.assert_array_equal(t3, self.t) np.testing.assert_allclose(np.diff(Pxx3, axis=1).max(), 0, atol=1e-08) for fstim in fstims: i = np.abs(freqs3 - fstim).argmin() self.assertTrue(Pxx3m[i] > Pxx3m[i+1]) self.assertTrue(Pxx3m[i] > Pxx3m[i-1])
def fingerprint(channel_samples, Fs=DEFAULT_FS, wsize=DEFAULT_WINDOW_SIZE, wratio=DEFAULT_OVERLAP_RATIO, fan_value=DEFAULT_FAN_VALUE, amp_min=DEFAULT_AMP_MIN): """ FFT the channel, loklsg transform output, find local maxima, then return locally sensitive hashes. """ # FFT the signal and extract frequency components arr2D = mlab.specgram( channel_samples, NFFT=wsize, Fs=Fs, window=mlab.window_hanning, noverlap=int(wsize * wratio))[0] # apply log transform since specgram() returns linear array np.seterr(all='ignore') arr2D = 10 * np.log10(arr2D) arr2D[arr2D == -np.inf] = 0 # replace infs with zeros # find local maxima local_maxima = get_2D_peaks(arr2D, plot=False, amp_min=amp_min) # return hashes return generate_hashes(local_maxima, fan_value=fan_value)
def get_fingerprints(X, ws=WINDOW_SIZE, sr=SAMPLE_RATE, si=SLIDE_INTERVAL, ns=NEIGHBOR_SIZE, thres=MIN_AMPLITUDE, fo=FAN_OUT): """ Calculate the fingerprints (hash values) of a given signal X. Return the fingerprints in term of (sha256, diff time). """ # apply fft to X and retrieve the spectrogram of X sg, freqs, t = specgram(X, NFFT=ws, Fs=sr, noverlap=si) # apply log transform to the spectrogram sg = 10 * log10(sg) # find the local maxima in neighborhood peaks = find_peaks(sg, ns, thres) # generate final fingerprints in form of (sha256, diff time) fingerprints = generate_fingerprints(peaks, fo) return fingerprints
def transform_one(row): row -= MIN row /= MAX spec = mlab.specgram(row, NFFT=256, Fs=16384)[0] spec = np.log(spec)#.ravel() #spec = ndimage.gaussian_filter(spec, 1) return spec
def simple_spectogram(df, meta): import numpy as np import pandas as pd from matplotlib.mlab import specgram def merge_two_dicts(x, y): z = x.copy() z.update(y) return z # extract numpy array from pandas.DataFrame data = np.asarray(df) spectrum, freqs, t = specgram(data.squeeze()) # Return value must be of a sequence of pandas.DataFrame df = pd.DataFrame(spectrum) # updata meta new_meta = {'spectogram_out': {'frequencies': freqs.tolist(), 'time_points': t.tolist()}} d = merge_two_dicts(meta.to_dict(), new_meta) meta = pd.DataFrame(d) return df, meta
def _energy_func(self, x, **kwargs): from matplotlib.mlab import specgram rval = sp.zeros_like(x) ns, nc = x.shape ov_samples = 0 offset = 0 if self.overlap == 1: ov_samples = self.nfft * 0.5 offset = self.nfft / 4 elif self.overlap == 2: ov_samples = self.nfft * 0.75 offset = self.nfft * 0.375 step = self.nfft - ov_samples for c in xrange(nc): psd_arr, freqs, times = specgram(x[:, c], NFFT=self.nfft, Fs=self.srate, noverlap=ov_samples) mask = freqs < self.cutoff_hz for b in xrange(len(times)): bin_s = b * step + offset bin_e = bin_s + step if self.en_func == 'mean_coeff': rval[bin_s:bin_e, c] = psd_arr[mask == True, b].mean() / psd_arr[mask == False, b].mean() elif self.en_func == 'max_coeff': rval[bin_s:bin_e, c] = psd_arr[mask == True, b].max() / psd_arr[mask == False, b].max() elif self.en_func == 'max_normed': rval[bin_s:bin_e, c] = psd_arr[mask == True, b].max() / psd_arr[:, b].sum(axis = 0) else: raise RuntimeError('Energy function does not exist!') return rval
def psd_eeg(data, **kwargs): for arg in kwargs: if arg == "NFFT": NFFT = int(kwargs[arg]) if arg == "dt": Fs = 1.0 / float(kwargs[arg]) if arg == "noverlap": noverlap = int(kwargs[arg]) px_list = [] print "PSD Computing..." for sample in range(data.shape[0]): for ch in range(data.shape[1]): eeg = data[sample, ch, :] [Pxx, freq, t] = specgram(eeg, NFFT=NFFT, noverlap=noverlap, Fs=Fs) px_list.append(Pxx) shape = px_list[0].shape pot = np.array(px_list) pot = pot.reshape(data.shape[0], data.shape[1], shape[0], -1) del px_list return [pot, freq]
def _do_fft(self): t = self.getp('t') v = self.getp('v') try: Fs = 1/(t[1] - t[0]) NFFT = self.getp('NFFT') detrend = detrends[self.getp('detrend')] window = windows[self.getp('window')] noverlap = self.getp('noverlap') sides = self.getp('sides') pad_to = self.getp('pad_to') if pad_to == 'none': pad_to = None z, y, x = mlab.specgram(v, NFFT=NFFT, Fs=Fs, detrend = detrend, window = window, noverlap = noverlap, pad_to=pad_to, sides = sides, scale_by_freq=None) self.setp("x", x + t[0]) self.setp("y", y) self.setp("z", z) except: traceback.print_exc() self.setp("x", None) self.setp("y", None) self.setp("z", None) return False return True
def calculate_specgram(self, nfft, noverlap, **kwargs): spec = mlab.specgram(self.audio, NFFT=nfft, Fs=self.framerate, noverlap=noverlap, **kwargs) self.specgram_nfft = nfft self.specgram_overlap = noverlap self.specgram = spec[0] self.specgram_freqs = spec[1] self.specgram_bins = spec[2]
def fingerprint( channel_samples, Fs=DEFAULT_FS, wsize=DEFAULT_WINDOW_SIZE, wratio=DEFAULT_OVERLAP_RATIO, fan_value=DEFAULT_FAN_VALUE, amp_min=DEFAULT_AMP_MIN, plot=False, ): """ FFT the channel, log transform output, find local maxima, then return locally sensitive hashes. """ # FFT the signal and extract frequency components # http://matplotlib.org/api/mlab_api.html#matplotlib.mlab.specgram # return of specgram is (spectrum, freqs, t) arr2D, freqs, times = mlab.specgram( channel_samples, NFFT=wsize, Fs=Fs, window=mlab.window_hanning, noverlap=int(wsize * wratio) ) # apply log transform since specgram() returns linear array arr2D = 10 * np.log10(arr2D) arr2D[arr2D == -np.inf] = 0 # replace infs with zeros # find local maxima local_maxima = get_2D_peaks(arr2D, plot=plot, amp_min=amp_min, freqs=freqs, times=times) # return hashes return generate_hashes(local_maxima, fan_value=fan_value)
def plot_specgram(ax, data, fs, nfft=256, noverlap=128, window='hann', cmap='jet', interpolation='bilinear', rasterized=True): if window not in SPECGRAM_WINDOWS: raise ValueError("Window not supported") elif window == "boxcar": mwindow = signal.boxcar(nfft) elif window == "hamming": mwindow = signal.hamming(nfft) elif window == "hann": mwindow = signal.hann(nfft) elif window == "bartlett": mwindow = signal.bartlett(nfft) elif window == "blackman": mwindow = signal.blackman(nfft) elif window == "blackmanharris": mwindow = signal.blackmanharris(nfft) specgram, freqs, time = mlab.specgram(data, NFFT=nfft, Fs=fs, window=mwindow, noverlap=noverlap) specgram = 10 * np.log10(specgram[1:, :]) specgram = np.flipud(specgram) freqs = freqs[1:] halfbin_time = (time[1] - time[0]) / 2.0 halfbin_freq = (freqs[1] - freqs[0]) / 2.0 extent = (time[0] - halfbin_time, time[-1] + halfbin_time, freqs[0] - halfbin_freq, freqs[-1] + halfbin_freq) ax.imshow(specgram, cmap=cmap, interpolation=interpolation, extent=extent, rasterized=rasterized) ax.axis('tight')
def load_spec(path): ''' Loads the spectrogram file that was saved by the function sess_spectrogram Input: path : either the absolute path for the spectrogram file or a list containing the cage ID, block number, and sess Output: P : MxN spectrogram array (M frequencies, N time bins) F : vector of length M indicating the frequencies included in the spectrogram ''' exten = os.path.splitext(path)[-1] if exten == '.npz': tmp = np.load(path) P = np.array(tmp['P'].min().todense()) F = tmp['F'] T = tmp['T'] tmp.close() elif exten == '.h5': NFFT = 512 noverlap = 256 f = h5py.File(path, 'r+') s = f['s'].value fs = f['fs'].value f.close() (P, F, T) = specgram(s, Fs = fs, NFFT = NFFT, noverlap = noverlap) return P, F, T
def get_fingerprint_from_data(wave_data): # pxx[freq_idx][t] - мощность сигнала pxx, _, _ = mlab.specgram( wave_data, NFFT=cf.WINDOW_SIZE, noverlap=cf.WINDOW_OVERLAP, Fs=cf.SAMPLE_RATE) # 300-2870 | delta = 256 * 10 = 8 * 32 * 10 matrix = pxx[30*2:300*2].transpose() cnt1, cnt2 = 0, 0 arr = [] for time, timeline in enumerate(matrix): if time == 0: continue hash64, pow2 = 0, 1 for j in range(1, 65): energy1 = energy(matrix, time, j) - energy(matrix, time, j - 1) energy2 = energy(matrix, time - 1, j) - energy(matrix, time - 1, j - 1) if energy1 - energy2 > 0: hash64 += pow2 cnt1 += 1 else: cnt2 += 1 pow2 *= 2 arr.append(hash64) print('Done fingerprinting...', cnt1, cnt2) return [arr]
def _plot_spectrum(self, data, sampling_frequency): (Pxx, freqs, bins) = mlab.specgram(data, Fs=sampling_frequency, NFFT=self.NFFT, noverlap=self.noverlap) if numpy.any(Pxx[0,0] == 0): self._log("SpectrumPlot::Instance has power 0 in a frequency band, skipping...") return # Update minimal and maximal value self.min_value = min(self.min_value, min(Pxx.flatten())) self.max_value = max(self.max_value, max(Pxx.flatten())) Z = numpy.flipud(Pxx) extent = 0, numpy.amax(bins), freqs[0], freqs[-1] pylab.imshow(Z, None, extent=extent, vmin=self.min_value, vmax=self.max_value) pylab.axis('auto') pylab.xlabel("Time(s)") pylab.ylabel("Frequency(Hz)") if self.colorbar and not self.physiological_arrangement: pylab.colorbar() return (Pxx, freqs, bins)
def calc_power_spectrum(lfp): npts, ntrials = lfp.shape Fs = 384. X = np.zeros() x = np.zeros((129, 7, ntrials)) for i in range(ntrials): x[:, :, i] = specgram(lfp[:127, i], Fs = Fs)[0]
def specgram(signal, sampling_frequency, time_resolution, frequency_resolution, bath_signals=[], high_frequency_cutoff=None, axes=None, logscale=True, **kwargs): """ This function wraps matplotlib.mlab.specgram to provide a more intuitive interface. Inputs: signal : the input signal (a one dimensional array) sampling_frequency : the sampling frequency of signal time_resolution : the desired time resolution of the specgram this is the guaranteed worst time resolution frequency_resolution : the desired frequency resolution of the specgram. this is the guaranteed worst frequency resolution. --keyword arguments-- bath_signals : Subtracts a bath signal from the spectrogram axes=None : If an Axes instance is passed then it will plot to that. **kwargs : Arguments passed on to matplotlib.mlab.specgram Returns: If axes is None: Pxx freqs bins if axes is an Axes instance: Pxx, freqs, bins, and im """ if (high_frequency_cutoff is not None and high_frequency_cutoff < sampling_frequency): resampled_signal = resample_signal(signal, sampling_frequency, high_frequency_cutoff) else: high_frequency_cutoff = sampling_frequency resampled_signal = signal num_data_samples = len(resampled_signal) specgram_settings = find_NFFT_and_noverlap(frequency_resolution, high_frequency_cutoff, time_resolution, num_data_samples) NFFT = specgram_settings['power_of_two_NFFT'] noverlap = specgram_settings['noverlap'] Pxx, freqs, bins = mlab.specgram(resampled_signal, NFFT=NFFT, Fs=high_frequency_cutoff, noverlap=noverlap, **kwargs) plotted_Pxx = Pxx if bath_signals: bath_signal = numpy.hstack(bath_signals) psd_Pxx, psd_freqs = psd(bath_signal, sampling_frequency, frequency_resolution, high_frequency_cutoff=high_frequency_cutoff ) plotted_Pxx = (Pxx.T/psd_Pxx).T if axes is not None: im = plot_specgram(plotted_Pxx, freqs, bins, axes, logscale=logscale) return plotted_Pxx, freqs, bins, im return plotted_Pxx, freqs, bins
def score(self, audio): nfft = int(self.window*audio.framerate) audio.calculate_specgram(nfft=nfft, noverlap=nfft/2) freqs = np.where((audio.specgram_freqs >= self.lower_call_frequency)*(audio.specgram_freqs <= self.upper_call_frequency)) spec2 = mlab.specgram(mean(log(audio.specgram[freqs[0],]), 0), NFFT=1024, noverlap=512, Fs=2/self.window) freqs2 = np.where((spec2[1] >= self.lower_syllable_frequency)*(spec2[1] <= self.upper_syllable_frequency)) max_kiwi = max(np.max(spec2[0][freqs2[0], :], 0)) mean_kiwi = np.exp(np.mean(np.mean(np.log(spec2[0][freqs2[0], :]), 0))) return max_kiwi/mean_kiwi
def generateSpectogram(channel_samples, Fs=DEFAULT_FS, wsize=DEFAULT_WINDOW_SIZE, wratio=DEFAULT_OVERLAP_RATIO, fan_value=DEFAULT_FAN_VALUE, amp_min=DEFAULT_AMP_MIN): # a tuple (Pxx, freqs, t) is said to be the return value of specgram arr2D = mlab.specgram(channel_samples, NFFT=wsize, Fs=Fs, window=mlab.window_hanning, noverlap=int(wsize * wratio))[0] # apply log transform since specgram() returns linear array arr2D = 10 * np.log10(arr2D) arr2D[arr2D == -np.inf] = 0 # replace infs with zeros # find local maxima plotPeaks(arr2D, amp_min=amp_min)
def __call__(iterator): for AudioFile in iterator: x = AudioFile.data data = mlab.specgram(x, NFFT=256, Fs=2, detrend=mlab.detrend_none, window=mlab.window_hanning, noverlap=128, cmap=None, xextent=None, pad_to=None, sides='default', scale_by_freq=None, mode='default') yield data
def get_spectrum_data(self): print("Calculating spectrum data...") self.spec_PSDperHz, self.spec_freqs, self.spec_t = mlab.specgram(np.squeeze(self.data), NFFT=self.NFFT, window=mlab.window_hanning, Fs=self.fs_Hz, noverlap=self.overlap ) # returns PSD power per Hz # convert the units of the spectral data self.spec_PSDperBin = self.spec_PSDperHz * self.fs_Hz / float(self.NFFT)
def get_specgram(self): winpoints = self.winfunc(self.specfftsize) iq_spec, f, t = mlab.specgram(self.iq, Fs=self.sample_rate, NFFT=self.specfftsize, noverlap=self.specfftsize/4.0, window=winpoints, scale_by_freq=False) self.iq_spec = 10.0*scipy.log10(abs(iq_spec)) self.spec_f = f self.spec_t = t
def specgram( signal, sampling_frequency, time_resolution, frequency_resolution, high_frequency_cutoff=None, logscale=True, **kwargs ): """This function wraps matplotlib.mlab.psd to provide a more intuitive interface. Plot with: power, freqs, bins = specgram(...) extent = (bins[0], bins[-1], freqs[0], freqs[-1]) imshow(power, aspect='auto', origin='lower', extent=extent) # from pyplot :param: signal - the input signal (a one dimensional array) :param: sampling_frequency - the sampling frequency of signal (i.e.: 10000) :param: frequency_resolution - the desired frequency resolution of the specgram. this is the guaranteed worst frequency resolution. :param: time_resolution - the desired frequency resolution of the specgram. this is the guaranteed worst time resolution. :param: high_frequency_cutoff - optional high freq. cutoff. resamples data to this value and then uses that for Fs parameter :param: logscale - rescale data based on log values? defaults is True :param: **kwargs - Arguments passed on to matplotlib.mlab.psd :returns: - tuple of three numpy arrays: power - 2d array of power (dB/Hz) freqs - in Hz bins - in seconds """ if high_frequency_cutoff is not None and high_frequency_cutoff < sampling_frequency: resampled_signal = resample_signal(signal, sampling_frequency, high_frequency_cutoff) else: high_frequency_cutoff = sampling_frequency resampled_signal = signal num_data_samples = len(resampled_signal) specgram_settings = find_NFFT_and_noverlap( frequency_resolution, high_frequency_cutoff, time_resolution, num_data_samples ) NFFT = specgram_settings["power_of_two_NFFT"] noverlap = specgram_settings["noverlap"] power, freqs, bins = mlab.specgram( resampled_signal, NFFT=NFFT, Fs=high_frequency_cutoff, noverlap=noverlap, **kwargs ) if logscale: power = 10 * np.log10(power) return power, freqs, bins
def ReadAndAnalyze(f): wav = wave.open(f, 'r') frames = wav.readframes(-1) sound_info = numpy.fromstring(frames, 'Int16') frame_rate = wav.getframerate() wav.close() specdata = mlab.specgram(sound_info, NFFT=nfft, pad_to=padto, Fs=frame_rate) spectrum = specdata[0] freqs = specdata[1] return spectrum, freqs
def get_center_frequencies(self): """ Returns center frequencies of filter bank channels """ nwin, nshift, nfft, fs, noverlap = self.__get_fft_params() _, fc, _ = specgram(np.zeros((2*nwin,)), NFFT=nfft, Fs=fs, noverlap=noverlap) if self.f_cutoff is not None: valid = np.logical_and(fc >= self.f_cutoff[0], fc <= self.f_cutoff[1]) fc = fc[valid] return fc
def get_power_spectrum_of_wave(sample_rate, data): noverlap = 96 nfft = 128 spectrum, frequencies, times = specgram( data, Fs=sample_rate, noverlap=noverlap, NFFT=nfft, scale_by_freq=True, ) return spectrum
def transform(self, waveform): """Converts a waveform to a suitable spectrogram. Removes high and low frequencies, rebins in time (via median) to reduce data size. Returned times are the midpoints of the new bins. Returns: Pxx, freqs, t Pxx is an array of dB power of the shape (len(freqs), len(t)). It will be real but may contain -infs due to log10 """ # For now use NFFT of 256 to get appropriately wide freq bands, then # downsample in time Pxx, freqs, t = mlab.specgram(waveform, NFFT=self.NFFT, noverlap=self.noverlap, Fs=self.Fs, detrend=self.detrend, **self.specgram_kwargs) # Apply the normalization Pxx = Pxx * np.tile(freqs[:, np.newaxis] ** self.normalization, (1, Pxx.shape[1])) # strip out unused frequencies if self.max_freq is not None: Pxx = Pxx[freqs < self.max_freq, :] freqs = freqs[freqs < self.max_freq] if self.min_freq is not None: Pxx = Pxx[freqs > self.min_freq, :] freqs = freqs[freqs > self.min_freq] # Rebin in size "downsample_ratio". If last bin is not full, discard. Pxx_rebinned = [] t_rebinned = [] for n in range(0, len(t) - self.downsample_ratio + 1, self.downsample_ratio): Pxx_rebinned.append( np.median(Pxx[:, n:n+self.downsample_ratio], axis=1).flatten()) t_rebinned.append( np.mean(t[n:n+self.downsample_ratio])) # Convert to arrays Pxx_rebinned_a = np.transpose(np.array(Pxx_rebinned)) t_rebinned_a = np.array(t_rebinned) # log it and deal with infs Pxx_rebinned_a_log = -np.inf * np.ones_like(Pxx_rebinned_a) Pxx_rebinned_a_log[np.nonzero(Pxx_rebinned_a)] = \ 10 * np.log10(Pxx_rebinned_a[np.nonzero(Pxx_rebinned_a)]) self.freqs = freqs self.t = t_rebinned_a return Pxx_rebinned_a_log, freqs, t_rebinned_a
def __init_spectrogram(self, nfft = DEFAULT_WINDOW_SIZE, overlap = DEFAULT_OVERLAP_RATIO): # matplotlib has 3 different specgram implementations - mlab, pyplot, and on # the axes: # 1. mlab - [https://github.com/matplotlib/matplotlib/blob/78f1942f5af063abacc3d5709912bde6bbb6ffec/lib/matplotlib/mlab.py] # 2. pyplot - [https://github.com/matplotlib/matplotlib/blob/e7717f71abae542ba0a5fea5b072bf52548d5ee3/lib/matplotlib/pyplot.py] # 3. axes - [https://github.com/matplotlib/matplotlib/blob/e7717f71abae542ba0a5fea5b072bf52548d5ee3/lib/matplotlib/axes/_axes.py] # 1 is the primary implementation. 2 calls 3 and 3 calls 1, but does the # added job of plotting after log scaling, and flipping the surface # matrix appropriately. We derive the plotting code from theirs. Pxx, freqs, bins = mlab.specgram(self.data, NFFT = nfft, Fs = self.frequency, pad_to = self.specgram_freq_bins, noverlap = (int(nfft*overlap))) return Pxx, freqs, bins
def trial_specgram(d, samplerate=None, NFFT=256): ''' Calculate a spectrogram for each channel and each trial. Parameters ---------- d : :class:`DataSet` The trials. samplerate : float The sample rate of the data. When omitted, :func:`psychic.get_samplerate` is used to estimate the sample rate. NFFT : int Number of FFT points to use to calculate the spectrograms. Returns ------- d : :class:`DataSet` The spectrograms: - ``d.data``: [channels x freqs x samples x trials] - ``d.feat_lab``: The feature labels for the axes [channels (strings), frequencies (floats), time in seconds (floats)] ''' assert d.data.ndim == 3 if samplerate is None: assert d.feat_lab is not None, 'Must either supply samplerate or feat_lab to deduce it.' samplerate = np.round(1./np.median(np.diff([float(x) for x in d.feat_lab[1]]))) all_TFs = [] for trial in range(d.ninstances): channel_TFs = [] for channel in range(d.data.shape[0]): TF, freqs, times = specgram(d.data[channel,:,trial], NFFT, samplerate, noverlap=NFFT/2) channel_TFs.append(TF.T[np.newaxis,:,:]) all_TFs.append(np.concatenate(channel_TFs, axis=0)[..., np.newaxis]) all_TFs = np.concatenate(all_TFs, axis=3) nchannels, nfreqs, nsamples, ninstances = all_TFs.shape feat_lab = [d.feat_lab[0], times.tolist(), freqs.tolist()] feat_dim_lab=['channels', 'time', 'frequencies'] return DataSet( data=all_TFs, feat_lab=feat_lab, feat_dim_lab=feat_dim_lab, default=d)
def showSignal(self): Pxx, freqs, bins = specgram(self.signal, NFFT = self.NFFT, Fs= self.fs, noverlap = 2*self.NFFT/3, window = gaussian(self.NFFT,self.NFFT/6)) Z= 10*np.log10(Pxx) Z = np.flipud(Z) Z[Z>np.amax(Z)-3]= np.amax(Z)-3 self.rawSpecData = Z Z[Z<(np.amax(Z)-self.dynamicRange)]=self.noiseFloor extent = 0, self.timeLength, freqs[0], freqs[-1] self.axes.imshow(Z,cm.get_cmap('Greys'),extent = extent) self.axes.axis('auto') self.axes.set_ylim([0,self.freqRange]) self.axes.set_xlim([0,self.timeLength]) self.axes.grid(True) self.draw()
def spectrogram(data, samp_rate, per_lap=0.9, wlen=None, log=False, outfile=None, fmt=None, axes=None, dbscale=False, mult=8.0, cmap=obspy_sequential, zorder=None, title=None, show=True, clip=[0.0, 1.0]): """ Computes and plots spectrogram of the input data. :param data: Input data :type samp_rate: float :param samp_rate: Samplerate in Hz :type per_lap: float :param per_lap: Percentage of overlap of sliding window, ranging from 0 to 1. High overlaps take a long time to compute. :type wlen: int or float :param wlen: Window length for fft in seconds. If this parameter is too small, the calculation will take forever. If None, it defaults to (samp_rate/100.0). :type log: bool :param log: Logarithmic frequency axis if True, linear frequency axis otherwise. :type outfile: str :param outfile: String for the filename of output file, if None interactive plotting is activated. :type fmt: str :param fmt: Format of image to save :type axes: :class:`matplotlib.axes.Axes` :param axes: Plot into given axes, this deactivates the fmt and outfile option. :type dbscale: bool :param dbscale: If True 10 * log10 of color values is taken, if False the sqrt is taken. :type mult: float :param mult: Pad zeros to length mult * wlen. This will make the spectrogram smoother. :type cmap: :class:`matplotlib.colors.Colormap` :param cmap: Specify a custom colormap instance. If not specified, then the default ObsPy sequential colormap is used. :type zorder: float :param zorder: Specify the zorder of the plot. Only of importance if other plots in the same axes are executed. :type title: str :param title: Set the plot title :type show: bool :param show: Do not call `plt.show()` at end of routine. That way, further modifications can be done to the figure before showing it. :type clip: [float, float] :param clip: adjust colormap to clip at lower and/or upper end. The given percentages of the amplitude range (linear or logarithmic depending on option `dbscale`) are clipped. """ import matplotlib.pyplot as plt # enforce float for samp_rate samp_rate = float(samp_rate) # set wlen from samp_rate if not specified otherwise if not wlen: wlen = samp_rate / 100. npts = len(data) # nfft needs to be an integer, otherwise a deprecation will be raised # XXX add condition for too many windows => calculation takes for ever nfft = int(_nearest_pow_2(wlen * samp_rate)) if nfft > npts: nfft = int(_nearest_pow_2(npts / 8.0)) if mult is not None: mult = int(_nearest_pow_2(mult)) mult = mult * nfft nlap = int(nfft * float(per_lap)) data = data - data.mean() end = npts / samp_rate # Here we call not plt.specgram as this already produces a plot # matplotlib.mlab.specgram should be faster as it computes only the # arrays # XXX mlab.specgram uses fft, would be better and faster use rfft specgram, freq, time = mlab.specgram(data, Fs=samp_rate, NFFT=nfft, pad_to=mult, noverlap=nlap) # db scale and remove zero/offset for amplitude if dbscale: specgram = 10 * np.log10(specgram[1:, :]) else: specgram = np.sqrt(specgram[1:, :]) freq = freq[1:] vmin, vmax = clip if vmin < 0 or vmax > 1 or vmin >= vmax: msg = "Invalid parameters for clip option." raise ValueError(msg) _range = float(specgram.max() - specgram.min()) vmin = specgram.min() + vmin * _range vmax = specgram.min() + vmax * _range norm = Normalize(vmin, vmax, clip=True) if not axes: fig = plt.figure() ax = fig.add_subplot(111) else: ax = axes # calculate half bin width halfbin_time = (time[1] - time[0]) / 2.0 halfbin_freq = (freq[1] - freq[0]) / 2.0 # argument None is not allowed for kwargs on matplotlib python 3.3 kwargs = { k: v for k, v in (('cmap', cmap), ('zorder', zorder)) if v is not None } if log: # pcolor expects one bin more at the right end freq = np.concatenate((freq, [freq[-1] + 2 * halfbin_freq])) time = np.concatenate((time, [time[-1] + 2 * halfbin_time])) # center bin time -= halfbin_time freq -= halfbin_freq # Log scaling for frequency values (y-axis) ax.set_yscale('log') # Plot times ax.pcolormesh(time, freq, specgram, norm=norm, **kwargs) else: # this method is much much faster! specgram = np.flipud(specgram) # center bin extent = (time[0] - halfbin_time, time[-1] + halfbin_time, freq[0] - halfbin_freq, freq[-1] + halfbin_freq) ax.imshow(specgram, interpolation="nearest", extent=extent, **kwargs) # set correct way of axis, whitespace before and after with window # length ax.axis('tight') ax.set_xlim(0, end) ax.grid(False) if axes: return ax ax.set_xlabel('Time [s]') ax.set_ylabel('Frequency [Hz]') if title: ax.set_title(title) if not os.environ.get('SPHINXBUILD'): # ignoring all NumPy warnings during plot with np.errstate(all='ignore'): plt.draw() if outfile: if fmt: fig.savefig(outfile, format=fmt) else: fig.savefig(outfile) elif show: plt.show() else: return fig
def audioToFilteredSpectrogram(data, expandByOne=True, dropZeroColumnsPercent=0.95): # calculate the spectogram # #tempSpec = np.log10(mlab.specgram(data, NFFT=512, noverlap=256, Fs=16000)[0]) tempSpec = np.log10( mlab.specgram(data, NFFT=512, noverlap=256, Fs=16000)[0] + 1) # drop higher frequencies tempSpec = tempSpec[0:200, :] tempSpecFiltered = np.copy(tempSpec) # we analize the spectogram by 20x30 sized cells # to achieve better accuray the size of this cell should be finetuned rowBorders = np.ceil(np.linspace(0, tempSpec.shape[0], 20)) columnBorders = np.hstack((np.ceil(np.arange(0, tempSpec.shape[1], 30)), tempSpec.shape[1])) rowBorders = [int(x) for x in rowBorders] columnBorders = [int(x) for x in columnBorders] keepCells = np.ones((len(rowBorders) - 1, len(columnBorders) - 1)) # we create a mask for the spectogram: we scan the spectogram with the 20x30 sized # cell and create 0 mask based on the mean and std of the spectogram calculated for the cells and rows for i in range(len(rowBorders) - 1): row_mean = np.mean(tempSpec[rowBorders[i]:rowBorders[i + 1], :]) row_std = np.std(tempSpec[rowBorders[i]:rowBorders[i + 1], :]) for j in range(len(columnBorders) - 1): cell_mean = np.mean(tempSpec[rowBorders[i]:rowBorders[i + 1], columnBorders[j]:columnBorders[j + 1]]) cell_max_top10_mean = np.mean( np.sort(tempSpec[rowBorders[i]:rowBorders[i + 1], columnBorders[j]:columnBorders[j + 1]], axis=None)[-10:]) if (cell_mean < 0 or ((cell_max_top10_mean) < (row_mean + row_std) * 1.5)): keepCells[i, j] = 0 # expand by ones (see above) if expandByOne: keepCells = expandOnes(keepCells) # apply the mask to the spectogram for i in range(keepCells.shape[0]): for j in range(keepCells.shape[1]): if not keepCells[i, j]: tempSpecFiltered[rowBorders[i]:rowBorders[i + 1], columnBorders[j]:columnBorders[j + 1]] = 0 # drop zero columns # the amount of zero values along axis 0 (frequency) is calculated for every column (timeslice) # and it is dropped, if the number of zero values is higher than the dropZeroColumnsPercent # eg. dropZeroColumnsPercent=0.95, than a column (timeslice) is dropped, if more than 95% of the values (frequencies) is 0 tempSpecFilteredBackup = np.copy(tempSpecFiltered) tempSpecFiltered = np.delete( tempSpecFiltered, np.nonzero((tempSpecFiltered == 0).sum( axis=0) > tempSpecFiltered.shape[0] * dropZeroColumnsPercent), axis=1) # if every row was 0 than use the backed up spectogram if tempSpecFiltered.shape[1] == 0: tempSpecFiltered = tempSpecFilteredBackup return tempSpec, tempSpecFiltered
def spectrogram(x, SR, winlen): Pxx, freqs, bins, im = mlab.specgram(x, NFFT=winlen, Fs=SR)
def features_and_labels(path_input, path_label, access, type_data): #This function computes spectrogram for each audio, creates the extended featureMAP, divides this in segments of lenght 400 #and creates the list of the inputs of the neural network and the list of the rispective labels #The lists are saved of hdf5 files #type_data defines the partition (train, dev, eval) list_input=[] list_label_b=[] list_label_m=[] UFeatureMAP=np.zeros((257, 1600)) segment=np.zeros((257,400)) M=400 #Lenght of the segments L=200 #Overlap between segments file_label = open(path_label,"r", encoding='utf8') rows=file_label.readlines(); file_label.close() #File txt where for each audio where are saved the number of segments and the label file_segments=type_data+'_segments.txt' f=open(file_segments,'w', encoding='utf8') f.close() #File where segments and labels will be saved filename_input=os.path.join(type_data+'_input.hdf5') #es. train_input.hdf5 filename_label_m=os.path.join(type_data+'_label_m.hdf5') filename_label_b=os.path.join(type_data+'_label_b.hdf5') fx = h5py.File(filename_input, "a") fy_multi = h5py.File(filename_label_m, "a") fy_binary = h5py.File(filename_label_b, "a") dset = fx.create_dataset('dataset', (0,257,400,1), maxshape=(None,None,None,None), chunks=True, compression="gzip", compression_opts=9) dset_binary=fy_binary.create_dataset('dataset', (0,), maxshape=(None,), chunks=True, compression="gzip", compression_opts=4) dset_multi=fy_multi.create_dataset('dataset', (0,), maxshape=(None,), chunks=True, compression="gzip", compression_opts=4) print('Start extracting features...') print('Creating hdf5 file...') N_files=len(glob.glob(path_input)) S=3000 #How much segments are appended to the file hdf5 each time N_iterazioni=int(N_files/S) rest2=N_files-N_iterazioni*S counter=0 #glob.glob return a string like this: /content/LA/ASVspoof2019_LA_train/flac/LA_T_1929428.flac #We wanto to extract from this string the name of the audio that is in this case: LA_T_1929428 #So, to do that we take filename[len(filename)-17:-5] for filename in glob.glob(path_input): counter=counter+1 flag_found=0 for row in rows: fields=row.split(" ") if fields[1]==filename[len(filename)-17:-5]: flag_found=1 label_multi=fields[3] label_multi=convert_label(label_multi, access) if fields[4]=='bonafide\n': label_binary=0 if fields[4]=='spoof\n': label_binary=1 break if flag_found==1: #Spectrogram data,fs=sf.read(filename) [Ps, f, t] = mlab.specgram(data, NFFT=512, Fs=fs, window=signal.get_window('hamming', 512), noverlap=256, mode='psd') Ps=np.where(Ps==0, 1e-200 , Ps) PsdB=10*np.log10(Ps); [Nf,Nt]=PsdB.shape #For each audio define the lenght of the unified feature map multiple=int(np.ceil((Nt/400))) N=2*multiple-1 lenght=multiple*400 #Create UNIFIED FEATURE MAP Q=int (lenght/Nt ) rest1 = lenght - Nt*Q UFeatureMAP[:, 0:(Q*Nt)] = np.tile(PsdB,Q) UFeatureMAP[:, (Q*Nt):lenght] = PsdB[:, 0:rest1] #Divide feature map in segments #Append the segment to list of all segmets and the corrispective to list of labels for i in range(0,N): segment=np.copy(UFeatureMAP[: , (i*L):(i*L+M)]) segment=np.expand_dims(segment, axis=2) list_input.append(segment) list_label_m.append(label_multi) list_label_b.append(label_binary) #Write on a file, for each audio, the number of the segments and the label (binary and multi-class) of the speech f=open(file_segments,'a',encoding='utf8') a = '{0}\t{1}\t{2}\n'.format(N,str(label_binary),str(label_multi)) f.write(a) f.close() P=len(list_input) #Each time S audio are processed, the list of the segments is appendend on the file hdf5 and the list is reset if counter%S==0 and counter!=N_files and P!=0: print(counter) dset.resize(dset.shape[0]+P, axis=0) dset[-P:,:,:,:] = list_input[0:P] dset_binary.resize(dset_binary.shape[0]+P, axis=0) dset_binary[-P:] = list_label_b[0:P] dset_multi.resize(dset_multi.shape[0]+P, axis=0) dset_multi[-P:] = list_label_m[0:P] list_input=[] list_label_m=[] list_label_b=[] #This is the last iteration if counter==N_files and P!=0: print(counter) dset.resize(dset.shape[0]+P, axis=0) dset[-P:,:,:,:] = list_input[0:P] dset_binary.resize(dset_binary.shape[0]+P, axis=0) dset_binary[-P:] = list_label_b[0:P] dset_multi.resize(dset_multi.shape[0]+P, axis=0) dset_multi[-P:] = list_label_m[0:P] list_input=[] list_label_m=[] list_label_b=[] fx.close() fy_multi.close() fy_binary.close() print('Done...') return
def wave_amplitude(data, fs_hz, NFFT, overlap, length, frequenciesRange): data = np.asarray(data) data = data[:buffersize, :] f_eeg_data = filter_data(data, fs_hz) #t0 = time.time() if frequenciesRange == 'delta': wave_band_Hz = np.array([0.4, 4]) elif frequenciesRange == 'theta': wave_band_Hz = np.array([4, 7]) if frequenciesRange == 'alpha': wave_band_Hz = np.array([8, 12]) elif frequenciesRange == 'beta': wave_band_Hz = np.array([12, 25]) elif frequenciesRange == 'gamma': wave_band_Hz = np.array([25, 35]) size = f_eeg_data.shape[1] mean_range = np.zeros((1, size)) max_range = np.zeros((1, size)) min_range = np.zeros((1, size)) ratio = np.zeros((1, size)) for channel in range(size): spec_PSDperHz, freqs, t_spec = mlab.specgram( f_eeg_data[20:, channel], NFFT=NFFT, Fs=fs_hz, window=mlab.window_hanning, noverlap=overlap) # convert the units of the spectral data spec_PSDperBin = spec_PSDperHz * fs_hz / float( NFFT) # convert to "Power Spectral Density per bin" spec_PSDperBin = np.asarray(spec_PSDperBin) # print(spec_PSDperBin.shape) # from 1 to 110 Hz, step of 1Hz # take the average spectrum according to the time - axis 1 bool_inds_wave_range = (freqs > wave_band_Hz[0]) & (freqs < wave_band_Hz[1]) #freq_range = freqs[bool_inds_wave_range == 1] #freq_range = freq_range[max_range_idx] spec_PSDperBin_range = spec_PSDperBin[bool_inds_wave_range] mean_range[0][channel] = np.mean(spec_PSDperBin_range) # max_range[0][channel] = np.amax(spec_PSDperBin_range) # get the frequency of the max in each range alpha, beta, theta, gamma # max_range_idx = np.argmax(spec_PSDperBin_range) ''' Get the median, max and min of the 4 channels b ''' med_range = np.median(mean_range[0][:]) max_range = np.amax(mean_range[0][:]) min_range = np.min(mean_range[0][:]) # return [med_alpha, max_alpha, min_alpha, freq_alpha, # med_beta, max_beta, min_beta, freq_beta, # med_theta, max_theta, min_theta, freq_theta, # med_gamma, max_gamma, min_gamma, freq_gamma, time_last_alpha] results = [med_range, max_range, min_range] result = results[0] # print(med_gamma.type()) return result
#print fft_op.shape #plt.plot(np.arange(44100), np.absolute(np.fft.fft(wav_arr[1][:4096, 0], 44100))) #plt.show() print "mean:", np.mean(abs(wav_arr[1][:43000, 0])) print "median", np.median(abs(wav_arr[1][:43000, 0])) tmp_arr = [i if i > 350 else 0 for i in wav_arr[1][:, 0]] write('test.wav', 44100, np.int16(tmp_arr)) filter_op = butter_lowpass_filter(wav_arr[1][:, 0], 1000, 44100, 6) NFFT = int(fs * 0.1) noverlap = int(NFFT / 4) print NFFT, noverlap print "spec" Pxx, freqs, t = specgram(wav_arr[1][:43000, 0], NFFT=NFFT, window=window_hanning, noverlap=noverlap) print Pxx, freqs, t plt.pcolormesh(t, freqs, Pxx) plt.colorbar() plt.show() Pxx, freqs, t = specgram(filter_op, NFFT=NFFT, window=window_hanning, noverlap=noverlap) print Pxx, freqs, t plt.pcolormesh(t, freqs, Pxx) plt.colorbar() plt.show() #print np.amax(butter_lowpass_filter(wav_arr[1][:, 0], 1000, 44100, 6));
from scipy.stats import skew import numpy as np #import pandas as pd # ReadAIFF function def ReadAIFF(file): # Reads the frames from the audio clip and returns the uncompressed data s = aifc.open(file,'r') nFrames = s.getnframes() strSig = s.readframes(nFrames) return np.fromstring(strSig, np.short).byteswap() # Read one file as an example params = {'NFFT':256, 'Fs':200, 'noverlap':192} s = ReadAIFF('train6.aiff') P, freqs, bins = mlab.specgram(s, **params) # print(P.shape) # print(freqs.shape) # print(bins.shape) # Spectrogram plotting function long_sample_01.aiff def plot_spectrogram(ax, P): plt.imshow(P, origin='lower', extent=[-6,6,-1,1], aspect=4, cmap = cm.get_cmap('bwr')) loc = plticker.MultipleLocator(base=3.0) # this locator puts ticks at regular intervals ax.xaxis.set_major_locator(loc) ax.set_xticklabels(np.arange(1.0,12.5,0.5)) ax.set_yticklabels(range(0,10000,250)) ax.set_xlabel('Time (seconds)', fontsize = 12) ax.set_ylabel('Frequency (Hz)', fontsize = 12) cbar = plt.colorbar()
def get_fft_histogram(signal, audio_sample_rate, seconds, histograms_per_second, buckets, plot): window_size = audio_sample_rate / histograms_per_second overlap_ratio = 0.0 # FFT the signal and extract frequency components # Some parameter explanations: # NFFT = the number of samples grouped into each specgram # Fs = The sample rate of the signal specgram = mlab.specgram( signal, NFFT=window_size, Fs=audio_sample_rate, window=mlab.window_hanning, noverlap=int(window_size * overlap_ratio)) # The periodogram is a 2D array in the format: [frequencyId][sampleId] # The actual frequency of each {frequencyId} is recorded in specgram[1] # where specgram[1][frequencyId] will return the frequency value in Hz # The {sampleId} represents the sample number after the total number of # samples is grouped by {window_size} # Each data point in this array represents signal density at a particular # frequency and sample number periodogram = specgram[0] if verbose: print "Dimensions of periodogram: %i x %i" % (len(periodogram), len(periodogram[0])) # apply log transform since specgram() returns linear array # volume is logrithmic, therefore the periodogram's data (which represents # amplitude / density of each frequency) must be converted arr2D = 10 * np.log10(periodogram) arr2D[arr2D == -np.inf] = 0 # replace infs with zeros if plot: fig = plt.figure(figsize=(6, 3.2)) ax = fig.add_subplot(111) ax.set_title('Spectrogram') plt.imshow(arr2D) ax.set_aspect('equal') plt.colorbar(orientation='vertical') plt.show() return None else: # Converts periodogram from format [frequencyId][sampleId] # to [sampleId][frequencyId] flipped = np.transpose(arr2D) if verbose: print "Total samples: %i" % len(flipped) print "Samples per second: %f" % (len(flipped) / seconds) print "Grouping FFT into %i-bucket histogram..." % buckets grouped = [] # Creates histograms for each sample. Groups the entire frequency range # into {buckets} number of buckets for i, sample in enumerate(flipped): perc_done = float(i+1) / len(flipped) elapsed_seconds = (perc_done * seconds) histogram = np.array(np.histogram( sample, bins=buckets)[0] ).tolist() histogram = [elapsed_seconds] + histogram grouped.append(histogram) return grouped
#ax_fs.set_xlim(0.01*max(Pxx),1.1*max(Pxx)) ax_fs.set_xlim(0.01 * max(wavelet.get_wps()), 1.1 * max(wavelet.get_wps())) pl.setp(ax_ts.get_xticklabels() + ax_fs.get_yticklabels(), visible=False) pl.tight_layout() ######################## # Fourier Decomposition from matplotlib import mlab pl.figure() S, F, T = mlab.specgram(data, NFFT=int(0.1 * len(data)), Fs=sample_rate, window=mlab.window_hanning, noverlap=int(.5 * 0.1 * len(data))) pl.close() Time = T + min(time) #collevs=np.linspace(0, max(map(max,S)), 100) fpeakmin = 2000.0 freq_fourier, Pxx = signal.periodogram(data, fs=sample_rate) collevs = np.linspace(0, 5 * max(Pxx[freq_fourier > fpeakmin]), 100) fig, ax_cont = pl.subplots(figsize=(10, 5)) #ax_cont.contourf(Time, F, S, levels=collevs, cmap=cm.gnuplot2) extent = [min(Time), max(Time), min(F), max(F)]
for i in range(10): freqs, tempo, Sxx_scipy = signal.spectrogram(sinal, fs=1, nperseg=win * zer_pad, noverlap=(1 - 1 / step_scale) * win) time1 = time.time() print('\nSCIPY: {0} ms'.format(100 * (time1 - time0))) plt.subplot(4, 1, 3) plt.pcolormesh(tempo, freqs, Sxx_scipy) plt.ylim(freq_min, freq_max) plt.plot(tem, w, 'k', lw=2) plt.ylim(freq_min, freq_max) plt.title('scipy') # measure matplotlib spectrogram time plt.subplot(4, 1, 4) time0 = time.time() for i in range(10): Sxx_mlab, freqs, bins = specgram(sinal, Fs=1, NFFT=win * zer_pad, noverlap=(1 - 1. / step_scale) * win) time1 = time.time() print('\nMATPLOTLIB: {0} ms'.format(100 * (time1 - time0))) print('\ntime resolution:\n CUSTOM: {} \t SCIPY: {} \t MLAB: {}'.format(mat_cs.shape, Sxx_scipy.shape, Sxx_mlab.shape)) print('\ndark line is simulated frequency\n') print(len(tempo)) plt.plot(tem, w, 'k', lw=2) plt.pcolormesh(bins, freqs, Sxx_mlab) plt.ylim(freq_min, freq_max) plt.title('mlab') plt.tight_layout() plt.show()
def data_push(data_url): """ Utility function to upload spectogram and wav file from OOI website to s3. """ creds_data = load_creds() client = boto3.client('s3', aws_access_key_id=creds_data['key_id'], aws_secret_access_key=creds_data['key_access']) try: hydrophone_name = data_url.split('/')[5] url_date = data_url.split('--')[1][4:14].replace('-','_') # Read from url stream = read(data_url) samp_rate = stream[0].stats.sampling_rate t_start = stream[0].stats.starttime t_end = stream[0].stats.endtime duration = t_end-t_start # Ping Detections duration_check = int(duration) - 1 if duration_check > 0: logging.info('Executing Url: %s', data_url) pingtimes = np.zeros(duration_check) for stratpoint in range(duration_check): pingindex = np.argmax(stream[0].data[int(stratpoint * samp_rate):int((stratpoint + 1) * samp_rate)]) pingtimes[stratpoint] = (t_start + stratpoint + pingindex * stream[0].stats.delta) # Filter Data+Plot Spectrogram+Save Image and Audio step_size = 10 # for calculating the rms pressure and ploting the spectrogtam wlen = 0.056 # bin size in sec nfft = int(_nearest_pow_2(wlen * samp_rate)) # number of fft points of each bin per_lap = 0.995 # percentage of overlap nlap = int(nfft * float(per_lap)) # number of overlapped samples timestep = 10 # save results every 5 seceonds (no overlap) for i in range(0, len(pingtimes), timestep): st = stream.slice(UTCDateTime(pingtimes[i]), UTCDateTime(pingtimes[i]) + step_size) trace = st[0].copy() # Plot Spectrogram npts = len(st[0]) end = npts / samp_rate # using mlab to create the array of spectrogram specgram, freq, time = mlab.specgram(trace.data/1e-6, NFFT=nfft, Fs=samp_rate, noverlap=nlap, pad_to=None) specgram = 10 * np.log10(specgram[1:, :]) specgram = np.flipud(specgram) freq = freq[1:] / 1e3 # Convert Frequency to kHz halfbin_time = (time[1] - time[0]) / 2.0 halfbin_freq = (freq[1] - freq[0]) / 2.0 freq = np.concatenate((freq, [freq[-1] + 2 * halfbin_freq])) time = np.concatenate((time, [time[-1] + 2 * halfbin_time])) extent = (time[0] - halfbin_time, time[-1] + halfbin_time, freq[0] - halfbin_freq, freq[-1] + halfbin_freq) # colormap setting vmin = 0.50 # default should be 0 to start from the min number of the spectrgram vmax = 0.95 # default should be 1 to end at the max number of the spectrgram _range = float(specgram.max() - specgram.min()) vmin = specgram.min() + vmin * _range vmax = specgram.min() + vmax * _range norm = Normalize(vmin, vmax) # to scale a 2-D float X input to the (0, 1) range for input to the cmap # Save spectrogram fig = plt.figure(frameon=False, figsize=(8, 8)) ax = plt.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) cax = ax.imshow(specgram, interpolation="nearest", extent=extent, norm=norm, cmap='bone') dpi = fig.get_dpi() fig.set_size_inches(512/float(dpi), 512/float(dpi)) ax.axis('tight') ax.set_xlim(0, end) ax.set_ylim(0.01, 8) ax.grid(False) ax.set_xlabel('Time [s]') ax.set_ylabel('Frequency [kHz]') filename = st[0].stats.network+'_'+st[0].stats.station+'_'+st[0].stats.location+'_'+st[0].stats.channel+'_'+str(UTCDateTime(pingtimes[i])).replace("-", "_").replace( ":", "_") plt.savefig(filename[:-8] + '.jpg') client.upload_file(filename[:-8] + '.jpg', bucket_name ,'{}/{}/{}/'.format(folder_name, hydrophone_name, url_date) +filename[:-8] + '.jpg') os.remove(filename[:-8] + '.jpg') plt.cla() plt.clf() plt.close('all') # save audio Save2Wav(st[0], filename, samp_rate) client.upload_file(filename[:-8] + '.wav', bucket_name, '{}/{}/{}/'.format( folder_name, hydrophone_name, url_date) + filename[:-8] + '.wav') os.remove(filename[:-8] + '.wav') # delete large objects to release memory. del trace, st[0] gc.collect() else: logging.info("Skipped Url: %s", data_url) # check for unwanted URL format. except Exception as err: logging.info('Url with error: %s is %s', err, data_url)
def Updated_ReadingAudio( img_rows=64, img_cols=64, path=r"C:\Users\yaniv\Desktop\classification app\goldStandarts_2020_united.xlsx" ): import scipy from scipy import signal from scipy.io import wavfile from pathlib import Path import numpy as np from scipy.misc import imresize import xlrd # from AudioPreProcessing import AudioPreProcessing from skimage import img_as_ubyte import cv2 import matplotlib.pyplot as plt from matplotlib import mlab # Open the gold standard xl xl_workbook = xlrd.open_workbook(path) xl_sheet = xl_workbook.sheet_by_index(0) num_rows = xl_sheet.nrows # Number of rows Image = [None] * num_rows TrueLabels = [None] * num_rows Data = [None] * num_rows Precentages = [None] * num_rows for row_idx in range(0, num_rows): # Iterate through rows current_row = xl_sheet.row_values(row_idx) data_folder = current_row[0] file = "%s.wav" % (current_row[1]) #audiofile file_to_open = data_folder + file #audiofile Fs, samples = wavfile.read(file_to_open) times1 = int( round(current_row[2], 4) * Fs) #taking relevant times of the syllable from the audio file times2 = int( round(current_row[3], 4) * Fs) #taking relevant times of the syllable from the audio file Signal = samples[ times1: times2] #taking relevant times of the syllable from the audio file spectrogram, frequencies, times = mlab.specgram( Signal, NFFT=256, Fs=Fs, noverlap=120) # same spectrogram as the matlab # dBS = 20*np.log10(spectrogram) # convert to dB # plt.figure() # plt.pcolormesh(dBS) # spectrogram(sig,256,120,256,Fs,'MinThreshold',-110,'yaxis') # data = PreProcessedAudio #Dummy data. Just for testing width = img_rows # define the new spectrogram shape height = img_cols dim = (width, height) resized = cv2.resize(spectrogram, dim, interpolation=cv2.INTER_AREA) # plt.figure() # plt.pcolormesh(20*np.log10(resized)) # plt.colorbar() # img = resized/np.amax(resized) # plt.figure() # plt.pcolormesh(20*np.log10(img)) # plt.colorbar() Data[row_idx] = resized TrueLabels[row_idx] = current_row[8] return (Data, TrueLabels)
def rawPeakSPD(x, t=None, NFFT=1024): # A power, not amplitude return(np.max(specgram(x, NFFT=NFFT, noverlap=0)[0].flatten()))
def digital_to_spec( digital: np.ndarray, fs: float, frac_cut: float, plot: bool = False ) -> Union[Tuple[np.ndarray, float], Tuple[np.ndarray, float, Figure, Axes, float, float]]: """Produces a spectrogram and a cut-off intensity to yield the specified fraction of data. Parameters ---------- digital : numpy.ndarray, shape=(Ts, ) The sampled audio-signal. fs : float The sample-frequency used to create the digital signal. frac_cut : float The fractional portion of intensities for which the cutoff is selected. E.g. frac_cut=0.8 will produce a cutoff intensity such that the bottom 80% of intensities are excluded. plot : bool If True, produce a plot of the spectrogram and return the matplotlib fig & ax objects. Returns ------- Union[Tuple[numpy.ndarray, float]] The spectrogram and the desired cutoff If plot=True, then: (spectrogram, cutoff, fig, ax, df, dt) is returned. Where (fig, ax) are the plot objects, and df and dt are the frequency and time units associated with the spectrogram bins.""" if digital.max() <= 1: digital = digital * 2**15 assert 0.0 <= frac_cut <= 1.0 kwargs = dict(NFFT=4096, Fs=fs, window=mlab.window_hanning, noverlap=int(4096 / 2)) if not plot: S, freqs, times = mlab.specgram(digital, **kwargs) else: import matplotlib.pyplot as plt fig, ax = plt.subplots() S, freqs, times, im = ax.specgram(digital, **kwargs) fig.colorbar(im) # log-scaled Fourier amplitudes have a much more gradual distribution # for audio data. np.clip(S, a_min=1e-20, a_max=None, out=S) np.log(S, out=S) # Compute the cumulative distribution over Fourier component log-amplitudes. # Use this to identify the threshold amplitude below which `frac_cutoff` # proportion of amplitudes lie. a = np.sort(S.flatten()) cutoff = a[int(len(a) * frac_cut)] if not plot: return S, cutoff else: df = freqs[1] - freqs[0] dt = times[1] - times[0] return S, cutoff, fig, ax, df, dt
def recomputeSpectrogram(self, indexFrom=None, indexTo=None, maxCol=None): """ Method that computes the spectrogram of the signal in the supplied interval :param indexFrom: Start index in signal data array coordinates :param indexTo: End index in signal data array coordinates """ # do not work fine if the signal data changes # if not self.changes and self.lastInterval == (indexFrom, indexTo): # return indexFrom = indexFrom if indexFrom is not None else self.lastInterval[0] indexTo = indexTo if indexTo is not None else self.lastInterval[1] indexTo = indexTo if indexTo != -1 else self.signal.length maxCol = maxCol if maxCol != 0 else self.signal.length / self.NFFT if self.signal is None: raise Exception("No signal to compute spectrogram") # computing overlap so the number of columns is less or equal than maxCol smin = indexFrom - self.NFFT smax = indexTo + self.NFFT pre, post = np.zeros(max(-smin, 0)), np.zeros( max(smax - self.signal.length, 0)) data = np.concatenate( (pre, self.signal.data[max(smin, 0):min(smax, self.signal.length)], post)) self.__visual_overlap = self.overlap if maxCol is not None: cs = self.NFFT - self.overlap cols = (smax - smin - self.overlap) / cs if cols > maxCol: self.__visual_overlap = int(self.NFFT - (smax - smin) / maxCol) if False and indexFrom == self.lastInterval[ 0] and indexTo == self.lastInterval[1]: return # delegate in matplotlib specgram function the process of compute the spectrogram self.matriz, self.freqs, self.bins = mlab.specgram( data, NFFT=self.NFFT, Fs=self.signal.samplingRate, detrend=mlab.detrend_none, window=self.window, noverlap=self.__visual_overlap, sides=self.SPECGRAM_COMPLEX_SIDE) # changes to dB for bio acoustic processing temp = np.amax(self.matriz) if temp == 0: temp = 1.0 self.matriz = 10. * np.log10(self.matriz / temp) Zfin = np.isfinite(self.matriz) if np.any(Zfin): m = self.matriz[Zfin].min() self.matriz[np.isneginf(self.matriz)] = m else: self.matriz[self.matriz < -100] = -100 # verificar estos valores constantes self.matriz = np.transpose(self.matriz) self.lastInterval = (indexFrom, indexTo) self.lastMaxCol = maxCol self.changes = False
rcv_file.write(RecivedData) print("reciving another bounch of data") myconn.settimeout(5.0) RecivedData = myconn.recv(BUFF_SIZE) print(RecivedData) rcv_file.close() print("\n File has been copied successfully \n") myconn.close() print("\n Server closed the connection \n") server_socket.close() print("\n Plotting... \n") acc_data = np.genfromtxt(rcv_filename, delimiter=',', names=True) acc_x, freq_x, _ = mlab.specgram(acc_data['x'], Fs=SAMPLE_RATE, NFFT=SAMPLE_RATE * SMAPLE_TIME) acc_y, freq_y, _ = mlab.specgram(acc_data['y'], Fs=SAMPLE_RATE, NFFT=SAMPLE_RATE * SMAPLE_TIME) acc_z, freq_z, _ = mlab.specgram(acc_data['z'], Fs=SAMPLE_RATE, NFFT=SAMPLE_RATE * SMAPLE_TIME) plt.plot(freq_x[10:], acc_x[10:], label='x', linewidth=0.5) plt.plot(freq_y[10:], acc_y[10:], label='y', linewidth=0.5) plt.plot(freq_z[10:], acc_z[10:], label='z', linewidth=0.5) plt.yscale('log') plt.xlim((0, 160)) plt.legend(loc='upper right') plt.show() plt.savefig('spectrum.png')
def update_plots(self, draw=True): self.remove_peak_annotation() # trace: self.axt.set_xlim(self.toffset, self.toffset + self.twindow) t0 = int(np.round(self.toffset * self.samplerate)) t1 = int(np.round((self.toffset + self.twindow) * self.samplerate)) if t1 > len(self.data): t1 = len(self.data) time = np.arange(t0, t1) / self.samplerate if self.trace_artist == None: self.trace_artist, = self.axt.plot(time, self.data[t0:t1]) else: self.trace_artist.set_data(time, self.data[t0:t1]) self.axt.set_ylim(self.ymin, self.ymax) # compute power spectrum: nfft = int( np.round(2**(np.floor( np.log(self.samplerate / self.fresolution) / np.log(2.0)) + 1.0))) if nfft < 16: nfft = 16 nfft, noverlap = nfft_noverlap(self.fresolution, self.samplerate, 0.5, 16) t00 = t0 t11 = t1 w = t11 - t00 minw = nfft * (self.cfg['minPSDAverages'][0] + 1) // 2 if t11 - t00 < minw: w = minw t11 = t00 + w if t11 >= len(self.data): t11 = len(self.data) t00 = t11 - w if t00 < 0: t00 = 0 t11 = w power, freqs = ml.psd(self.data[t00:t11], NFFT=nfft, noverlap=noverlap, Fs=self.samplerate, detrend=ml.detrend_mean) self.deltaf = freqs[1] - freqs[0] # detect fish: h_kwargs = psd_peak_detection_args(self.cfg) h_kwargs.update(harmonic_groups_args(self.cfg)) self.fishlist, fzero_harmonics, self.mains, self.allpeaks, peaks, lowth, highth, center = harmonic_groups( freqs, power, verbose=self.verbose, **h_kwargs) highth = center + highth - 0.5 * lowth lowth = center + 0.5 * lowth # spectrogram: t2 = t1 + nfft specpower, freqs, bins = ml.specgram(self.data[t0:t2], NFFT=nfft, Fs=self.samplerate, noverlap=nfft // 2, detrend=ml.detrend_mean) z = decibel(specpower) z = np.flipud(z) extent = self.toffset, self.toffset + np.amax( bins), freqs[0], freqs[-1] self.axs.set_xlim(self.toffset, self.toffset + self.twindow) if self.spectrogram_artist == None: self.fmax = np.round((freqs[-1] / 4.0) / 100.0) * 100.0 min = highth min = np.percentile(z, 70.0) max = np.percentile(z, 99.9) + 30.0 # cm = plt.get_cmap( 'hot_r' ) cm = plt.get_cmap('jet') self.spectrogram_artist = self.axs.imshow(z, aspect='auto', extent=extent, vmin=min, vmax=max, cmap=cm, zorder=1) else: self.spectrogram_artist.set_data(z) self.spectrogram_artist.set_extent(extent) self.axs.set_ylim(self.fmin, self.fmax) # power spectrum: self.axp.set_xlim(self.fmin, self.fmax) if self.deltaf >= 1000.0: dfs = '%.3gkHz' % 0.001 * self.deltaf else: dfs = '%.3gHz' % self.deltaf tw = float(w) / self.samplerate if tw < 1.0: tws = '%.3gms' % (1000.0 * tw) else: tws = '%.3gs' % (tw) a = 2 * w // nfft - 1 # number of ffts m = '' if self.cfg['mainsFreq'][0] > 0.0: m = ', mains=%.0fHz' % self.cfg['mainsFreq'][0] if self.power_frequency_label == None: self.power_frequency_label = self.axp.set_xlabel( r'Frequency [Hz] (nfft={:d}, $\Delta f$={:s}: T={:s}/{:d}{:s})' .format(nfft, dfs, tws, a, m)) else: self.power_frequency_label.set_text( r'Frequency [Hz] (nfft={:d}, $\Delta f$={:s}: T={:s}/{:d}{:s})' .format(nfft, dfs, tws, a, m)) self.axp.set_xlim(self.fmin, self.fmax) if self.power_label == None: self.power_label = self.axp.set_ylabel('Power') if self.decibel: if len(self.allpeaks) > 0: self.allpeaks[:, 1] = decibel(self.allpeaks[:, 1]) power = decibel(power) pmin = np.min(power[freqs < self.fmax]) pmin = np.floor(pmin / 10.0) * 10.0 pmax = np.max(power[freqs < self.fmax]) pmax = np.ceil(pmax / 10.0) * 10.0 doty = pmax - 5.0 self.power_label.set_text('Power [dB]') self.axp.set_ylim(pmin, pmax) else: pmax = np.max(power[freqs < self.fmax]) doty = pmax pmax *= 1.1 self.power_label.set_text('Power') self.axp.set_ylim(0.0, pmax) if self.all_peaks_artis == None: self.all_peaks_artis, = self.axp.plot( self.allpeaks[:, 0], np.zeros(len(self.allpeaks[:, 0])) + doty, 'o', color='#ffffff') self.good_peaks_artist, = self.axp.plot(peaks, np.zeros(len(peaks)) + doty, 'o', color='#888888') else: self.all_peaks_artis.set_data( self.allpeaks[:, 0], np.zeros(len(self.allpeaks[:, 0])) + doty) self.good_peaks_artist.set_data(peaks, np.zeros(len(peaks)) + doty) labels = [] fsizes = [ np.sqrt(np.sum(self.fishlist[k][:, 1])) for k in range(len(self.fishlist)) ] fmaxsize = np.max(fsizes) if len(fsizes) > 0 else 1.0 for k in range(len(self.peak_artists)): self.peak_artists[k].remove() self.peak_artists = [] for k in range(len(self.fishlist)): if k >= len(self.markerrange): break fpeaks = self.fishlist[k][:, 0] fpeakinx = [ int(np.round(fp / self.deltaf)) for fp in fpeaks if fp < freqs[-1] ] fsize = 7.0 + 10.0 * (fsizes[k] / fmaxsize)**0.5 fishpoints, = self.axp.plot( fpeaks[:len(fpeakinx)], power[fpeakinx], linestyle='None', color=self.colorrange[k % len(self.colorrange)], marker=self.markerrange[k], ms=fsize, mec=None, mew=0.0, zorder=1) self.peak_artists.append(fishpoints) if self.deltaf < 0.1: labels.append('%4.2f Hz' % fpeaks[0]) elif self.deltaf < 1.0: labels.append('%4.1f Hz' % fpeaks[0]) else: labels.append('%4.0f Hz' % fpeaks[0]) if len(self.mains) > 0: fpeaks = self.mains[:, 0] fpeakinx = [ np.round(fp / self.deltaf) for fp in fpeaks if fp < freqs[-1] ] fishpoints, = self.axp.plot(fpeaks[:len(fpeakinx)], power[fpeakinx], linestyle='None', marker='.', color='k', ms=10, mec=None, mew=0.0, zorder=2) self.peak_artists.append(fishpoints) labels.append('%3.0f Hz mains' % self.cfg['mainsFreq'][0]) ncol = (len(labels) - 1) // 8 + 1 self.legendhandle = self.axs.legend(self.peak_artists[:len(labels)], labels, loc='upper right', ncol=ncol) self.legenddict = dict() for legpoints, (finx, fish) in zip(self.legendhandle.get_lines(), enumerate(self.fishlist)): legpoints.set_picker(8) self.legenddict[legpoints] = [finx, fish] self.legendhandle.set_visible(self.legend) if self.power_artist == None: self.power_artist, = self.axp.plot(freqs, power, 'b', zorder=3) else: self.power_artist.set_data(freqs, power) if draw: self.fig.canvas.draw()
def make(self, raw_audio, samp_freq): """makes spectrogram using assigned properties Parameters ---------- raw_audio : 1-d numpy array raw audio waveform samp_freq : integer scalar sampling frequency in Hz Returns ------- spect : 2-d numpy array freq_bins : 1-d numpy array time_bins : 1-d numpy array """ if self.filterFunc == 'diff': raw_audio = np.diff(raw_audio) # differential filter_func, as applied in Tachibana Okanoya 2014 elif self.filterFunc == 'bandpass_filtfilt': raw_audio = hvc.evfuncs.bandpass_filtfilt(raw_audio, samp_freq, self.freqCutoffs) elif self.filterFunc == 'butter_bandpass': raw_audio = butter_bandpass_filter(raw_audio, samp_freq, self.freqCutoffs) try: # try to make spectrogram if self.spectFunc == 'scipy': if self.window is not None: freq_bins, time_bins, spect = scipy.signal.spectrogram(raw_audio, samp_freq, window=self.window, nperseg=self.nperseg, noverlap=self.noverlap) else: freq_bins, time_bins, spect = scipy.signal.spectrogram(raw_audio, samp_freq, nperseg=self.nperseg, noverlap=self.noverlap) elif self.spectFunc == 'mpl': # note that the matlab specgram function returns the STFT by default # whereas the default for the matplotlib.mlab version of specgram # returns the PSD. So to get the behavior of matplotlib.mlab.specgram # to match, mode must be set to 'complex' # I think I determined empirically at one point (by staring at single # cases) that mlab.specgram gave me values that were closer to Matlab's # specgram function than scipy.signal.spectrogram # Matlab's specgram is what Tachibana used in his original feature # extraction code. So I'm maintaining the option to use it here. # 'mpl' is set to return complex frequency spectrum, # not power spectral density, # because some tachibana features (based on CUIDADO feature set) # need to use the freq. spectrum before taking np.abs or np.log10 if self.window is not None: spect, freq_bins, time_bins = specgram(raw_audio, NFFT=self.nperseg, Fs=samp_freq, window=self.window, noverlap=self.noverlap, mode='complex') else: spect, freq_bins, time_bins = specgram(raw_audio, NFFT=self.nperseg, Fs=samp_freq, noverlap=self.noverlap, mode='complex') except ValueError as err: # if `try` to make spectrogram raised error if str(err) == 'window is longer than input signal': raise WindowError() else: # unrecognized error raise if self.remove_dc: # remove zero-frequency component freq_bins = freq_bins[1:] spect = spect[1:,:] # we take the absolute magnitude # because we almost always want just that for our purposes spect = np.abs(spect) if self.logTransformSpect: spect = np.log10(spect) # log transform to increase range if self.thresh is not None: spect[spect < self.thresh] = self.thresh # below, I set freq_bins to >= freq_cutoffs # so that Koumura default of [1000,8000] returns 112 freq. bins if self.freqCutoffs is not None: f_inds = np.nonzero((freq_bins >= self.freqCutoffs[0]) & (freq_bins <= self.freqCutoffs[1]))[0] # returns tuple freq_bins = freq_bins[f_inds] spect = spect[f_inds, :] return spect, freq_bins, time_bins
def make_spectrogram(self, raw_audio, chunk_size=1000): ''' Given data, compute a spectrogram. To avoid slow memory issues build the spectrogram in a stream-like fashion where we build it in chunk sizes of 1000 spectrogram frames Assumptions: o self.framerate contains the data framerate o self.nfft contains the window size o self.hop contains the hop size for fft o self.pad_to contains the zero-padding that we add if self.pad_to > self.nfft Returns a two-tuple: an array of segment times and a 2D spectrogram array @param data: the time/amplitude data @type data: np.array([float]) @param chunk_size: controls the incremental size used to build up the spectrogram @type chunk_size: int @return: (time slices arrya, spectrogram) @rtype: (np.array([float]), np.array([float])) ''' # The time_labels will be in seconds. But # they will be fractions of a second, like # 0.256, ... 1440 self.log.info("Creating spectrogram...") # Compute the number of raw audio frames # needed to generate chunk_size spec frames len_chunk = (chunk_size - 1) * self.hop + self.nfft final_spec = None slice_times = None start_chunk = 0 # Generate 1000 spect frames at a time, being careful to follow the correct indexing at the boarders to # "simulate" the full fft. Namely, if we use indeces (raw_start, raw_end) to get the raw_audio frames needed # to generate the spectrogram chunk, remember the next chunk does not start at raw_end but actually start # and (raw_end - NFFT) + hop. **THIS IS KEY** to propertly simulate the full spectrogram creation process iteration = 0 print("Approx number of chunks:", int(raw_audio.shape[0] / len_chunk)) while start_chunk + len_chunk < raw_audio.shape[0]: if (iteration % 100 == 0): print("Chunk number " + str(iteration)) [spectrum, freqs, t] = ml.specgram(raw_audio[start_chunk:start_chunk + len_chunk], NFFT=self.nfft, Fs=self.framerate, noverlap=(self.nfft - self.hop), window=ml.window_hanning, pad_to=self.pad_to) # Cutout uneeded high frequencies! spectrum = spectrum[(freqs <= self.max_freq)] if start_chunk == 0: final_spec = spectrum slice_times = t else: final_spec = np.concatenate((final_spec, spectrum), axis=1) # Shift t to be 0 started than Offset the new times # by the last frame's time + the time gap between frames (= hop / fr) t = t - t[0] + slice_times[-1] + (self.hop / self.framerate) slice_times = np.concatenate((slice_times, t)) # Remember that we want to start as if we are doing one continuous sliding window start_chunk += len_chunk - self.nfft + self.hop iteration += 1 # Do one final chunk for whatever remains at the end [spectrum, freqs, t] = ml.specgram(raw_audio[start_chunk:], NFFT=self.nfft, Fs=self.framerate, noverlap=(self.nfft - self.hop), window=ml.window_hanning, pad_to=self.pad_to) # Cutout the high frequencies that are not of interest spectrum = spectrum[(freqs <= self.max_freq)] final_spec = np.concatenate((final_spec, spectrum), axis=1) # Update the times: t = t - t[0] + slice_times[-1] + (self.hop / self.framerate) slice_times = np.concatenate((slice_times, t)) # check the shape of this self.log.info("Done creating spectrogram.") # This we may actually want to do! Log transform!!! # Transformer for magnitude to power dB: #amp_to_dB_transformer = torchaudio.transforms.AmplitudeToDB() #freq_time_dB_tensor = amp_to_dB_transformer(torch.Tensor(freq_time)) # Note transpose the spectrogram to be of shape - (time, freq) return final_spec.T, slice_times
LEEG3_selection[0].T) #plots on top of previous plot with same y axis # Plotting data with channel names channel_names = ['L_EEG_3', 'R_EEG_4'] two_eeg_chans = raw[channel_names, start_sample:stop_sample] y_offset = np.array([1e-4, 0]) # just enough to separate the channel traces x = two_eeg_chans[1] y = two_eeg_chans[0].T + y_offset lines = plt.plot(x, y) plt.legend(lines, channel_names) #%% # Plotting spectrogram for first 50 seconds of first channel NFFT = 1024 # the length of the windowing segments spectrum1, freqs1, bins = mlab.specgram(LEEG3_selection[0][0], NFFT=NFFT, Fs=Fs, noverlap=900) spectrum2, freqs2, bins = mlab.specgram(REEG4_selection[0][0], NFFT=NFFT, Fs=Fs, noverlap=900) # Only run for [0,5000] min_val = 5 * np.log10(min(spectrum1.min(), spectrum2.min())) max_val = 15.5 * np.log10(min(spectrum1.max(), spectrum2.max())) start_stop_seconds = np.array([0, 5000]) start_sample, stop_sample = (start_stop_seconds * Fs).astype(int) cmap = plt.get_cmap('magma') cmap.set_under(color='k', alpha=None)
ax1 = plt.subplot(311) t_sec = np.array(range(0, f_eeg_data_uV.size)) / fs_Hz plt.plot(t_sec, f_eeg_data_uV) plt.ylim(-100, 100) plt.ylabel('EEG (uV)') plt.xlabel('Time (sec)') plt.title(fname) plt.xlim(t_sec[0], t_sec[-1]) # make spectrogram ax = plt.subplot(312, sharex=ax1) overlap = NFFT - int(0.25 * fs_Hz) # quarter-second steps spec_PSDperHz, freqs, t_spec = mlab.specgram( np.squeeze(f_eeg_data_uV), NFFT=NFFT, window=mlab.window_hanning, Fs=fs_Hz, noverlap=overlap) # returns PSD power per Hz spec_PSDperBin = spec_PSDperHz * fs_Hz / float(NFFT) #convert to "per bin" del spec_PSDperHz # remove this variable so that I don't mistakenly use it #reduce size full_spec_PSDperBin = spec_PSDperBin full_t_spec = t_spec spec_PSDperBin = full_spec_PSDperBin[:, 1:-1:2] # get every other time slice t_spec = full_t_spec[1:-1:2] # get every other time slice plt.pcolor(t_spec, freqs, 10 * np.log10(spec_PSDperBin)) # dB re: 1 uV plt.clim(25 - 5 + np.array([-40, 0])) plt.xlim(t_sec[0], t_sec[-1]) if (t_lim_sec[2 - 1] != 0):
def plot_spectrogram(st, start_sec, end_sec, vmin, vmax, fkhz_min, fkhz_max, adcp=''): def _nearest_pow_2(x): a = M.pow(2, M.ceil(np.log2(x))) b = M.pow(2, M.floor(np.log2(x))) if abs(a - x) < abs(b - x): return a else: return b spec_data = st.slice(st[0].stats.starttime + start_sec, st[0].stats.starttime + end_sec) fs = st[0].stats.sampling_rate wlen = 0.056 # bin size in sec npts = len(spec_data[0]) end = npts / fs nfft = int(_nearest_pow_2(wlen * fs)) # number of fft points of each bin print(nfft) per_lap = 0.10 # percentage of overlap nlap = int(nfft * float(per_lap)) # number of overlapped samples # remove ADCP if adcp == 'energy': samples = remove_adcp_energy(spec_data[0].data, nfft) #elif adcp == 'period': # samples = remove_adcp_periodicity(spec_data[0].data, fs) else: samples = spec_data[0].data # using mlab to create the array of spectrogram specgram, freq, time = mlab.specgram(samples, NFFT=nfft, Fs=fs, noverlap=nlap, pad_to=None) specgram = 10 * np.log10(specgram[1:, :]) + 169 - 128.9 specgram = np.flipud(specgram) freq = freq[1:] / 1e3 # Convert Frequency to kHz halfbin_time = (time[1] - time[0]) / 2.0 halfbin_freq = (freq[1] - freq[0]) / 2.0 freq = np.concatenate((freq, [freq[-1] + 2 * halfbin_freq])) time = np.concatenate((time, [time[-1] + 2 * halfbin_time])) extent = (time[0] - halfbin_time, time[-1] + halfbin_time, freq[0] - halfbin_freq, freq[-1] + halfbin_freq) # colormap setting #vmin = 0.50 # default should be 0 to start from the min number of the spectrgram #vmax = 0.90 # default should be 1 to end at the max number of the spectrgram _range = float(specgram.max() - specgram.min()) vmin = specgram.min() + vmin * _range vmax = specgram.min() + vmax * _range norm = Normalize( vmin, vmax ) # to scale a 2-D float X input to the (0, 1) range for input to the cmap # plot spectrogram fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111) cax = ax.imshow(specgram, interpolation="nearest", extent=extent, norm=norm, cmap='viridis') dpi = fig.get_dpi() fig.set_size_inches(512 / float(dpi), 512 / float(dpi)) ax.axis('tight') ax.set_xlim(0, end) ax.set_ylim(fkhz_min, fkhz_max) ax.grid(False) ax.set_xlabel('Time [s]') ax.set_ylabel('Frequency [kHz]') ax.set_title(spec_data[0].stats.starttime) cbar = fig.colorbar(cax)
dict_995 = np.load('../Ads_fingerprint_99.5.npy').item() while 1 != 2: sleep(2) #onlyfiles = [f for f in os.listdir() if os.path.isfile(str(f))] time_stamp_list = [] for k in os.listdir(): #onlyfiles: time_stamp_list.append(time.ctime(os.path.getmtime(str(k)))) Latest_Stream = os.listdir()[time_stamp_list.index(max(time_stamp_list))] rate1, song_array1 = wavfile.read(Latest_Stream) #rate2, song_array2 = wavfile.read('Josh-Woodward--I-Want-To-Destroy-Something-Beautiful_21sec_cut.wav') spec1, freqs1, t1 = specgram(song_array1[:, 0], NFFT=4096, Fs=rate1, noverlap=2048) #spec2, freqs2, t2 = specgram(song_array2[:,0], NFFT=4096, Fs=rate2, noverlap=2048) spec1[spec1 == 0] = 1e-6 #spec2[spec2 == 0] = 1e-6 min_freq = 0 max_freq = 15000 Z1, freqs1 = cut_specgram(min_freq, max_freq, spec1, freqs1) #Z2, freqs2 = cut_specgram(min_freq, max_freq, spec2, freqs2) coordinates1 = peak_local_max(Z1, min_distance=20, threshold_abs=20) #coordinates2 = peak_local_max(Z2, min_distance=20, threshold_abs=20) #len(song_array2)/len(song_array1) ad_vec = 0 tvec = {} for ix in dict_995.keys(): idx = 0
tock() # normalise if settings['normalise_volume']: print "Normalise volume" X_downsampled -= X_downsampled.mean(1).reshape(-1, 1) X_downsampled /= X_downsampled.std(1).reshape(-1, 1) tock() # compute spectrograms print "Compute spectrograms" nfft = settings['specgram_num_components'] noverlap = nfft * (1 - 1. / settings['specgram_redundancy']) log_scale = settings['log_scale'] dummy = specgram(X_downsampled[0], NFFT=nfft, noverlap=noverlap)[0] # to get the dimensions X_specgram = np.zeros((X.shape[0], dummy.shape[0], dummy.shape[1]), dtype=X.dtype) for k in xrange(X.shape[0]): X_specgram[k] = specgram(X_downsampled[k], NFFT=nfft, noverlap=noverlap)[0] X_specgram = np.log(1 + log_scale * X_specgram) tock() if 'lnorm' in settings and settings[ 'lnorm']: # check presence first for backwards compatibility print "Locally normalise spectrograms" lnorm_sigma_mean = settings['lnorm_sigma_mean'] lnorm_sigma_std = settings['lnorm_sigma_std']
def get_specgram(data): arr2D, freqs, bins = specgram(data, window=window_hanning, Fs=fs_Hz, NFFT=nfft, noverlap=overlap) return arr2D, freqs, bins
print 'Data: {} samples'.format(data.size) print 'Data Min/Max: ',data.min(),data.max() data = data << (16 - NBPS) data = data >> (16 - NBPS) print 'Data Min/Max: ',data.min(),data.max() if data.min() <= -2**(NBPS-1) : print 'Warning: MIN Saturated !!!!!' elif data.min() < -2**(NBPS-1)+16 : print 'Note: MIN close to be saturated !!!!!' if data.max() >= 2**(NBPS-1)-1 : print 'Warning: MAX Saturated !!!!!' elif data.max() > 2**(NBPS-1)-16 : print 'Note: MAX close to be saturated !!!!!' data = data.astype(float) * (2**-(NBPS-1)); #scale to 0dBFS data = np.multiply(data, np.cos((np.arange(data.size)*2*np.pi*120.0/240.0)+0.06287)) spectrum, unused1, unused2 = mlab.specgram(data, NFFT=NFFT, window = np.blackman(NFFT), noverlap=NFFT*overlap) spectrum /= NFFT/8; print 'Spectrogram shape: {0[0]}:{0[1]}'.format(spectrum.shape) cum_hist = spec_hist(spectrum, NFFT=NFFT, Pmin=Pmin, aspect=aspect) im = Image.fromarray( norm255(np.log2(cum_hist)) ) im.putpalette(getpalette(plt.cm.gnuplot2)) im = im.convert('RGBA').rotate(90) bg = Image.new('RGBA', im.size, (0, 0, 0, 0)) draw = ImageDraw.Draw(bg) FONTSIZE = 12 font = ImageFont.truetype("arial.ttf", FONTSIZE) for i in xrange(Pmax, FS_span, 5): # --- power level grid y = i*(float(bg.size[1])/FS_span)
def a2(x, fm, plim=None, dt=None, n=None, tw=None, dlog2p=None, s0=None): # subharmonic summation #VARIABLES if plim is None: # rango de los candidatos a altura plim = [50, 800] if dt is None: # tiempo entre estimados de altura dt = 0.010 if n is None: # cantidad de armonicas a analizar n = 7 if tw is None: # tamano de la ventana (segundos) tw = 0.050 if dlog2p is None: # distancia entre los candidatos (octavas) dlog2p = 1 / 48 if s0 is None: # umbral de claridad de altura s0 = 0 # CANDIDATES log2pc = arange(log2(plim[0]), log2(plim[1]), dlog2p) # log2 de los candidatos a altura pc = 2**log2pc # candidatos a altura # VENTANA ws = 2**round(log2(tw * fm)) # tamano de la ventana (muestras) w = hann(ws) # ventana Hann de tamano ws o = ws / 2 # traslape entre las ventanas (recomendado para ventana Hann: 50%) # SIGNAL t = arange(0, len(x) / fm, dt) # tiempos de los estimados de altura x = concatenate( (zeros(ws // 2), x, zeros(ws // 2)) ) # se agregan ceros al principio para garantizar que ventanas cubran principio y final de la senal S = zeros( (len(pc), len(t))) # matriz de puntos de los candidatos a lo largo del tiempo (X, f, tj) = specgram( x, ws, fm, window=w, noverlap=o, mode='magnitude' ) # calculo del espectro; devuelve tambien frecuencias y tiempos # INTERATE OVER THE CANDIDATES for i in range(0, len(pc)): # para cada candidato: fi = pc[i] * arange(1, n + 1) # identifique primeras n armonicas A = zeros((len(fi), X.shape[1])) # cree matriz nArmonicas x nVentanas for j in range(0, X.shape[1]): # por cada ventana: A[:, j] = interp(fi, f, X[:, j]) # estime el espectro en las armonicas si = sum( A, 0 ) # calcule el puntaje del candidato en cada ventana multiplicando el valor del espectro en las armonicas S[i, :] = interp(t, tj, si) # interpole los puntajes a los tiempos deseados p = pc[argmax( S, 0)] # escoja el candidato con mayor puntuacion en cada ventana s = amax(S, 0) # registre la puntuacion obtenida p[s < s0] = float( 'nan') # # indefina alturas cuyo puntaje no excede el umbral return ( p, t, s, pc, S ) # devuelva ganadores, tiempos, puntajes, lista de candidatos y matriz de puntajes
def spectrogram1(data, samp_rate, per_lap=0.9, wlen=None, log=False, fmt=None, dbscale=False, y_lim=False, title=False, fig_mark=[0], xtime_offset=0, mult=8.0, axes=False, zorder=None, clip=[0.0, 1.0]): samp_rate = float(samp_rate) if not wlen: wlen = samp_rate / 100.0 npts = len(data) nfft = int(_nearest_pow_2(wlen * samp_rate)) if nfft > npts: nfft = int(_nearest_pow_2(npts / 8.0)) if mult is not None: mult = int(_nearest_pow_2(mult)) mult = mult * nfft nlap = int(nfft * float(per_lap)) # data = data - data.mean() end = npts / samp_rate specgram, freq, time = mlab.specgram(data, Fs=samp_rate, NFFT=nfft, pad_to=mult, noverlap=nlap) if dbscale: specgram = 10 * np.log10(specgram[1:, :]) else: specgram = np.sqrt(specgram[1:, :]) freq = freq[1:] vmin, vmax = clip if vmin < 0 or vmax > 1 or vmin >= vmax: msg = "Invalid parameters for clip option." raise ValueError(msg) _range = float(specgram.max() - specgram.min()) vmin = specgram.min() + vmin * _range vmax = specgram.min() + vmax * _range norm = Normalize(vmin, vmax, clip=True) if not axes: fig = plt.figure() ax = fig.add_subplot(111) else: ax = axes halfbin_time = (time[1] - time[0]) / 2.0 halfbin_freq = (freq[1] - freq[0]) / 2.0 if log: # pcolor expects one bin more at the right end freq = np.concatenate((freq, [freq[-1] + 2 * halfbin_freq])) time = np.concatenate((time, [time[-1] + 2 * halfbin_time])) # center bin time -= halfbin_time freq -= halfbin_freq time = time + xtime_offset # Log scaling for frequency values (y-axis) ax.set_yscale('log') # Plot times ax.pcolormesh(time, freq, specgram, norm=norm, cmap=plt.cm.jet) else: # this method is much much faster! specgram = np.flipud(specgram) # center bin extent = (time[0] - halfbin_time + xtime_offset, time[-1] + halfbin_time + xtime_offset, freq[0] - halfbin_freq, freq[-1] + halfbin_freq) ax.imshow(specgram, interpolation="nearest", extent=extent, cmap=plt.cm.jet) if y_lim: ax.vlines(fig_mark, y_lim[0], y_lim[1], color='r') else: ax.vlines(fig_mark, y_lim[0], y_lim[1], color='r') ax.axis('tight') # ax.set_xlim(0,end) # if xtime_offset: # ax.set_xlim(0+xtime_offset, end+xtime_offset) # ih = 0 # while 0.5*ih<end: # ih = ih+1 # xraw_ticks = np.linspace(0,ih*0.5,ih,endpoint=False) # xnew_ticks = xraw_ticks + xtime_offset # ax.set_xticks(list(xraw_ticks),list(xnew_ticks)) # else: # ax.set_xlim(0, end) if y_lim: ax.set_ylim(y_lim[0], y_lim[1]) ax.grid(False) # ax.set_xlabel('Time [s]') # ax.set_ylabel('Frequency [Hz]') if title: ax.set_title(title) return specgram, freq, time
def plots(self, num_channels=8): """ Plot the raw and filtered data Input: - num_channels: number of channels to plot """ fig = plt.figure() for channel in range(num_channels): #fig = plt.figure() #fig.suptitle(self.name_channel[channel]) self.t_sec = np.array(range( 0, self.raw_eeg_data[:, channel].size)) / self.sample_rate ax1 = plt.subplot(321) plt.plot(self.t_sec, self.raw_eeg_data[:, channel], label=self.name_channel[channel]) plt.ylabel('EEG (uV)') plt.xlabel('Time (sec)') plt.title('Raw') plt.xlim(self.t_sec[0], self.t_sec[-1]) psd, freqs = mlab.psd(np.squeeze(self.raw_eeg_data[:, channel]), NFFT=500, Fs=250) ax2 = plt.subplot(322) plt.xlim(self.t_sec[0], self.t_sec[-1]) plt.xlabel('Frequency (Hz)') plt.ylabel('Power') plt.ylim(0, 20 * np.median(psd)) plt.plot(freqs, psd, label=self.name_channel[channel]) plt.title('PSD of Unfiltered') raw_spec_PSDperHz, raw_freqs, raw_t_spec = mlab.specgram( np.squeeze(raw_eeg_data[:, channel]), NFFT=NFFT, window=mlab.window_hanning, Fs=sample_rate, noverlap=overlap) raw_spec_PSDperBin = raw_spec_PSDperHz * sample_rate / float(NFFT) ax2 = plt.subplot(323) plt.pcolor(raw_t_spec, raw_freqs, 10 * np.log10(raw_spec_PSDperBin)) plt.clim(25 - 5 + np.array([-40, 0])) plt.xlim(t_sec[0], t_sec[-1]) plt.ylim([0, 100]) plt.xlabel('Time (sec)') plt.ylabel('Frequency (Hz)') plt.title('Spectogram of Unfiltered') ax3 = plt.subplot(323) plt.plot(self.t_sec, self.corrected_eeg_data[:, channel], label=self.name_channel[channel]) plt.ylabel('EEG (uV)') plt.xlabel('Time (sec)') plt.title('Filtered') plt.xlim(self.t_sec[0], self.t_sec[-1]) psd, freqs = mlab.psd(np.squeeze(self.corrected_eeg_data[:, channel]), NFFT=500, Fs=250) ax4 = plt.subplot(324) plt.xlim(self.t_sec[0], self.t_sec[-1]) plt.xlabel('Frequency (Hz)') plt.ylabel('Power') plt.ylim(0, 20 * np.median(psd)) plt.plot(freqs, psd, label=self.name_channel[channel]) plt.title('PSD of filtered') plt.legend(self.name_channel, loc='upper right', bbox_to_anchor=(0.01, 0.01)) plt.tight_layout() plt.show()
def test_specgram_warn_only1seg(self): """Warning should be raised if len(x) <= NFFT.""" with pytest.warns(UserWarning, match="Only one segment is calculated"): mlab.specgram(x=self.y, NFFT=len(self.y), Fs=self.Fs)