Esempio n. 1
0
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
Esempio n. 2
0
    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