Implementing calibration
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
import numpy as np
|
||||||
|
from scipy.optimize import minimize
|
||||||
|
|
||||||
|
def logisticFunction(L, L_50, s_50):
|
||||||
|
'''
|
||||||
|
Calculate logistic function for SNRs L, 50% SRT point L_50, and slope
|
||||||
|
s_50
|
||||||
|
'''
|
||||||
|
return 1./(1.+np.exp(4.*s_50*(L_50-L)))
|
||||||
|
|
||||||
|
def logisticFuncLiklihood(self, args):
|
||||||
|
'''
|
||||||
|
Calculate the log liklihood for given L_50 and s_50 parameters.
|
||||||
|
This function is designed for use with the scipy minimize optimisation
|
||||||
|
function to find the optimal L_50 and s_50 parameters.
|
||||||
|
|
||||||
|
args: a tuple containing (L_50, s_50)
|
||||||
|
self.wordsCorrect: an n dimensional binary array of shape (N, 5),
|
||||||
|
containing the correctness of responses to each of the 5 words for N
|
||||||
|
trials
|
||||||
|
self.trackSNR: A sorted list of SNRs of shape N, for N trials
|
||||||
|
'''
|
||||||
|
L_50, s_50 = args
|
||||||
|
ck = self.wordsCorrect[np.arange(self.trackSNR.shape[0])]
|
||||||
|
p_lf = self.logisticFunction(self.trackSNR, L_50, s_50)
|
||||||
|
# Reshape array for vectorized calculation of log liklihood
|
||||||
|
p_lf = p_lf[:, np.newaxis].repeat(5, axis=1)
|
||||||
|
# Calculate the liklihood
|
||||||
|
res = (p_lf**ck)*(((1.-p_lf)**(1.-ck)))
|
||||||
|
with np.errstate(divide='raise'):
|
||||||
|
try:
|
||||||
|
a = np.concatenate(res)
|
||||||
|
a[a == 0] = a.max()
|
||||||
|
out = -np.sum(np.log(a))
|
||||||
|
except:
|
||||||
|
set_trace()
|
||||||
|
return out
|
||||||
|
|
||||||
|
# Called from within a class in my implementation, will not work without a
|
||||||
|
# class containing member variables for wordsCorrect and trackSNR
|
||||||
|
res = minimize(logisticFuncLiklihood, np.array([-5.0,1.0]), method='L-BFGS-B')
|
||||||
Executable
+55
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "../matrix_test/helper_modules")
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from pathops import dir_must_exist
|
||||||
|
from filesystem import globDir
|
||||||
|
from pysndfile import sndio
|
||||||
|
import os
|
||||||
|
from signalops import block_process_wav
|
||||||
|
|
||||||
|
def calc_potential_max(wavs, noise_filepath, out_dir, out_name):
|
||||||
|
max_wav_samp = 0
|
||||||
|
max_wav_rms = 0
|
||||||
|
for wav in wavs:
|
||||||
|
x, fs, enc = sndio.read(wav)
|
||||||
|
max_wav_samp = np.max([max_wav_samp, np.max(np.abs(x))])
|
||||||
|
max_wav_rms = np.max([max_wav_rms, np.sqrt(np.mean(x**2))])
|
||||||
|
x, fs, enc = sndio.read(noise_filepath)
|
||||||
|
noise_rms = np.sqrt(np.mean(x**2))
|
||||||
|
max_noise_samp = max(np.abs(x))
|
||||||
|
|
||||||
|
snr = -15.0
|
||||||
|
snr_fs = 10**(-snr/20)
|
||||||
|
max_noise_samp *= max_wav_rms/noise_rms
|
||||||
|
max_sampl = max_wav_samp+(max_noise_samp*snr_fs)
|
||||||
|
reduction_coef = 1.0/max_sampl
|
||||||
|
np.save(os.path.join(out_dir, "{}.npy".format(out_name)), reduction_coef)
|
||||||
|
return reduction_coef
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
da_files = ["../da_stim/stimulus/3000_da.wav"]
|
||||||
|
story_dir = "../eeg_story_stim/stimulus"
|
||||||
|
mat_dir = "../matrix_test/speech_components"
|
||||||
|
noise_file = "../matrix_test/behavioural_stim/stimulus/wav/noise/noise.wav"
|
||||||
|
|
||||||
|
story_wavs = globDir(story_dir, '*.wav')
|
||||||
|
mat_wavs = globDir(mat_dir, '*.wav')
|
||||||
|
|
||||||
|
out_dir = "./out"
|
||||||
|
dir_must_exist(out_dir)
|
||||||
|
story_coef = calc_potential_max(story_wavs, noise_file, out_dir, "story_red_coef")
|
||||||
|
mat_coef = calc_potential_max(mat_wavs, noise_file, out_dir, "mat_red_coef")
|
||||||
|
da_coef = calc_potential_max(da_files, noise_file, out_dir, "da_red_coef")
|
||||||
|
|
||||||
|
mat_cal_stim = "../matrix_test/long_concat_stim/out/stim/stim_0.wav"
|
||||||
|
da_cal_stim = "../da_stim/stimulus/wav/10min_da.wav"
|
||||||
|
click_cal_stim = "../click_stim/click_3000_20Hz.wav"
|
||||||
|
story_cal_stim = "../eeg_story_stim/stimulus/odin_1_1.wav"
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -1,929 +0,0 @@
|
|||||||
{
|
|
||||||
"patcher" : {
|
|
||||||
"fileversion" : 1,
|
|
||||||
"appversion" : {
|
|
||||||
"major" : 6,
|
|
||||||
"minor" : 1,
|
|
||||||
"revision" : 10,
|
|
||||||
"architecture" : "x64"
|
|
||||||
}
|
|
||||||
,
|
|
||||||
"rect" : [ 0.0, 44.0, 1223.0, 678.0 ],
|
|
||||||
"bglocked" : 0,
|
|
||||||
"openinpresentation" : 0,
|
|
||||||
"default_fontsize" : 12.0,
|
|
||||||
"default_fontface" : 0,
|
|
||||||
"default_fontname" : "Arial",
|
|
||||||
"gridonopen" : 0,
|
|
||||||
"gridsize" : [ 15.0, 15.0 ],
|
|
||||||
"gridsnaponopen" : 0,
|
|
||||||
"statusbarvisible" : 2,
|
|
||||||
"toolbarvisible" : 1,
|
|
||||||
"boxanimatetime" : 200,
|
|
||||||
"imprint" : 0,
|
|
||||||
"enablehscroll" : 1,
|
|
||||||
"enablevscroll" : 1,
|
|
||||||
"devicewidth" : 0.0,
|
|
||||||
"description" : "",
|
|
||||||
"digest" : "",
|
|
||||||
"tags" : "",
|
|
||||||
"boxes" : [ {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-51",
|
|
||||||
"maxclass" : "flonum",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "float", "bang" ],
|
|
||||||
"parameter_enable" : 0,
|
|
||||||
"patching_rect" : [ 53.25, 407.0, 88.0, 20.0 ],
|
|
||||||
"presentation_rect" : [ 376.0, 544.0, 0.0, 0.0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-52",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 141.25, 447.0, 32.5, 20.0 ],
|
|
||||||
"presentation_rect" : [ 464.0, 584.0, 0.0, 0.0 ],
|
|
||||||
"text" : "*~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-53",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 175.25, 447.0, 32.5, 20.0 ],
|
|
||||||
"presentation_rect" : [ 498.0, 584.0, 0.0, 0.0 ],
|
|
||||||
"text" : "*~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-54",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 141.25, 373.0, 33.0, 20.0 ],
|
|
||||||
"presentation_rect" : [ 464.0, 510.0, 0.0, 0.0 ],
|
|
||||||
"text" : "sig~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-55",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 173.75, 333.0, 32.5, 18.0 ],
|
|
||||||
"presentation_rect" : [ 496.5, 470.0, 0.0, 0.0 ],
|
|
||||||
"text" : "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-56",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 141.25, 333.0, 32.5, 18.0 ],
|
|
||||||
"presentation_rect" : [ 464.0, 470.0, 0.0, 0.0 ],
|
|
||||||
"text" : "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-57",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 3,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "signal", "signal" ],
|
|
||||||
"patching_rect" : [ 141.25, 407.0, 110.0, 20.0 ],
|
|
||||||
"text" : "groove~ noise_buf"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-33",
|
|
||||||
"maxclass" : "flonum",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "float", "bang" ],
|
|
||||||
"parameter_enable" : 0,
|
|
||||||
"patching_rect" : [ 253.25, 407.0, 88.0, 20.0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-34",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 341.25, 447.0, 32.5, 20.0 ],
|
|
||||||
"text" : "*~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-35",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 375.25, 447.0, 32.5, 20.0 ],
|
|
||||||
"text" : "*~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-37",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 341.25, 373.0, 33.0, 20.0 ],
|
|
||||||
"text" : "sig~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-39",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 373.75, 333.0, 32.5, 18.0 ],
|
|
||||||
"text" : "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-48",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 341.25, 333.0, 32.5, 18.0 ],
|
|
||||||
"text" : "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-50",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 3,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "signal", "signal" ],
|
|
||||||
"patching_rect" : [ 341.25, 407.0, 94.0, 20.0 ],
|
|
||||||
"text" : "groove~ da_buf"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-32",
|
|
||||||
"maxclass" : "flonum",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "float", "bang" ],
|
|
||||||
"parameter_enable" : 0,
|
|
||||||
"patching_rect" : [ 442.25, 407.0, 88.0, 20.0 ],
|
|
||||||
"presentation_rect" : [ 557.0, 512.0, 0.0, 0.0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-30",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 530.25, 447.0, 32.5, 20.0 ],
|
|
||||||
"presentation_rect" : [ 503.0, 573.0, 0.0, 0.0 ],
|
|
||||||
"text" : "*~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-31",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 564.25, 447.0, 32.5, 20.0 ],
|
|
||||||
"presentation_rect" : [ 537.0, 573.0, 0.0, 0.0 ],
|
|
||||||
"text" : "*~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-19",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "signal" ],
|
|
||||||
"patching_rect" : [ 530.25, 373.0, 33.0, 20.0 ],
|
|
||||||
"presentation_rect" : [ 732.0, 455.0, 0.0, 0.0 ],
|
|
||||||
"text" : "sig~"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-25",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 562.75, 333.0, 32.5, 18.0 ],
|
|
||||||
"presentation_rect" : [ 697.0, 411.0, 0.0, 0.0 ],
|
|
||||||
"text" : "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-26",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 530.25, 333.0, 32.5, 18.0 ],
|
|
||||||
"presentation_rect" : [ 622.0, 416.0, 0.0, 0.0 ],
|
|
||||||
"text" : "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-29",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 3,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "signal", "signal" ],
|
|
||||||
"patching_rect" : [ 530.25, 407.0, 104.0, 20.0 ],
|
|
||||||
"text" : "groove~ click_buf"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-17",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 53.25, 682.0, 486.0, 20.0 ],
|
|
||||||
"text" : "loadmess append OSX:/Users/samuelperry/Work/SOTON/Initial_work/BPLabs/click_stim/"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-13",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 835.75, 204.0, 97.0, 20.0 ],
|
|
||||||
"presentation_rect" : [ 512.0, 408.0, 0.0, 0.0 ],
|
|
||||||
"text" : "prepend replace"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-14",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 835.75, 164.0, 79.0, 20.0 ],
|
|
||||||
"presentation_rect" : [ 512.0, 368.0, 0.0, 0.0 ],
|
|
||||||
"text" : "absolutepath"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-15",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 835.75, 132.0, 127.0, 18.0 ],
|
|
||||||
"presentation_rect" : [ 512.0, 299.0, 0.0, 0.0 ],
|
|
||||||
"text" : "click_3000_20Hz.wav"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-16",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "float", "bang" ],
|
|
||||||
"patching_rect" : [ 835.75, 235.0, 98.0, 20.0 ],
|
|
||||||
"text" : "buffer~ click_buf"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-28",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 53.25, 702.0, 476.0, 20.0 ],
|
|
||||||
"text" : "loadmess append OSX:/Users/samuelperry/Work/SOTON/Initial_work/BPLabs/da_stim/"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-27",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 53.25, 662.0, 596.0, 20.0 ],
|
|
||||||
"text" : "loadmess append OSX:/Users/samuelperry/Work/SOTON/Initial_work/BPLabs/matrix_test/stimulus/wav/noise/"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-23",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 650.0, 132.0, 64.0, 18.0 ],
|
|
||||||
"text" : "noise.wav"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-20",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 650.0, 204.0, 97.0, 20.0 ],
|
|
||||||
"text" : "prepend replace"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-21",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 650.0, 164.0, 79.0, 20.0 ],
|
|
||||||
"text" : "absolutepath"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-22",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "float", "bang" ],
|
|
||||||
"patching_rect" : [ 650.0, 235.0, 103.0, 20.0 ],
|
|
||||||
"text" : "buffer~ noise_buf"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-18",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 508.0, 204.0, 97.0, 20.0 ],
|
|
||||||
"text" : "prepend replace"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-2",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 53.25, 750.0, 49.0, 20.0 ],
|
|
||||||
"text" : "filepath"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-11",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 508.0, 164.0, 79.0, 20.0 ],
|
|
||||||
"text" : "absolutepath"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-10",
|
|
||||||
"maxclass" : "message",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 1,
|
|
||||||
"outlettype" : [ "" ],
|
|
||||||
"patching_rect" : [ 508.0, 132.0, 82.0, 18.0 ],
|
|
||||||
"text" : "3000_da.wav"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"fontname" : "Arial",
|
|
||||||
"fontsize" : 12.0,
|
|
||||||
"id" : "obj-8",
|
|
||||||
"maxclass" : "newobj",
|
|
||||||
"numinlets" : 1,
|
|
||||||
"numoutlets" : 2,
|
|
||||||
"outlettype" : [ "float", "bang" ],
|
|
||||||
"patching_rect" : [ 508.0, 235.0, 88.0, 20.0 ],
|
|
||||||
"text" : "buffer~ da_buf"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"box" : {
|
|
||||||
"id" : "obj-6",
|
|
||||||
"maxclass" : "ezdac~",
|
|
||||||
"numinlets" : 2,
|
|
||||||
"numoutlets" : 0,
|
|
||||||
"patching_rect" : [ 341.25, 537.0, 45.0, 45.0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lines" : [ {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-11", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-10", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-18", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-11", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-16", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-13", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-13", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-14", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-14", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-15", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-2", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-17", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-8", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-18", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-29", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-19", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-22", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-20", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-20", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-21", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-21", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-23", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-19", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-25", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-19", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-26", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-2", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-27", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-2", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-28", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-30", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-29", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-31", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-29", 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-6", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-30", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-6", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-31", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-30", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-32", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-31", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-32", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-34", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-33", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-35", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-33", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-6", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-34", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-6", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-35", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-50", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-37", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-37", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-39", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-37", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-48", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-34", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-50", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-35", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-50", 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-52", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-51", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-53", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-51", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-6", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-52", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-6", 1 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-53", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-57", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-54", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-54", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-55", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-54", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-56", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-52", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-57", 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
"patchline" : {
|
|
||||||
"destination" : [ "obj-53", 0 ],
|
|
||||||
"disabled" : 0,
|
|
||||||
"hidden" : 0,
|
|
||||||
"source" : [ "obj-57", 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"dependency_cache" : [ ]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "../matrix_test/helper_modules")
|
||||||
from scipy.signal import square
|
from scipy.signal import square
|
||||||
from pysndfile import sndio
|
from pysndfile import sndio
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pdb
|
import pdb
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
from signalops import gen_trigger
|
||||||
|
|
||||||
def gen_click(idx, freq, length, fs):
|
def gen_click(idx, freq, length, fs):
|
||||||
duty = length*freq
|
duty = length*freq
|
||||||
@@ -22,7 +25,12 @@ def main():
|
|||||||
y = (np.arange(length) % period == 0).astype(float)
|
y = (np.arange(length) % period == 0).astype(float)
|
||||||
y[np.where(y == 1.0)[0][1::2]] = -1.0
|
y[np.where(y == 1.0)[0][1::2]] = -1.0
|
||||||
y = np.concatenate([np.zeros(fs), y, np.zeros(fs)])
|
y = np.concatenate([np.zeros(fs), y, np.zeros(fs)])
|
||||||
print("Number of clicks generated: {}".format(np.sum(np.abs(y) == 1.0)))
|
|
||||||
|
idx = np.arange(y.size)
|
||||||
|
trigger = gen_trigger(idx, 2., 0.01, fs)
|
||||||
|
y = np.vstack((y, y, trigger)).T
|
||||||
|
|
||||||
|
print("Number of clicks generated: {}".format(np.sum(np.abs(y[:, 0]) == 1.0)))
|
||||||
sndio.write('./click_3000_20Hz.wav', y, rate = fs, format='wav', enc='pcm16')
|
sndio.write('./click_3000_20Hz.wav', y, rate = fs, format='wav', enc='pcm16')
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
+10
-2
@@ -8,6 +8,7 @@ import numpy as np
|
|||||||
import pdb
|
import pdb
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from pathops import dir_must_exist
|
from pathops import dir_must_exist
|
||||||
|
from signalops import gen_trigger
|
||||||
|
|
||||||
def gen_da_stim(n, outpath):
|
def gen_da_stim(n, outpath):
|
||||||
da_file = './BioMAP_da-40ms.wav'
|
da_file = './BioMAP_da-40ms.wav'
|
||||||
@@ -21,8 +22,15 @@ def gen_da_stim(n, outpath):
|
|||||||
y_part_inv = -y_part
|
y_part_inv = -y_part
|
||||||
|
|
||||||
y_2part = np.concatenate([y_part, y_part_inv])
|
y_2part = np.concatenate([y_part, y_part_inv])
|
||||||
y = np.tile(y_2part, n)
|
y_r = np.tile(y_2part, n)
|
||||||
sndio.write(outpath, y, rate = fs, format = fmt, enc=enc)
|
y_r = np.insert(y_r, 0, np.zeros(fs))
|
||||||
|
y_l = np.zeros(y_r.size)
|
||||||
|
|
||||||
|
idx = np.arange(y_l.size)
|
||||||
|
trigger = gen_trigger(idx, 2., 0.01, fs)
|
||||||
|
|
||||||
|
y = np.vstack((y_l, y_r, trigger))
|
||||||
|
sndio.write(outpath, y.T, rate = fs, format = fmt, enc=enc)
|
||||||
return outpath
|
return outpath
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Executable
+260
@@ -0,0 +1,260 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "../matrix_test/helper_modules")
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import errno
|
||||||
|
import shutil
|
||||||
|
import re
|
||||||
|
import fnmatch
|
||||||
|
import pdb
|
||||||
|
import numpy as np
|
||||||
|
from natsort import natsorted
|
||||||
|
from collections import namedtuple
|
||||||
|
from pysndfile import PySndfile, sndio
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
from gen_da import gen_da_stim
|
||||||
|
|
||||||
|
from pathops import dir_must_exist
|
||||||
|
try:
|
||||||
|
from signalops import rolling_window_lastaxis, calc_rms
|
||||||
|
except ImportError:
|
||||||
|
from .signalops import rolling_window_lastaxis, block_lfilter, calc_rms
|
||||||
|
|
||||||
|
import scipy.signal as sgnl
|
||||||
|
from scipy.stats import pearsonr
|
||||||
|
|
||||||
|
from pyswarm import pso
|
||||||
|
|
||||||
|
try:
|
||||||
|
from lpc import lpc
|
||||||
|
except ImportError:
|
||||||
|
from .lpc import lpc
|
||||||
|
|
||||||
|
try:
|
||||||
|
from filesystem import globDir, organiseWavs, prepareOutDir
|
||||||
|
except ImportError:
|
||||||
|
from .filesystem import globDir, organiseWavs, prepareOutDir
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
i += blocksize
|
||||||
|
return y_out
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def gen_audio_stim(da, OutDir, indexes):
|
||||||
|
if os.path.exists(OutDir):
|
||||||
|
shutil.rmtree(OutDir)
|
||||||
|
os.makedirs(OutDir)
|
||||||
|
wavFiles = globDir(MatrixDir, '*.wav')
|
||||||
|
wavFileMatrix = organiseWavs(wavFiles)
|
||||||
|
wavDir = os.path.join(OutDir, "wav")
|
||||||
|
dir_must_exist(wavDir)
|
||||||
|
wavDir = os.path.join(wavDir, "noise-sentences")
|
||||||
|
dir_must_exist(wavDir)
|
||||||
|
files = []
|
||||||
|
n = 0
|
||||||
|
o = 0
|
||||||
|
for sentenceList in indexes:
|
||||||
|
n += 1
|
||||||
|
o = 0
|
||||||
|
files.append([])
|
||||||
|
for ind in sentenceList:
|
||||||
|
o += 1
|
||||||
|
y, wavInfo, partnames = synthesize_trial(wavFileMatrix, ind)
|
||||||
|
fileName = os.path.join(wavDir, 'Trial_{0:02d}_{1:02d}.wav'.format(n, o))
|
||||||
|
print("Generating: " + fileName)
|
||||||
|
sndio.write(fileName, y, **wavInfo)
|
||||||
|
files[-1].append(fileName)
|
||||||
|
|
||||||
|
return files
|
||||||
|
|
||||||
|
def gen_indexes():
|
||||||
|
x = np.repeat(np.arange(10), 5)
|
||||||
|
x = x.reshape(10, 5)
|
||||||
|
|
||||||
|
y = np.zeros((50, 10, 5), dtype=int)
|
||||||
|
|
||||||
|
# 50 lists
|
||||||
|
for i in range(50):
|
||||||
|
x[:, 1] = np.roll(x[:, 1], 1)
|
||||||
|
x[:, 2] = np.roll(x[:, 2], 2)
|
||||||
|
x[:, 3] = np.roll(x[:, 3], 3)
|
||||||
|
x[:, 4] = np.roll(x[:, 4], 4)
|
||||||
|
y[i] = x.copy()
|
||||||
|
return y
|
||||||
|
|
||||||
|
def gen_rms(files, OutDir):
|
||||||
|
rmsFiles = []
|
||||||
|
for file in files:
|
||||||
|
head, tail = os.path.split(file)
|
||||||
|
tail = os.path.splitext(tail)[0]
|
||||||
|
tail = tail + "_rms.npy"
|
||||||
|
dir_must_exist(OutDir)
|
||||||
|
rmsFilepath = os.path.join(OutDir, tail)
|
||||||
|
print("Generating: "+rmsFilepath)
|
||||||
|
y, fs, _ = sndio.read(file)
|
||||||
|
y_rms = calc_rms(y, round(0.02*fs))
|
||||||
|
np.save(rmsFilepath, y_rms)
|
||||||
|
rmsFiles.append(rmsFilepath)
|
||||||
|
return rmsFiles
|
||||||
|
|
||||||
|
def detect_silences(rmsFiles, fs, seg_min_size=0.02):
|
||||||
|
print("Detecting silence in wav files...")
|
||||||
|
if not seg_min_size:
|
||||||
|
seg_min_size = np.inf
|
||||||
|
silences = []
|
||||||
|
for envelopeFile in rmsFiles:
|
||||||
|
env = np.load(envelopeFile)
|
||||||
|
silence = env < 0.001
|
||||||
|
# Get segment start end indexes for all silences in envelope
|
||||||
|
silentSegs = np.where(np.concatenate(([silence[0]],silence[:-1]!=silence[1:],[True])))[0].reshape(-1, 2)
|
||||||
|
validSegs = np.diff(silentSegs) > seg_min_size*fs
|
||||||
|
silences.append(silentSegs[np.repeat(validSegs, 2, axis=1)].reshape(-1, 2))
|
||||||
|
return silences
|
||||||
|
|
||||||
|
|
||||||
|
def calc_spectrum(files, silences, fs=44100, plot=False):
|
||||||
|
window = 4096
|
||||||
|
sentenceLen = []
|
||||||
|
sentenceFFT = []
|
||||||
|
|
||||||
|
print("Calculating LTASS...")
|
||||||
|
for ind, file in enumerate(files):
|
||||||
|
x, fs, _ = sndio.read(file)
|
||||||
|
f, t, Zxx = sgnl.stft(x, window=np.ones(window), nperseg=window, noverlap=0)
|
||||||
|
sil = silences[ind]
|
||||||
|
sTemp = np.zeros((sil.shape[0], t.size), dtype=bool)
|
||||||
|
for ind3, s in enumerate(sil):
|
||||||
|
sTemp[ind3, :] = np.logical_and(t > s[0], t < s[1])
|
||||||
|
invalidFFT = np.any(sTemp, axis=0)
|
||||||
|
sentenceFFT.append(np.abs(Zxx[:, ~np.any(sTemp, axis=0)]))
|
||||||
|
sentenceLen.append(x.size)
|
||||||
|
sentenceLen = np.array([sentenceLen]).T
|
||||||
|
sentenceLen = sentenceLen / sentenceLen.max()
|
||||||
|
sentenceFFT = [x * sentenceLen[i] for i, x in enumerate(sentenceFFT)]
|
||||||
|
sentenceFFT = np.concatenate([x.T for x in sentenceFFT])
|
||||||
|
|
||||||
|
grandAvgFFT = np.mean(sentenceFFT, axis=0)
|
||||||
|
grandAvgFFT = grandAvgFFT / grandAvgFFT.max()
|
||||||
|
print("Fitting filter to LTASS...")
|
||||||
|
b = sgnl.firls(2049, np.linspace(0, 1, 2049)[1:], grandAvgFFT[1:])
|
||||||
|
if plot:
|
||||||
|
plt.semilogy(np.abs(sgnl.freqz(b)[1]))
|
||||||
|
plt.plot(np.linspace(0, 512, 2049), grandAvgFFT)
|
||||||
|
plt.show()
|
||||||
|
return b
|
||||||
|
|
||||||
|
|
||||||
|
def gen_noise(OutDir, b, fs, s_rms):
|
||||||
|
print("Generating noise...")
|
||||||
|
# Generate 10 minutes of white noise
|
||||||
|
x = np.random.randn(int(fs*60.*20.))
|
||||||
|
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 = block_lfilter_wav(b, [1.0], x, os.path.join(noiseDir, 'noise.wav'), 65538, 44100)
|
||||||
|
noise_rms_path = os.path.join(noiseRMSDir, 'noise_rms.npy')
|
||||||
|
rms = np.sqrt(np.mean(y**2))
|
||||||
|
np.save(noise_rms_path, rms)
|
||||||
|
return y
|
||||||
|
|
||||||
|
|
||||||
|
def calc_speech_rms(files, silences, rmsDir, fs=44100, plot=False):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
f = files
|
||||||
|
sumsqrd = 0.0
|
||||||
|
n = 0
|
||||||
|
for wavfile, sil in zip(f, silences):
|
||||||
|
y, fs, _ = sndio.read(wavfile)
|
||||||
|
t = np.arange(y.size)
|
||||||
|
sTemp = np.zeros(t.size, dtype=bool)
|
||||||
|
print("Started")
|
||||||
|
for ind, s in enumerate(sil):
|
||||||
|
print("Check {}".format(ind))
|
||||||
|
sTemp = np.logical_or(sTemp, np.logical_and(t > s[0], t < s[1]))
|
||||||
|
print("Done")
|
||||||
|
silentSamples = np.any(sTemp, axis=0)
|
||||||
|
y_temp = y[~silentSamples]
|
||||||
|
sumsqrd += np.sum(y_temp**2)
|
||||||
|
n += y_temp.size
|
||||||
|
rms = np.sqrt(sumsqrd/n)
|
||||||
|
np.save(os.path.join(rmsDir, 'overall_da_rms.npy'), rms)
|
||||||
|
return rms
|
||||||
|
#sentenceFFT.append(np.abs(Zxx[:, ~np.any(sTemp, axis=0)]))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from pathtype import PathType
|
||||||
|
# Create commandline interface
|
||||||
|
parser = argparse.ArgumentParser(description='Generate stimulus for '
|
||||||
|
'training TRF decoder by concatenating '
|
||||||
|
'matrix test materials')
|
||||||
|
parser.add_argument('--OutDir', type=PathType(exists=None, type='dir'),
|
||||||
|
default='./stimulus', help='Output directory')
|
||||||
|
parser.add_argument('--CalcRMS', action='store_true')
|
||||||
|
args = {k:v for k,v in vars(parser.parse_args()).items() if v is not None}
|
||||||
|
|
||||||
|
rmsDir = os.path.join(args['OutDir'], "rms")
|
||||||
|
dir_must_exist(rmsDir)
|
||||||
|
wavDir = os.path.join(args['OutDir'], "wav")
|
||||||
|
dir_must_exist(wavDir)
|
||||||
|
if args['CalcRMS']:
|
||||||
|
daFile = gen_da_stim(3333, os.path.join(wavDir, '10min_da.wav'))
|
||||||
|
rmsFiles = gen_rms([daFile], rmsDir)
|
||||||
|
else:
|
||||||
|
daFile = globDir(wavDir, '*.wav')[0]
|
||||||
|
rmsFile = globDir(rmsDir, '*.npy')[0]
|
||||||
|
silences = detect_silences([rmsFile], 44100, None)
|
||||||
|
s_rms = calc_speech_rms([daFile], silences, rmsDir)
|
||||||
|
b = calc_spectrum([daFile], silences)
|
||||||
|
y = gen_noise(args['OutDir'], b, 44100, s_rms)
|
||||||
@@ -62,7 +62,6 @@ class EEGMatTrainThread(BaseThread):
|
|||||||
|
|
||||||
self.reduction_coef = np.load(red_coef)
|
self.reduction_coef = np.load(red_coef)
|
||||||
|
|
||||||
|
|
||||||
self.wav_files = []
|
self.wav_files = []
|
||||||
self.marker_files = []
|
self.marker_files = []
|
||||||
self.question_files = []
|
self.question_files = []
|
||||||
|
|||||||
Executable
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "../matrix_test/helper_modules")
|
||||||
|
|
||||||
|
from filesystem import globDir
|
||||||
|
from pudb import set_trace
|
||||||
|
from pysndfile import sndio
|
||||||
|
from signalops import gen_trigger
|
||||||
|
import os
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
wavs = globDir("./stimulus", "*.wav")
|
||||||
|
for wav in wavs:
|
||||||
|
x, fs, enc, fmt = sndio.read(wav, return_format=True)
|
||||||
|
y_r = np.insert(x, 0, np.zeros(fs))
|
||||||
|
idx = np.arange(x.shape[0])
|
||||||
|
y = np.vstack([x, x, np.zeros(x.shape[0])]).T
|
||||||
|
trigger = gen_trigger(idx, 2., 0.01, fs)
|
||||||
|
y[:, 2] = trigger
|
||||||
|
wav_out = os.path.splitext(wav)[0] + "_trig.wav"
|
||||||
|
sndio.write(wav_out, y, rate=fs, format=fmt, enc=enc)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
1, What items did the dwarves forge?
|
|
||||||
2, Could they work in peace?
|
|
||||||
3, Who is, in fact, Gadfly?
|
|
||||||
@@ -59,6 +59,8 @@ class EEGTestThread(BaseThread):
|
|||||||
self.question = []
|
self.question = []
|
||||||
self.response = []
|
self.response = []
|
||||||
|
|
||||||
|
self.reduction_coef = np.load(red_coef)
|
||||||
|
|
||||||
# Percent speech inteligibility (estimated using behavioural measure)
|
# Percent speech inteligibility (estimated using behavioural measure)
|
||||||
# to present stimuli at
|
# to present stimuli at
|
||||||
self.si = np.array([20.0, 35.0, 50.0, 65.0, 80.0, 90.0, 100.0])
|
self.si = np.array([20.0, 35.0, 50.0, 65.0, 80.0, 90.0, 100.0])
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import queue
|
|||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from pysndfile import PySndfile, construct_format
|
from pysndfile import PySndfile, construct_format
|
||||||
|
from scipy.signal import square
|
||||||
|
|
||||||
import sounddevice as sd
|
import sounddevice as sd
|
||||||
import soundfile as sf
|
import soundfile as sf
|
||||||
@@ -83,6 +84,24 @@ def block_lfilter(b, a, x, blocksize=8192):
|
|||||||
i += blocksize
|
i += blocksize
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def block_process_wav(wavpath, out_wavpath, func, block_size=4096, **args):
|
||||||
|
'''
|
||||||
|
Mix two wav files, applying gains to each
|
||||||
|
'''
|
||||||
|
wav = PySndfile(wavpath_a, 'r')
|
||||||
|
|
||||||
|
out_wav = PySndfile(out_wavpath, 'w', construct_format('wav', 'pcm16'), wav.channels(), wav.samplerate())
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < wav_a.frames():
|
||||||
|
if i+block_size > wav_a.frames():
|
||||||
|
block_size = wav_a.frames()-i
|
||||||
|
x = wav_a.read_frames(block_size)
|
||||||
|
y = func(x, **args)
|
||||||
|
out_wav.write_frames(x1)
|
||||||
|
i += block_size
|
||||||
|
|
||||||
|
|
||||||
def block_mix_wavs(wavpath_a, wavpath_b, out_wavpath, a_gain=1., b_gain=1., block_size=4096):
|
def block_mix_wavs(wavpath_a, wavpath_b, out_wavpath, a_gain=1., b_gain=1., block_size=4096):
|
||||||
'''
|
'''
|
||||||
Mix two wav files, applying gains to each
|
Mix two wav files, applying gains to each
|
||||||
@@ -104,6 +123,13 @@ def block_mix_wavs(wavpath_a, wavpath_b, out_wavpath, a_gain=1., b_gain=1., bloc
|
|||||||
i += block_size
|
i += block_size
|
||||||
|
|
||||||
|
|
||||||
|
def gen_trigger(x, freq, length, fs):
|
||||||
|
|
||||||
|
duty = length*freq
|
||||||
|
trigger = square(2*np.pi*(x/fs)*freq, duty=duty)
|
||||||
|
trigger[trigger < 0] = 0
|
||||||
|
return trigger
|
||||||
|
|
||||||
|
|
||||||
def calc_rms(y, window, plot=False):
|
def calc_rms(y, window, plot=False):
|
||||||
y_2 = y**2
|
y_2 = y**2
|
||||||
|
|||||||
@@ -10,13 +10,14 @@ import shutil
|
|||||||
import errno
|
import errno
|
||||||
import re
|
import re
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import pdb
|
import pudb
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from natsort import natsorted
|
from natsort import natsorted
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import pysndfile
|
import pysndfile
|
||||||
from pysndfile import sndio, PySndfile
|
from pysndfile import sndio, PySndfile
|
||||||
|
|
||||||
|
from signalops import gen_trigger
|
||||||
from pathtype import PathType
|
from pathtype import PathType
|
||||||
from tokens_to_words import tokens_to_words, load_component_map
|
from tokens_to_words import tokens_to_words, load_component_map
|
||||||
|
|
||||||
@@ -82,29 +83,44 @@ def concatenateStimuli(MatrixDir, OutDir, Length, n):
|
|||||||
totalSize += size
|
totalSize += size
|
||||||
totalSize += int(0.1*fs)
|
totalSize += int(0.1*fs)
|
||||||
if (totalSize/fs) > Length:
|
if (totalSize/fs) > Length:
|
||||||
y.append(np.zeros(totalSize))
|
# total size + 2 second silence at start
|
||||||
|
y.append(np.zeros((totalSize+2*fs, 3)))
|
||||||
parts.append([])
|
parts.append([])
|
||||||
questions.append([])
|
questions.append([])
|
||||||
i += 1
|
i += 1
|
||||||
totalSize = 0
|
totalSize = 0
|
||||||
|
|
||||||
writePtr = 0
|
writePtr = 2*fs
|
||||||
|
idx = np.arange(0, writePtr)
|
||||||
|
chunk = np.zeros(idx.size)
|
||||||
|
chunk = np.vstack([chunk, chunk, chunk]).T
|
||||||
|
trigger = gen_trigger(idx, 2., 0.01, fs)
|
||||||
|
chunk[:, 2] = trigger
|
||||||
|
for i, _ in enumerate(y):
|
||||||
|
y[i][0:writePtr, :] = chunk
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
for wav, word, part in zip(wavFiles, stim_word_rows, stim_part_rows):
|
for wav, word, part in zip(wavFiles, stim_word_rows, stim_part_rows):
|
||||||
if writePtr >= y[i].size:
|
if writePtr >= y[i].shape[0]:
|
||||||
i += 1
|
i += 1
|
||||||
writePtr = 0
|
writePtr = fs*2
|
||||||
if i == n:
|
if i == n:
|
||||||
break
|
break
|
||||||
x, fs, encStr, fmtStr = sndio.read(wav, return_format=True)
|
x, fs, encStr, fmtStr = sndio.read(wav, return_format=True)
|
||||||
threeMs = int(0.1*fs)
|
threeMs = int(0.1*fs)
|
||||||
silence = np.zeros(threeMs)
|
silence = np.zeros(threeMs)
|
||||||
chunk = np.append(x, silence)
|
chunk = np.append(x, silence)
|
||||||
y[i][writePtr:writePtr + chunk.size] = chunk
|
|
||||||
|
idx = np.arange(writePtr, writePtr+chunk.shape[0])
|
||||||
|
chunk = np.vstack([chunk, chunk, np.zeros(chunk.shape[0])]).T
|
||||||
|
trigger = gen_trigger(idx, 2., 0.01, fs)
|
||||||
|
chunk[:, 2] = trigger
|
||||||
|
|
||||||
|
y[i][writePtr:writePtr + chunk.shape[0], :] = chunk
|
||||||
questions[i].append(word)
|
questions[i].append(word)
|
||||||
parts[i].append(part)
|
parts[i].append(part)
|
||||||
|
|
||||||
writePtr += chunk.size
|
writePtr += chunk.shape[0]
|
||||||
|
|
||||||
for ind, (data, q, p) in enumerate(zip(y, questions, parts)):
|
for ind, (data, q, p) in enumerate(zip(y, questions, parts)):
|
||||||
pysndfile.sndio.write(os.path.join(OutDir, 'stim_{}.wav'.format(ind)), data, format=fmtStr, enc=encStr)
|
pysndfile.sndio.write(os.path.join(OutDir, 'stim_{}.wav'.format(ind)), data, format=fmtStr, enc=encStr)
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import sys
|
|
||||||
sys.path.insert(0, "../helper_modules/")
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -108,6 +108,11 @@ def main():
|
|||||||
sample(range(stim_count_half, stim_count-1), n_questions)
|
sample(range(stim_count_half, stim_count-1), n_questions)
|
||||||
]).T
|
]).T
|
||||||
a = 0
|
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)):
|
for ind, (wav, txt) in enumerate(zip(merged_wavs, words)):
|
||||||
csv_line = [counter]
|
csv_line = [counter]
|
||||||
silence = np.zeros((int(np.random.uniform(int(0.3*44100), int(0.4*44100), 1)), 3))
|
silence = np.zeros((int(np.random.uniform(int(0.3*44100), int(0.4*44100), 1)), 3))
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{% extends 'participant_index.html' %}
|
{% extends 'participant_index.html' %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="main-div" class="outer">
|
<div id="main-div" class="outer">
|
||||||
|
<h3 id="question"></h3>
|
||||||
<div class="mat_grid">
|
<div class="mat_grid">
|
||||||
<button type="button" href="#" disabled id="mat-0" class="Btn Btn-outline-secondary mat-button">Peter</button>
|
<button type="button" href="#" disabled id="mat-0" class="Btn Btn-outline-secondary mat-button">Peter</button>
|
||||||
<button type="button" href="#" disabled id="mat-1" class="Btn Btn-outline-secondary mat-button">got</button>
|
<button type="button" href="#" disabled id="mat-1" class="Btn Btn-outline-secondary mat-button">got</button>
|
||||||
@@ -100,6 +101,10 @@
|
|||||||
// Disable all inputs whilst processing
|
// Disable all inputs whilst processing
|
||||||
$('#main-div').find('input, textarea, button, select').attr('disabled','disabled');
|
$('#main-div').find('input, textarea, button, select').attr('disabled','disabled');
|
||||||
});
|
});
|
||||||
|
socket.on('question', function(msg) {
|
||||||
|
// Disable all inputs whilst processing
|
||||||
|
$('#question').text(msg);
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('stim_done', function(msg) {
|
socket.on('stim_done', function(msg) {
|
||||||
$('#main-div').find('input, textarea, button, select').removeAttr('disabled');
|
$('#main-div').find('input, textarea, button, select').removeAttr('disabled');
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
from pysndfile import sndio
|
||||||
|
import numpy as np
|
||||||
|
import pdb
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''
|
||||||
|
Generate train of equally spaced clicks
|
||||||
|
'''
|
||||||
|
fs = 44100
|
||||||
|
n = np.arange(fs*10)
|
||||||
|
trig_s = np.where(np.mod(n, fs/2.) == 0)
|
||||||
|
click = np.ones(int(0.01*fs))
|
||||||
|
y = np.zeros(n.size)
|
||||||
|
for i in trig_s[0]:
|
||||||
|
y[i:i+click.size] = click
|
||||||
|
|
||||||
|
sndio.write("./trig_test.wav", y, fs, format='wav', enc='pcm16')
|
||||||
|
|
||||||
|
pdb.set_trace()
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user