def test_rms(): """Test RMS calculation """ # Test a couple trivial things we know sin = np.sin(2 * np.pi * 1000 * np.arange(10000, dtype=float) / 10000.) assert_array_almost_equal(rms(sin), 1. / np.sqrt(2)) assert_array_almost_equal(rms(np.ones((100, 2)) * 2, 0), [2, 2])
def test_hrtf_convolution(): """Test HRTF convolution """ data = np.random.randn(2, 10000) assert_raises(ValueError, convolve_hrtf, data, 44100, 0) data = data[0] assert_raises(ValueError, convolve_hrtf, data, 44100, 0.5) # invalid angle out = convolve_hrtf(data, 44100, 0) out_2 = convolve_hrtf(data, 24414, 0) assert_equal(out.ndim, 2) assert_equal(out.shape[0], 2) assert_true(out.shape[1] > data.size) assert_true(out_2.shape[1] < out.shape[1]) # ensure that, at least for zero degrees, it's close out = convolve_hrtf(data, 44100, 0)[:, 1024:-1024] assert_allclose(np.mean(rms(out)), rms(data), rtol=1e-1) out = convolve_hrtf(data, 44100, -90) rmss = rms(out) assert_true(rmss[0] > 4 * rmss[1])
def test_hrtf_convolution(): """Test HRTF convolution """ data = np.random.randn(2, 10000) assert_raises(ValueError, convolve_hrtf, data, 44100, 0) data = data[0] assert_raises(ValueError, convolve_hrtf, data, 44100, 0.5) # invalid angle for source in ['barb', 'cipic']: out = convolve_hrtf(data, 44100, 0, source=source) out_2 = convolve_hrtf(data, 24414, 0, source=source) assert_equal(out.ndim, 2) assert_equal(out.shape[0], 2) assert_true(out.shape[1] > data.size) assert_true(out_2.shape[1] < out.shape[1]) # ensure that, at least for zero degrees, it's close out = convolve_hrtf(data, 44100, 0, source=source)[:, 1024:-1024] assert_allclose(np.mean(rms(out)), rms(data), rtol=1e-1) out = convolve_hrtf(data, 44100, -90, source=source) rmss = rms(out) assert_true(rmss[0] > 4 * rmss[1])
def test_hrtf_convolution(): """Test HRTF convolution.""" data = np.random.randn(2, 10000) assert_raises(ValueError, convolve_hrtf, data, 44100, 0, interp=False) data = data[0] assert_raises(ValueError, convolve_hrtf, data, 44100, 0.5, interp=False) assert_raises(ValueError, convolve_hrtf, data, 44100, 0, source='foo', interp=False) assert_raises(ValueError, convolve_hrtf, data, 44100, 90.5, interp=True) assert_raises(ValueError, convolve_hrtf, data, 44100, 0, interp='foo') # invalid angle when interp=False for interp in [True, False]: for source in ['barb', 'cipic']: if interp and source == 'barb': # raise an error when trying to interp with 'barb' assert_raises(ValueError, convolve_hrtf, data, 44100, 2.5, source=source, interp=interp) else: out = convolve_hrtf(data, 44100, 0, source=source, interp=interp) out_2 = convolve_hrtf(data, 24414, 0, source=source, interp=interp) assert_equal(out.ndim, 2) assert_equal(out.shape[0], 2) assert_true(out.shape[1] > data.size) assert_true(out_2.shape[1] < out.shape[1]) if interp: out_3 = convolve_hrtf(data, 44100, 2.5, source=source, interp=interp) out_4 = convolve_hrtf(data, 44100, -2.5, source=source, interp=interp) assert_equal(out_3.ndim, 2) assert_equal(out_4.ndim, 2) # ensure that, at least for zero degrees, it's close out = convolve_hrtf(data, 44100, 0, source=source, interp=interp)[:, 1024:-1024] assert_allclose(np.mean(rms(out)), rms(data), rtol=1e-1) out = convolve_hrtf(data, 44100, -90, source=source, interp=interp) rmss = rms(out) assert_true(rmss[0] > 4 * rmss[1])
def test_hrtf_convolution(): """Test HRTF convolution.""" data = np.random.randn(2, 10000) pytest.raises(ValueError, convolve_hrtf, data, 44100, 0, interp=False) data = data[0] pytest.raises(ValueError, convolve_hrtf, data, 44100, 0.5, interp=False) pytest.raises(ValueError, convolve_hrtf, data, 44100, 0, source='foo', interp=False) pytest.raises(ValueError, convolve_hrtf, data, 44100, 90.5, interp=True) pytest.raises(ValueError, convolve_hrtf, data, 44100, 0, interp='foo') # invalid angle when interp=False for interp in [True, False]: for source in ['barb', 'cipic']: if interp and source == 'barb': # raise an error when trying to interp with 'barb' pytest.raises(ValueError, convolve_hrtf, data, 44100, 2.5, source=source, interp=interp) else: out = convolve_hrtf(data, 44100, 0, source=source, interp=interp) out_2 = convolve_hrtf(data, 24414, 0, source=source, interp=interp) assert_equal(out.ndim, 2) assert_equal(out.shape[0], 2) assert (out.shape[1] > data.size) assert (out_2.shape[1] < out.shape[1]) if interp: out_3 = convolve_hrtf(data, 44100, 2.5, source=source, interp=interp) out_4 = convolve_hrtf(data, 44100, -2.5, source=source, interp=interp) assert_equal(out_3.ndim, 2) assert_equal(out_4.ndim, 2) # ensure that, at least for zero degrees, it's close out = convolve_hrtf(data, 44100, 0, source=source, interp=interp)[:, 1024:-1024] assert_allclose(np.mean(rms(out)), rms(data), rtol=1e-1) out = convolve_hrtf(data, 44100, -90, source=source, interp=interp) rmss = rms(out) assert (rmss[0] > 4 * rmss[1])
onset = tr_onset_samp[tnum, snum, wnum] offset = onset + len(samps) tr_mono[tnum, snum, onset:offset] += samps del word, samps, onset, offset # HRTF CONVOLUTION print('Convolving with HRTFs') stream_len = stim.convolve_hrtf(np.zeros(stream_len), output_fs, 0).shape[-1] tr_hrtf = np.zeros((trials, streams, 2, stream_len), dtype=float) for tnum in range(trials): for snum in range(streams): tr_hrtf[tnum, snum] = stim.convolve_hrtf(tr_mono[tnum, snum], output_fs, angles[snum]) # RENORMALIZE print('Renormalizing') tr_original_rms = stim.rms(tr_mono) tr_convolved_rms = np.mean(stim.rms(tr_hrtf), axis=-1) multiplier = tr_original_rms / tr_convolved_rms tr_norm = (tr_hrtf.T * multiplier.T).T # broadcasting tr_norm_rms = np.mean(stim.rms(tr_norm), axis=-1) # TODO: test RMS # COMBINE L & R CHANNELS ACROSS STREAMS tr_stim = np.sum(tr_norm, axis=1) tr_stim_rms = np.mean(stim.rms(tr_stim), axis=-1) # TODO: test RMS assert tr_hrtf.shape[0] == tr_stim.shape[0] assert tr_hrtf.shape[-2] == tr_stim.shape[-2] assert tr_hrtf.shape[-1] == tr_stim.shape[-1] # TRAINING STIMULI print('Constructing training stimuli') one_idx = np.where((np.sum(tr_attn, axis=-1) == 1) & (tr_targs == 2) & (tr_cat_size == 3))
import numpy as np import matplotlib.pyplot as mpl from expyfun.stimuli import vocode, play_sound, window_edges, read_wav, rms from expyfun import fetch_data_file print(__doc__) data, fs = read_wav(fetch_data_file('audio/dream.wav')) data = window_edges(data[0], fs) t = np.arange(data.size) / float(fs) # noise vocoder data_noise = vocode(data, fs, mode='noise') data_noise = data_noise * 0.01 / rms(data_noise) # sinewave vocoder data_tone = vocode(data, fs, mode='tone') data_tone = data_tone * 0.01 / rms(data_tone) # poisson vocoder data_click = vocode(data, fs, mode='poisson', rate=400) data_click = data_click * 0.01 / rms(data_click) # combine all three cutoff = data.shape[-1] // 3 data_allthree = data_noise.copy() data_allthree[cutoff:2 * cutoff] = data_tone[cutoff:2 * cutoff] data_allthree[2 * cutoff:] = data_click[2 * cutoff:] snd = play_sound(data_allthree, fs, norm=False, wait=False) # Uncomment this to play the original, too:
all_spatials = [s.split('x') for s in spatials] for s in all_spatials[1:]: all_spatials[0] += s all_spatials = all_spatials[0] all_spatials = list(np.unique([float(s) for s in all_spatials])) letter_dir = op.join(work_dir, 'letters') wavs = np.zeros((len(talkers), len(letters), len(all_spatials), 2, letter_ns)) for li, letter in enumerate(letters): for ti, talker in enumerate(talkers): data, fs_in = read_wav(op.join(letter_dir, talker, '%s.wav' % letter), verbose=False) data = resample(data[0], fs, fs_in) for si, angle in enumerate(all_spatials): dd = convolve_hrtf(data, fs, angle) dd *= 0.01 / np.mean(rms(data)) idx = min(dd.shape[1], letter_ns) wavs[ti, li, si, :, :idx] = dd[:, :idx] ############################################################################## # Randomization n_trials = n_tpc * len(attns) * run_matrix.sum() * len(gap_durs) trial_dur = (letter_dur * (n_cue_let + n_targ_let) + cue_targ_gap + np.mean(gap_durs) + inter_trial_dur) exp_dur = trial_dur * n_trials print('Experiment duration: %s min (%s blocks)' % (round(exp_dur / 60., 1), round((exp_dur / 60. / n_blocks), 1))) # figure out what positions work assert n_targ_let == 4
""" import numpy as np import matplotlib.pyplot as plt from expyfun.stimuli import vocode, play_sound, window_edges, read_wav, rms from expyfun import fetch_data_file print(__doc__) data, fs = read_wav(fetch_data_file('audio/dream.wav')) data = window_edges(data[0], fs) t = np.arange(data.size) / float(fs) # noise vocoder data_noise = vocode(data, fs, mode='noise') data_noise = data_noise * 0.01 / rms(data_noise) # sinewave vocoder data_tone = vocode(data, fs, mode='tone') data_tone = data_tone * 0.01 / rms(data_tone) # poisson vocoder data_click = vocode(data, fs, mode='poisson', rate=400) data_click = data_click * 0.01 / rms(data_click) # combine all three cutoff = data.shape[-1] // 3 data_allthree = data_noise.copy() data_allthree[cutoff:2 * cutoff] = data_tone[cutoff:2 * cutoff] data_allthree[2 * cutoff:] = data_click[2 * cutoff:] snd = play_sound(data_allthree, fs, norm=False, wait=False) # Uncomment this to play the original, too:
list_name = list_names[0] # okay, just process one then del list_names datas = list() print('Reading and resampling stimuli...') for ii, (name, code) in enumerate(zip(names, codes)): data, fs_read = read_wav(op.join(stim_dir, name), verbose=False) assert fs == fs_read assert (data[0] == data[1]).all() data = data[0] # one channel datas.append(resample(data, fs_out, fs, npad='auto')) assert np.isclose(datas[-1].shape[-1] / float(fs_out), data.shape[-1] / float(fs), atol=1e-3) # 1 ms assert len(datas) == len(names) rmss = [rms(d) for d in datas] factor = rms_out / np.mean(rmss) print('Writing stimuli...') for name, data in zip(names, datas): data *= factor # RMS mean across stimuli is now our desired value write_wav(op.join(out_dir, name), data, fs_out, verbose=False, overwrite=True) rmss = np.array([rms(d) for d in datas]) assert np.isclose(np.mean(rmss), rms_out) play_rmss = dB_out + 20 * np.log10(rmss / rms_out) print('Assuming a %s dB SPL set in ExperimentController, stimuli will ' 'play with a long-term RMS of:\n[%0.1f, %0.1f] dB' % (dB_out, play_rmss.min(), play_rmss.max()))
one_1_tone_delay = convolve_hrtf(finalstim_tc_delay, fs, -30.0) one_2_tone_delay = convolve_hrtf(finalstim_tc_delay, fs, 0.0) one_3_tone_delay = convolve_hrtf(finalstim_tc_delay, fs, 30.0) #without delay one_1_noise = convolve_hrtf(finalstim_nb, fs, -30.0) one_2_noise = convolve_hrtf(finalstim_nb, fs, 0.0) one_3_noise = convolve_hrtf(finalstim_nb, fs, 30.0) one_1_tone = convolve_hrtf(finalstim_tc, fs, -30.0) one_2_tone = convolve_hrtf(finalstim_tc, fs, 0.0) one_3_tone = convolve_hrtf(finalstim_tc, fs, 30.0) # rms stuff: center_rms_noise = rms(one_2_noise, axis=None) center_rms_tone = rms(one_2_tone, axis=None) center_rms_noise_delay = rms(one_2_noise_delay, axis=None) center_rms_tone_delay = rms(one_2_tone_delay, axis=None) one_2_noise /= center_rms_noise one_2_tone /= center_rms_tone #combine to make double beeps: two_1_noise = np.append(one_1_noise_delay, one_1_noise, axis=1) two_2_noise = np.append(one_2_noise_delay, one_2_noise, axis=1) two_3_noise = np.append(one_3_noise_delay, one_3_noise, axis=1) two_1_tone = np.append(one_1_tone_delay, one_1_tone, axis=1) two_2_tone = np.append(one_2_tone_delay, one_2_tone, axis=1)
names, codes, isis = parse_list(op.join(stim_dir, list_names[0])) names_b, codes_b, isis_b = parse_list(op.join(stim_dir, list_names[1])) assert set(names) == set(names_b) list_name = list_names[0] # okay, just process one then del list_names datas = list() print('Reading and resampling stimuli...') for ii, (name, code) in enumerate(zip(names, codes)): data, fs_read = read_wav(op.join(stim_dir, name), verbose=False) assert fs == fs_read assert (data[0] == data[1]).all() data = data[0] # one channel datas.append(resample(data, fs_out, fs, npad='auto')) assert np.isclose(datas[-1].shape[-1] / float(fs_out), data.shape[-1] / float(fs), atol=1e-3) # 1 ms assert len(datas) == len(names) rmss = [rms(d) for d in datas] factor = rms_out / np.mean(rmss) print('Writing stimuli...') for name, data in zip(names, datas): data *= factor # RMS mean across stimuli is now our desired value write_wav(op.join(out_dir, name), data, fs_out, verbose=False, overwrite=True) rmss = np.array([rms(d) for d in datas]) assert np.isclose(np.mean(rmss), rms_out) play_rmss = dB_out + 20 * np.log10(rmss / rms_out) print('Assuming a %s dB SPL set in ExperimentController, stimuli will ' 'play with a long-term RMS of:\n[%0.1f, %0.1f] dB' % (dB_out, play_rmss.min(), play_rmss.max()))
# -*- coding: utf-8 -*- """ ============================= Script 'DAS-cog-load stimuli' ============================= This script makes spatially-distributed word streams. """ # Author: Dan McCloy <*****@*****.**> # # License: BSD (3-clause) import os.path as op from glob import glob from expyfun.stimuli import rms, read_wav, write_wav indir = 'monotonizedWords' outdir = 'normalizedWords' target_rms = 0.01 files = glob(op.join(indir, '*.wav')) for f in files: fname = op.split(f)[-1] wav, fs = read_wav(f) new_wav = wav * target_rms / rms(wav) write_wav(op.join(outdir, fname), new_wav, fs)
sound_files = None # ['left.wav', 'right.wav'] if sound_files is None: fs = 44100 fc = 2e3 sound_len = int(np.round(isi * 0.8 * fs)) sound_dur = float(sound_len) / fs # sounds = stim.window_edges(np.random.randn(1, sound_len), fs, # sound_dur / 2.5) # b, a = sig.butter(2, fc / (fs / 2)) # sounds = sig.lfilter(b, a, sounds) t = np.arange(sound_len, dtype=float) / fs sounds = np.zeros(sound_len) f0 = 200 for f in range(f0, 1301, f0): sounds += np.sin(2 * np.pi * t * f) sounds *= base_vol / stim.rms(sounds, keepdims=True) sounds *= np.exp(-t / sound_dur * 4) sounds = stim.window_edges(sounds, fs, 0.01) else: assert(len(sound_files) == 1) temp = [] for wav in sound_files: temp += [stim.read_wav(wav)[0]] fs = stim.read_wav(sound_files[0])[1] lens = [w.shape[1] for w in temp] sounds = np.zeros((2, np.max(lens))) for si, l in enumerate(lens): sounds[si, :l] = temp[si] sounds = sig.resample(sounds, 44100 * sounds.shape[1] / fs, axis=1) fs = 44100 sound_len = sounds.shape[1]
ax.set(xlabel='Time (sec)', ylabel='Amplitude', title='Original', xlim=t[[0, -1]]) fig.tight_layout() ############################################################################### # Normalize it # ------------ # :class:`expyfun.ExperimentController` by default has ``stim_rms=0.01``. This # means that audio samples normalized to an RMS (root-mean-square) value of # 0.01 will play out at whatever ``stim_db`` value you supply (during class # initialization) when the experiment is deployed on properly calibrated # hardware, typically in an experimental booth. So let's normalize our clip: print(rms(data_orig)) target = data_orig / rms(data_orig) target *= 0.01 # do manual calculation same as ``rms``, result should be 0.01 # (to numerical precision) print(np.sqrt(np.mean(target**2))) ############################################################################### # One important thing to note about this stimulus is that its long-term RMS # (over the entire 2 seconds) is now 0.01. There will be quiet parts where the # RMS is effectively lower (close to zero) and louder parts where it's bigger. # # Add some noise # -------------- # Now let's add some masker noise, say 6 dB down (6 dB target-to-masker ratio; # TMR) from that of the target.