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
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
def block_lfilter_wav(b, a, x, outfile, fmt, fs, blocksize=8192): ''' Filter 1D signal in blocks. For use with large signals ''' new_state = np.zeros(b.size - 1) sndfile = PySndfile(outfile, 'w', fmt, 1, fs) i = 0 y_out = np.zeros(x.size) y_max = 0.0 while i < x.size: print("Filtering {0} to {1} of {2}".format(i, i + blocksize, x.size)) if i + blocksize > x.size: y, new_state = sgnl.lfilter(b, a, x[i:-1], zi=new_state) sndfile.write_frames(y) y_out[i:i + y.size] = y else: y, new_state = sgnl.lfilter(b, a, x[i:i + blocksize], zi=new_state) sndfile.write_frames(y) y_out[i:i + y.size] = y y_max = np.max([y_max, np.abs(y).max()]) i += blocksize return y_out, y_max
def write(name, vec, rate=44100, format="aiff", enc='pcm16'): """ Write datavector to aiff file using amplerate and encoding as specified """ nchans = len(vec.shape) if nchans != 1: nchans = vec.shape[1] sf = PySndfile(name, "w", format=construct_format(formt, enc), channels=nchans, samplerate=rate) nf = sf.write_frames(vec) if nf != vec.shape[0]: raise IOError("sndio.write::error::writing of samples failed") return nf
def write(name, data, rate=44100, format="aiff", enc='pcm16') : """ Write datavector to sndfile using samplerate, format and encoding as specified valid format strings are all the keys in the dict pysndfile.fileformat_name_to_id valid encodings are those that are supported by the selected format from the list of keys in pysndfile.encoding_name_to_id. """ nchans = len(data.shape) if nchans == 2 : nchans = data.shape[1] elif nchans != 1: raise RuntimeError("error:sndio.write:can only be called with vectors or matrices ") sf = PySndfile(name, "w", format=construct_format(format, enc), channels = nchans, samplerate = rate) nf = sf.write_frames(data) if nf != data.shape[0]: raise IOError("sndio.write::error::writing of samples failed") return nf
def main(): stim_dir = "../behavioural_stim/stimulus" wav_dir = "../behavioural_stim/stimulus/wav" base_dir = "../behavioural_stim/stimulus/wav/sentence-lists/" noise_dir = "../behavioural_stim/stimulus/wav/noise/" out_dir = "./out" dir_must_exist(base_dir) dir_must_exist(out_dir) dir_must_exist(wav_dir) dir_must_exist(noise_dir) noise_filepath = "../behavioural_stim/stimulus/wav/noise/noise_norm.wav" folders = os.listdir(base_dir) folders = natsorted(folders)[1:15] folders = list(zip(folders[::2], folders[1::2])) calc_potential_max(base_dir, noise_filepath, out_dir) n_questions = 4 fs = 44100 for ind, (list_folder_1, list_folder_2) in enumerate(folders): out_folder_name = 'Stim_{}'.format(ind) out_folder = os.path.join(out_dir, out_folder_name) delete_if_exists(out_folder) dir_must_exist(out_folder) out_wav_path = os.path.join(out_folder, "stim.wav") out_csv_path = os.path.join(out_folder, "markers.csv") out_rms_path = os.path.join(out_folder, "rms.npy") out_q_path = [ os.path.join(out_folder, "questions_{}.csv".format(x)) for x in range(n_questions) ] out_wav = PySndfile(out_wav_path, 'w', construct_format('wav', 'pcm16'), 3, 44100) list_1_wav = globDir(os.path.join(base_dir, list_folder_1), '*.wav') list_2_wav = globDir(os.path.join(base_dir, list_folder_2), '*.wav') list_1_csv = globDir(os.path.join(base_dir, list_folder_1), '*.csv') list_2_csv = globDir(os.path.join(base_dir, list_folder_2), '*.csv') merged_wavs = list_1_wav + list_2_wav merged_csvs = list_1_csv + list_2_csv words = [] for c in merged_csvs: with open(c, 'r') as csvfile: for line in csv.reader(csvfile): words.append(line) c = list(zip(merged_wavs, words)) shuffle(c) merged_wavs, words = zip(*c) sum_sqrd = 0. n = 0 with open(out_csv_path, 'w') as csvfile, ExitStack() as stack: # Open all question files qfiles = [ stack.enter_context(open(qfile, 'w')) for qfile in out_q_path ] writer = csv.writer(csvfile) qwriters = [csv.writer(qfile) for qfile in qfiles] counter = 0 stim_count = len(merged_wavs) stim_count_half = stim_count // 2 q_inds = np.array([ sample(range(0, stim_count_half), n_questions), sample(range(stim_count_half, stim_count - 1), n_questions) ]).T a = 0 silence = np.zeros((88200, 3)) idx = np.arange(0, silence.shape[0]) trigger = gen_trigger(idx, 2., 0.01, fs) silence[:, 2] = trigger out_wav.write_frames(silence) for ind, (wav, txt) in enumerate(zip(merged_wavs, words)): csv_line = [counter] silence = np.zeros((int( np.random.uniform(int(0.3 * 44100), int(0.4 * 44100), 1)), 3)) idx = np.arange(counter, counter + silence.shape[0]) trigger = gen_trigger(idx, 2., 0.01, fs) silence[:, 2] = trigger out_wav.write_frames(silence) counter += silence.shape[0] csv_line.append(counter) csv_line.append("#") writer.writerow(csv_line) csv_line = [counter] x, fs, enc = sndio.read(wav) sum_sqrd += np.sum(x**2) n += x.size y = np.vstack([x, x, np.zeros(x.size)]).T idx = np.arange(counter, counter + y.shape[0]) trigger = gen_trigger(idx, 2., 0.01, fs) y[:, 2] = trigger out_wav.write_frames(y) counter += y.shape[0] csv_line.append(counter) csv_line.append(" ".join(txt)) writer.writerow(csv_line) if ind in q_inds: writer_ind = int(np.where(ind == q_inds)[0]) blank_ind = randint(0, len(txt) - 1) q_list = copy(txt) q_list[blank_ind] = '_' qwriters[writer_ind].writerow( [" ".join(q_list), txt[blank_ind]]) a += 1 if a != 8: pdb.set_trace() csv_line = [counter] silence = np.zeros( (int(np.random.uniform(int(0.3 * 44100), int(0.4 * 44100), 1)), 3)) idx = np.arange(counter, counter + silence.shape[0]) trigger = gen_trigger(idx, 2., 0.01, fs) silence[:, 2] = trigger out_wav.write_frames(silence) counter += silence.size csv_line.append(counter) csv_line.append("#") writer.writerow(csv_line) rms = np.sqrt(sum_sqrd / n) np.save(out_rms_path, rms) x, fs, enc = sndio.read(out_wav_path)