Exemplo 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
Exemplo n.º 2
0
def block_mix_wavs(wavpath_a,
                   wavpath_b,
                   out_wavpath,
                   a_gain=1.,
                   b_gain=1.,
                   block_size=4096,
                   mute_left=False):
    '''
    Mix two wav files, applying gains to each
    '''
    wav_a = PySndfile(wavpath_a, 'r')
    wav_b = PySndfile(wavpath_b, 'r')

    out_wav = PySndfile(out_wavpath, 'w', construct_format('wav', 'pcm16'),
                        wav_a.channels(), wav_a.samplerate())

    i = 0
    while i < wav_a.frames():
        if i + block_size > wav_a.frames():
            block_size = wav_a.frames() - i
        x1 = wav_a.read_frames(block_size)
        x2 = wav_b.read_frames(block_size)
        x1[:, :2] *= a_gain
        x2 *= b_gain
        if x1.shape[1] == 3:
            y = np.zeros(x1.shape)
            y[:, 0] = x1[:, 0] + x2
            y[:, 1] = x1[:, 1] + x2
            y[:, 2] = x1[:, 2]
            if mute_left:
                y[:, 0] = 0.0
        else:
            y = x1 + x2
        out_wav.write_frames(y)
        i += block_size
Exemplo n.º 3
0
def synthesize_trial(wavFileMatrix, indexes):
    '''
    Using the matrix of alternative words and the selected words for each
    column, generate samples from audio files
    Returns an array of samples generated by concatenating the selected audio
    files
    '''
    columnNames = ['a', 'b', 'c', 'd', 'e']
    indexes = np.pad(indexes, ((0, 1)), 'constant', constant_values=0)
    indexes = rolling_window_lastaxis(indexes, 2)
    offset = 10
    y = np.array([])
    filenames = []
    for name, ind in zip(columnNames, indexes):
        if name == 'e':
            offset = 1
        wavFilename, wavFilepath = wavFileMatrix[name][(ind[0] * offset) +
                                                       ind[1]]
        wav = PySndfile(wavFilepath)
        fs = wav.samplerate()
        x = wav.read_frames()
        y = np.append(y, x)
        filenames.append(wavFilename)
    return (y, {
        'rate': fs,
        'format': wav.major_format_str(),
        'enc': wav.encoding_str()
    }, filenames)
Exemplo n.º 4
0
def gen_noise(OutDir, b, fs):
    print("Generating noise...")
    # Generate 10 minutes of white noise
    x = np.random.randn(int(fs * 60. * 5.))
    x /= x.max()
    noiseDir = os.path.join(OutDir, 'wav')
    noiseRMSDir = os.path.join(OutDir, 'rms')
    dir_must_exist(noiseDir)
    noiseDir = os.path.join(noiseDir, 'noise')
    dir_must_exist(noiseDir)
    y, y_max = block_lfilter_wav(b, [1.0], x,
                                 os.path.join(noiseDir, 'noise.wav'), 65538,
                                 44100)
    block_process_wav(os.path.join(noiseDir, 'noise.wav'),
                      os.path.join(noiseDir, 'noise_norm.wav'), lambda x: x /
                      (y_max * 1.05))
    noise_norm_wav = PySndfile(os.path.join(noiseDir, 'noise_norm.wav'), 'r')
    noise_rms_path = os.path.join(noiseRMSDir, 'noise_rms.npy')
    y = noise_norm_wav.read_frames(fs * 60)
    y = y / (np.abs(y).max() * 0.95)
    # rms = np.sqrt(np.mean(y**2))
    # rms, _, _ = asl_P56(y, fs, 16)
    rms = rms_no_silences(y, fs, -30.)
    print(f"Noise level: {rms}")

    peak = np.abs(y).max()
    np.save(noise_rms_path, rms)
    np.save('./stimulus/peak/noise_peak.npy', peak)
    return y
Exemplo n.º 5
0
def main():
    wavs = globDir('./out/stim/', '*.wav')
    silences = globDir('./out/stim/', 'stim_*_silence.npy')
    outDir = "./out/stim/"
    for wav, sil in zip(wavs, silences):
        snd = PySndfile(wav, 'r')
        fs = int(snd.samplerate())
        s = np.load(sil)
        sil_bool = slice_to_bool(s, snd.frames())

        rms = np.sqrt(np.mean(np.abs(snd.read_frames()[~sil_bool]**2)))

        head, tail = os.path.split(wav)
        tail = os.path.splitext(tail)[0]
        tail = tail + "_rms.npy"
        rms_filepath = os.path.join(outDir, tail)
        np.save(rms_filepath, rms)
Exemplo n.º 6
0
def main():
    wavs = globDir('./out/stim/', '*.wav')
    envs = globDir('./out/stim/', 'stim_*_env.npy')
    silences = globDir('./out/stim/', 'stim_*_silence.npy')
    for wavfp, envfp, silfp in zip(wavs, envs, silences):
        snd = PySndfile(wavfp, 'r')
        fs = int(snd.samplerate())
        env = np.load(envfp)
        sil_slices = np.load(silfp)
        sil = np.zeros(env.size)
        for sil_slice in sil_slices:
            sil[sil_slice[0]:sil_slice[1]] = 1
        pdb.set_trace()

        plt.plot(snd.read_frames(fs*60))
        plt.plot(sil[:fs*60])
        plt.show()
Exemplo n.º 7
0
def block_process_wav(wavpath, out_wavpath, func, block_size=4096, **args):
    '''
    Mix two wav files, applying gains to each
    '''
    wav = PySndfile(wavpath, 'r')

    out_wav = PySndfile(out_wavpath, 'w', construct_format('wav', 'pcm16'),
                        wav.channels(), wav.samplerate())

    i = 0
    while i < wav.frames():
        if i + block_size > wav.frames():
            block_size = wav.frames() - i
        x = wav.read_frames(block_size)
        y = func(x, **args)
        out_wav.write_frames(y)
        i += block_size
    del out_wav
Exemplo n.º 8
0
with open(outfile, "w") as f:
    f.write("/// Impulse response header, generated by ir_wav2h.py\n")
    f.write("/// Input file: {}\n\n".format(filename))
    f.write("#ifndef IR_{}_H\n#define IR_{}_H\n\n".format(
        nsname.upper(), nsname.upper()))
    f.write("#include <vector>\n\n".format(nsname))
    f.write("namespace {} {{\n\n".format(nsname))
    f.write("static const char* name = \"{}\";\n".format(name))
    f.write("static const char* vendor = \"{}\";\n".format(
        vendor.replace("_", " ")))
    f.write("static const char* mic = \"{}\";\n".format(mic.replace("_", " ")))
    f.write("static int samplerate =  {};\n\n".format(wav.samplerate()))
    f.write("static std::vector<double> frames = {{\n".format(nsname))
    first = True
    i = 0
    for s in wav.read_frames():
        if first:
            first = False
            f.write("    ")
        else:
            if i % 6 == 0:
                f.write(",\n    ")
            else:
                f.write(", ")
        f.write(str(s))
        i = i + 1

    f.write("\n};  // frames\n\n")
    f.write(
        "int __init__ = add_ir(name, vendor, mic, frames, samplerate);\n\n")
    f.write("}}   // {}\n\n".format(nsname))
Exemplo n.º 9
0
def read_audio(name_audio):
    soundIO = PySndfile(name_audio)

    frames = soundIO.read_frames()
    s_rate = soundIO.samplerate()
    return frames, s_rate
Exemplo n.º 10
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