def read(name, end=None, start=0, dtype=np.float64, return_format=False) : """read samples from arbitrary sound files. return data, samplerate and encoding string returns subset of samples as specified by start and end arguments (Def all samples) normalizes samples to [-1,1] if the datatype is a floating point type """ sf = PySndfile(name) enc = sf.encoding_str() nf = sf.seek(start, 0) if not nf == start: raise IOError("sndio.read::error:: while seeking at starting position") if end == None: ff = sf.read_frames(dtype=dtype) else: ff = sf.read_frames(end-start, dtype=dtype) # if norm and (enc not in ["float32" , "float64"]) : # if enc in enc_norm_map : # ff = ff / enc_norm_map[sf.encoding_str()] # else : # raise IOError("sndio.read::error::normalization of compressed pcm data is not supported") if return_format: return ff, sf.samplerate(), enc, sf.major_format_str() return ff, sf.samplerate(), enc
def loadStimulus(self): ''' ''' self.participant.load('mat_test') try: srt_50 = self.participant.data['mat_test']['srt_50'] s_50 = self.participant.data['mat_test']['s_50'] except KeyError: raise KeyError( "Behavioural matrix test results not available, make " "sure the behavioural test has been run before " "running this test.") save_dir = self.participant.data_paths['eeg_test/stimulus'] ''' # Estimate speech intelligibility thresholds using predicted # psychometric function s_50 *= 0.01 x = logit(self.si * 0.01) snrs = (x/(4*s_50))+srt_50 snrs = np.append(snrs, np.inf) snr_map = pd.DataFrame({"speech_intel" : np.append(self.si, 0.0), "snr": snrs}) snr_map_path = os.path.join(save_dir, "snr_map.csv") snr_map.to_csv(snr_map_path) snrs = np.repeat(snrs[np.newaxis], 4, axis=0) snrs = roll_independant(snrs, np.array([0,-1,-2,-3])) stim_dirs = [x for x in os.listdir(self.listDir) if os.path.isdir(os.path.join(self.listDir, x))] shuffle(stim_dirs) ''' snrs = self.participant.data['parameters']['decoder_test_SNRs'] + srt_50 stim_dirs = [ x for x in os.listdir(self.listDir) if os.path.isdir(os.path.join(self.listDir, x)) ] ordered_stim_dirs = [] for ind in self.participant_parameters['decoder_test_lists']: for folder in stim_dirs: if re.match(f'Stim_({int(ind)})', folder): ordered_stim_dirs.append(folder) # ordered_stim_dirs *= int(len(snrs)) noise_file = PySndfile(self.noise_path, 'r') wav_files = [] wav_metas = [] question = [] marker_files = [] self.socketio.emit('test_stim_load', namespace='/main') for ind, dir_name in enumerate(ordered_stim_dirs[:snrs.shape[1]]): logger.debug( f"Processing list directory {ind+1} of {snrs.shape[1]}") stim_dir = os.path.join(self.listDir, dir_name) wav = globDir(stim_dir, "*.wav")[0] csv_files = natsorted(globDir(stim_dir, "*.csv")) marker_file = csv_files[0] question_files = csv_files[1:] # rms_file = globDir(stim_dir, "*.npy")[0] # speech_rms = float(np.load(rms_file)) snr = snrs[:, ind] audio, fs, enc, fmt = sndio.read(wav, return_format=True) speech = audio[:, :2] triggers = audio[:, 2] #speech_rms, _, _ = asl_P56(speech, fs, 16.) rms_no_silences(speech, fs, -30.) wf = [] wm = [] for ind2, s in enumerate(snr): start = randint(0, noise_file.frames() - speech.shape[0]) noise_file.seek(start) noise = noise_file.read_frames(speech.shape[0]) noise_rms = np.sqrt(np.mean(noise**2)) # noise_rms = asl_P56(noise, fs, 16) snr_fs = 10**(-s / 20) if snr_fs == np.inf: snr_fs = 0. elif snr_fs == -np.inf: raise ValueError( "Noise infinitely louder than signal at snr: {}". format(snr)) noise = noise * (speech_rms / noise_rms) out_wav_path = os.path.join( save_dir, "Stim_{0}_{1}.wav".format(ind, ind2)) out_meta_path = os.path.join( save_dir, "Stim_{0}_{1}.npy".format(ind, ind2)) with np.errstate(divide='raise'): try: out_wav = (speech + (np.stack([noise, noise], axis=1) * snr_fs)) * self.reduction_coef except: set_trace() out_wav = np.concatenate([out_wav, triggers[:, np.newaxis]], axis=1) sndio.write(out_wav_path, out_wav, fs, fmt, enc) np.save(out_meta_path, s) wf.append(out_wav_path) wm.append(out_meta_path) wav_metas.append(wm) wav_files.append(wf) out_marker_path = os.path.join(save_dir, "Marker_{0}.csv".format(ind)) marker_files.append(out_marker_path) copyfile(marker_file, out_marker_path) for q_file in question_files: out_q_path = os.path.join( save_dir, "Questions_{0}_{1}.csv".format(ind, ind2)) self.question_files.append(out_q_path) copyfile(q_file, out_q_path) for q_file_path in question_files: q = [] with open(q_file_path, 'r') as q_file: q_reader = csv.reader(q_file) for line in q_reader: q.append(line) question.append(q) self.wav_files = [item for sublist in wav_files for item in sublist] self.wav_metas = [item for sublist in wav_metas for item in sublist] self.question.extend(question) for item in marker_files: self.marker_files.extend([item] * 4) self.answers = np.empty(np.shape(self.question)[:2]) self.answers[:] = np.nan