Multiple fixes. SNR calculation still needs fixing

This commit is contained in:
2020-01-12 18:56:19 +00:00
parent 210b5c8bd5
commit e955b746d1
19 changed files with 313 additions and 58 deletions
+1
View File
@@ -22,6 +22,7 @@ import scipy.signal as signal
import matplotlib.pyplot as plt
def asl_P56(x, fs, nbits):
nbits = int(nbits)
eps = np.finfo(float).eps
x = x[:] # make sure x is column vector
if len(x.shape) < 2:
+1
View File
@@ -26,6 +26,7 @@ g = exp( -1/( fs* T)); % smoothing factor in envelop detection
c( 1: thres_no)= 2.^ (-15: thres_no- 16);
% vector with thresholds from one quantizing level up to half the maximum
% code, at a step of 2, in the case of 16bit samples, from 2^-15 to 0.5;
a( 1: thres_no) = 0; % activity counter for each level threshold
hang( 1: thres_no) = I; % hangover counter for each level threshold
+9 -8
View File
@@ -3,8 +3,8 @@
"fileversion" : 1,
"appversion" : {
"major" : 8,
"minor" : 0,
"revision" : 8,
"minor" : 1,
"revision" : 1,
"architecture" : "x64",
"modernui" : 1
}
@@ -159,11 +159,12 @@
"fontname" : "Arial",
"fontsize" : 12.0,
"id" : "obj-18",
"linecount" : 2,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 408.0, 215.0, 81.75, 20.0 ],
"text" : "70 dB SPL"
"patching_rect" : [ 408.0, 215.0, 81.75, 33.0 ],
"text" : "70 dB Peak SPL"
}
}
@@ -684,8 +685,8 @@
"followglobaltempo" : 0,
"formantcorrection" : 0,
"mode" : "basic",
"originallength" : [ 866265.382312924717553, "ticks" ],
"originaltempo" : 119.999999999999943,
"originallength" : [ 866265.382312924601138, "ticks" ],
"originaltempo" : 119.999999999999929,
"pitchcorrection" : 0,
"quality" : "basic",
"timestretch" : [ 0 ]
@@ -969,8 +970,8 @@
"followglobaltempo" : 0,
"formantcorrection" : 0,
"mode" : "basic",
"originallength" : [ 137594.144217686989577, "ticks" ],
"originaltempo" : 119.999999999999929,
"originallength" : [ 137594.144217686960474, "ticks" ],
"originaltempo" : 119.999999999999915,
"pitchcorrection" : 0,
"quality" : "basic",
"timestretch" : [ 0 ]
+38
View File
@@ -0,0 +1,38 @@
#!/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
import matplotlib.pyplot as plt
def main():
'''
'''
fs = 44100
f = 1000.0
n = np.arange(fs * 60 * 5)
y = np.sin(2*np.pi*f*n/fs)
coef = np.load('./out/calibration_coefficients/click_cal_coef.npy')
y *= coef
dir_must_exist('./out/calibrated_stim/')
sndio.write("./out/calibrated_stim/1k_tone.wav", y, fs, format='wav', enc='pcm16')
coef = np.load('./out/calibration_coefficients/da_cal_coef.npy')
y, fs, enc = sndio.read('./out/stimulus/da_cal_stim.wav')
sndio.write('./out/calibrated_stim/da_cal_stim.wav', y*coef, fs, format='wav', enc='pcm16')
coef = np.load('./out/calibration_coefficients/mat_cal_coef.npy')
y, fs, enc = sndio.read('./out/stimulus/mat_cal_stim.wav')
sndio.write('./out/calibrated_stim/mat_cal_stim.wav', y*coef, fs, format='wav', enc='pcm16')
coef = np.load('./out/calibration_coefficients/story_cal_coef.npy')
y, fs, enc = sndio.read('./out/stimulus/story_cal_stim.wav')
sndio.write('./out/calibrated_stim/story_cal_stim.wav', y*coef, fs, format='wav', enc='pcm16')
if __name__ == "__main__":
main()
+74
View File
@@ -0,0 +1,74 @@
#!/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
from shutil import copyfile
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 = -5.
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 = ["../tone_stim/stimulus/tone_2000/tone_3000_2000Hz.wav", "../tone_stim/stimulus/tone_500/tone_3000_500Hz.wav"]
story_dir = "../eeg_story_stim/stimulus"
mat_dir = "../matrix_test/speech_components"
noise_file = "../matrix_test/behavioural_stim/stimulus/wav/noise/noise_norm.wav"
da_noise_file = "../da_stim/noise/wav/noise/noise_norm.wav"
story_wavs = globDir(story_dir, '*.wav')
mat_wavs = globDir(mat_dir, '*.wav')
out_dir = "./out"
out_red_dir = os.path.join(out_dir, 'reduction_coefficients')
out_stim_dir = os.path.join(out_dir, 'stimulus')
dir_must_exist(out_dir)
dir_must_exist(out_red_dir)
dir_must_exist(out_stim_dir)
story_coef = calc_potential_max(story_wavs, noise_file, out_red_dir, "story_red_coef")
mat_coef = calc_potential_max(mat_wavs, noise_file, out_red_dir, "mat_red_coef")
da_coef = calc_potential_max(da_files, da_noise_file, out_red_dir, "da_red_coef")
mat_cal_stim = "../matrix_test/long_concat_stim/out/stim/stim_0.wav"
da_cal_stim = "./out/stimulus/1k_tone.wav"
# click_cal_stim = "../tone_stim/stimulus/tone_2000/tone_3000_2000Hz.wav"
story_cal_stim = "../eeg_story_stim/stimulus/odin_1_1.wav"
mat_out_stim = os.path.join(out_stim_dir, "mat_cal_stim.wav")
# click_out_stim = os.path.join(out_stim_dir, "click_cal_stim.wav")
da_out_stim = os.path.join(out_stim_dir, "1k_cal_stim.wav")
story_out_stim = os.path.join(out_stim_dir, "story_cal_stim.wav")
block_process_wav(mat_cal_stim, mat_out_stim, lambda x: x * mat_coef)
block_process_wav(story_cal_stim, story_out_stim, lambda x: x * story_coef)
block_process_wav(da_cal_stim, da_out_stim, lambda x: x * da_coef)
# block_process_wav(click_cal_stim, click_out_stim, lambda x: x * click_coef)
#copyfile(click_cal_stim, click_out_stim)
if __name__ == "__main__":
main()
+27
View File
@@ -0,0 +1,27 @@
#!/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
import matplotlib.pyplot as plt
def main():
'''
'''
fs = 44100
f = 1000.0
n = np.arange(fs * 60 * 5)
y = np.sin(2*np.pi*f*n/fs)
y = np.array([y, y]).T
sndio.write("./out/stimulus/1k_tone.wav", y, fs, format='wav', enc='pcm16')
if __name__ == "__main__":
main()
+1 -1
View File
@@ -44,7 +44,7 @@ class DaTestThread(BaseThread):
'''
def __init__(self, sessionFilepath=None,
stimFolder='./tone_stim/stimulus',
noiseFilepath="./tone_stim/noise/wav/noise/noise.wav",
noiseFilepath="./tone_stim/noise/wav/noise/noise_norm.wav",
noiseintensityFilepath="./tone_stim/noise/intensity/noise_intensity.npy",
red_coef="./calibration/out/reduction_coefficients/tone_red_coef.npy",
cal_coef="./calibration/out/calibration_coefficients/tone_cal_coef.npy",
+1 -1
View File
@@ -16,8 +16,8 @@ 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])
breakpoint()
y = np.vstack([x, x, np.zeros(x.shape[0])]).T
trigger = gen_trigger(idx, 2., 0.01, fs)
y[:, 2] = trigger
+2 -2
View File
@@ -1,3 +1,3 @@
1, Who are the characters of this story?
2, What are they up to?
3, What did they wager?
2, What are the characters doing?
3, What did the characters wager?
1 1 Who are the characters of this story?
2 2 What are they up to? What are the characters doing?
3 3 What did they wager? What did the characters wager?
+30 -9
View File
@@ -19,6 +19,9 @@ import csv
import pdb
import dill
import sounddevice as sd
from hearing_loss_sim import apply_hearing_loss_sim
symb_dict = {
True: 10003,
False: 10007
@@ -38,7 +41,7 @@ class EEGStoryTrainThread(BaseThread):
Thread for running server side matrix test operations
'''
def __init__(self, sessionFilepath=None,
stimFolder='./eeg_story_stim/', nTrials=2,
stimFolder='./eeg_story_stim/stimulus/', nTrials=2,
socketio=None, participant=None, srt_50=None, s_50=None):
self.test_name = 'eeg_story_train'
self.stimDir = stimFolder
@@ -90,6 +93,7 @@ class EEGStoryTrainThread(BaseThread):
if self._stopevent.isSet() or self.finishTest:
break
# Play concatenated matrix sentences at set SNR
self.playStimulus(wav)
self.waitForResponse()
if self._stopevent.isSet() or self.finishTest:
@@ -142,21 +146,38 @@ class EEGStoryTrainThread(BaseThread):
def displayInstructions(self):
self.socketio.emit('display_instructions', namespace='/main')
def playStimulus(self, wav_file, replay=False):
def playStimulus(self, wav):
'''
Output audio stimulus from numpy array
'''
self.newResp = False
self.socketio.emit("stim_playing", namespace="/main")
# if not replay:
# self.y = self.generateTrial(self.snr)
x, fs, _ = sndio.read(wav)
if self.participant.parameters['hl_sim_active']:
y = apply_hearing_loss_sim(x, fs)
# Play audio
# sd.play(self.y, self.fs, blocking=True)
if not self.dev_mode:
self.play_wav(wav_file, 'finish_test')
sd.play(y, fs, blocking=True)
else:
self.play_wav('./da_stim/DA_170.wav', 'finish_test')
self.play_wav('./da_stim/DA_170.wav', '')
self.socketio.emit("stim_done", namespace="/main")
# def playStimulus(self, wav_file, replay=False):
# x, fs, _ = sndio.read(wav_file)
# self.newResp = False
# self.socketio.emit("stim_playing", namespace="/main")
# # if not replay:
# # self.y = self.generateTrial(self.snr)
# # Play audio
# # sd.play(self.y, self.fs, blocking=True)
# if not self.dev_mode:
# self.play_wav(wav_file, 'finish_test')
# else:
# self.play_wav('./da_stim/DA_170.wav', 'finish_test')
# self.socketio.emit("stim_done", namespace="/main")
def saveState(self, out="test_state.pkl"):
saveDict = {k:self.__dict__[k] for k in self.toSave}
+28 -7
View File
@@ -10,7 +10,10 @@ import numpy as np
import pandas as pd
from shutil import copy2
import re
import sounddevice as sd
from ITU_P56 import asl_P56
from hearing_loss_sim import apply_hearing_loss_sim
from test_base import BaseThread, run_test_thread
from scipy.special import logit
from config import socketio
@@ -52,7 +55,7 @@ class EEGTestThread(BaseThread):
'''
def __init__(self, sessionFilepath=None,
listFolder="./matrix_test/short_concat_stim/out",
noiseFilepath="./matrix_test/behavioural_stim/stimulus/wav/noise/noise.wav",
noiseFilepath="./matrix_test/behavioural_stim/stimulus/wav/noise/noise_norm.wav",
red_coef="./calibration/out/reduction_coefficients/mat_red_coef.npy",
cal_coef="./calibration/out/calibration_coefficients/mat_cal_coef.npy",
socketio=None, participant=None, srt_50=None, s_50=None):
@@ -116,7 +119,7 @@ class EEGTestThread(BaseThread):
logger.info("{0:<25}".format("Current question 2:") + f"{' '.join(q[1][:-1])} | Answer: {q[1][-1]}")
logger.info("{0:<25}".format("Current SNR(-srt):") + f"{snr}")
# Play concatenated matrix sentences at set SNR
self.playStimulusWav(wav)
self.playStimulus(wav)
self.setMatrix(q)
self.saveState(out=self.backupFilepath)
logger.info("-"*78)
@@ -171,8 +174,8 @@ class EEGTestThread(BaseThread):
def finaliseResults(self):
toSave = ['marker_files', 'clinPageLoaded', 'wav_files', 'participant',
'response', 'backupFilepath', 'noise_path', 'question_files',
'si', 'question', 'answers', 'trial_ind']
saveDict = {k:self.__dict__[k] for k in toSave}
'question', 'answers', 'trial_ind']
saveDict = {k:self.__dict__[k] for k in toSave if k in self.__dict__.keys()}
self.participant['eeg_test'].update(saveDict)
self.participant.save("eeg_test")
backup_path = os.path.join(self.participant.data_paths['eeg_test'],
@@ -240,20 +243,22 @@ class EEGTestThread(BaseThread):
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))
# 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.)
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 = 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.
@@ -302,6 +307,22 @@ class EEGTestThread(BaseThread):
self.answers[:] = np.nan
def playStimulus(self, wav):
'''
Output audio stimulus from numpy array
'''
self.newResp = False
self.socketio.emit("stim_playing", namespace="/main")
x, fs, _ = sndio.read(wav)
if self.participant.parameters['hl_sim_active']:
y = apply_hearing_loss_sim(x, fs)
# Play audio
if not self.dev_mode:
sd.play(y, fs, blocking=True)
else:
self.play_wav('./da_stim/DA_170.wav', '')
self.socketio.emit("{}_stim_done".format(self.test_name), namespace="/main")
def submitTestResponse(self, msg):
'''
Get and store participant response for current trial
+3 -1
View File
@@ -18,6 +18,7 @@ import os
from pathlib import Path
from datetime import datetime
import re
from copy import deepcopy
logger = logging.getLogger(__name__)
nowtime = datetime.now()
@@ -42,7 +43,7 @@ def find_participants(folder='./participant_data/'):
if os.path.isdir(os.path.join(folder,o))]
for path in part_folder:
part_key = os.path.basename(path)
participants[part_key] = Participant(participant_dir=path)
participants[part_key] = deepcopy(Participant(participant_dir=path))
participants[part_key].load('info')
participants[part_key].load('parameters')
return participants
@@ -144,6 +145,7 @@ class Participant:
'''
'''
folder = os.path.join(self.participant_dir, data_key)
# print(f"Participant {self.data['info']['number']}: {folder}")
with open(os.path.join(folder, "{}.pkl".format(data_key)), 'rb') as f:
self.data[data_key].update(dill.load(f))
+13
View File
@@ -0,0 +1,13 @@
from scipy import signal
import matplotlib.pyplot as plt
import numpy as np
def apply_hearing_loss_sim(x, fs, channels=[0, 1]):
b, a = signal.butter(4, 1170.0/(fs/2.), 'low')
if len(x.shape) < 2:
x = x[:, np.newaxis]
for channel in channels:
x[:, channel] = signal.filtfilt(b, a, x[:, channel])
return x
# w, h = signal.freqs(b, a)
+51 -17
View File
@@ -3,6 +3,8 @@
import sys
#sys.path.insert(0, "../helper_modules")
#sys.path.insert(0, "../matrix_test/helper_modules/")
sys.path.insert(0, "../../")
sys.path.insert(0, "../helper_modules")
import argparse
import os
@@ -16,6 +18,11 @@ from natsort import natsorted
from collections import namedtuple
from pysndfile import PySndfile, sndio
import matplotlib.pyplot as plt
from ITU_P56 import asl_P56
from pathlib import Path
from multiprocessing.dummy import Pool as ThreadPool
import multiprocessing
from pathops import dir_must_exist
from signalops import rolling_window_lastaxis, block_lfilter, calc_rms, block_process_wav
@@ -191,7 +198,7 @@ def calc_spectrum(files, silences, fs=44100, plot=False):
return b
def gen_noise(OutDir, b, fs, s_rms):
def gen_noise(OutDir, b, fs):
print("Generating noise...")
# Generate 10 minutes of white noise
x = np.random.randn(int(fs*60.*5.))
@@ -203,9 +210,14 @@ def gen_noise(OutDir, b, fs, s_rms):
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 = np.sqrt(np.mean(y**2))
rms, _, _ = asl_P56(y, fs, 16)
print(f"Noise level: {rms}")
peak = np.abs(y).max()
np.save(noise_rms_path, rms)
np.save('./stimulus/peak/noise_peak.npy', peak)
@@ -215,21 +227,43 @@ def gen_noise(OutDir, b, fs, s_rms):
def calc_speech_rms(files, silences, rmsDir, fs=44100, plot=False):
'''
'''
files = files[:3]
#silences = silences[:3]
f = sum(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((sil.shape[0], t.size), dtype=bool)
for ind3, s in enumerate(sil):
sTemp[ind3, :] = np.logical_and(t > s[0], t < s[1])
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_speech_rms.npy'), rms)
n_files = len(f)
#for ind, (wavfile, sil) in enumerate(zip(f, silences)):
def level_calc(args):
ind, wavfile = args
x, fs, _ = sndio.read(wavfile)
level = asl_P56(x, fs, 16.)[0]
print(f"Calculated level of {Path(wavfile).name} ({ind+1}/{n_files}): {level}")
return level
# Make the Pool of workers
pool = ThreadPool(multiprocessing.cpu_count()-1)
# Open the urls in their own threads
# and return the results
levels = pool.map(level_calc, enumerate(f))
#close the pool and wait for the work to finish
pool.close()
pool.join()
rms = np.mean(levels)
# f = sum(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((sil.shape[0], t.size), dtype=bool)
# for ind3, s in enumerate(sil):
# sTemp[ind3, :] = np.logical_and(t > s[0], t < s[1])
# 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_speech_rms.npy'), rms)
return rms
#sentenceFFT.append(np.abs(Zxx[:, ~np.any(sTemp, axis=0)]))
@@ -268,4 +302,4 @@ if __name__ == "__main__":
silences = detect_silences(rmsFiles, 44100)
s_rms = calc_speech_rms(wavFiles, silences, rmsDir)
b = calc_spectrum(wavFiles, silences)
y = gen_noise(args['OutDir'], b, 44100, s_rms)
y = gen_noise(args['OutDir'], b, 44100)
+1
View File
@@ -98,6 +98,7 @@ def block_process_wav(wavpath, out_wavpath, func, block_size=4096, **args):
y = func(x, **args)
out_wav.write_frames(y)
i += block_size
del out_wav
def window_rms(a, window_size):
print("Squaring...")
@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
import sys
sys.path.insert(0, "../helper_modules/")
sys.path.insert(0, "../../")
import os
from filesystem import globDir
@@ -17,17 +18,27 @@ import csv
from copy import copy
from contextlib import ExitStack
from scipy.signal import square
from ITU_P56 import asl_P56
from pathlib import Path
def calc_potential_max(stim_folder, noise_filepath, out_dir):
max_wav_samp = 0
max_wav_rms = 0
wavs = globDir(stim_folder, '*.wav')
for wav in wavs:
n_files = len(wavs)
for ind, wav in enumerate(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))])
#max_wav_rms = np.max([max_wav_rms, np.sqrt(np.mean(x**2))])
level = asl_P56(x, fs, 16.)[0]
max_wav_rms = np.max([max_wav_rms, ])
print(f"Calculated level of {Path(wav).name} ({ind+1}/{n_files}): {level}")
x, fs, enc = sndio.read(noise_filepath)
noise_rms = np.sqrt(np.mean(x**2))
# noise_rms = np.sqrt(np.mean(x**2))
print(f"Calculating level of {Path(noise_filepath).name}")
noise_rms, _, _ = asl_P56(x, fs, 16.)
print(f"Calculated level of {Path(noise_filepath).name}: {noise_rms}")
max_noise_samp = max(np.abs(x))
snr = -15.0
@@ -56,7 +67,7 @@ def main():
dir_must_exist(wav_dir)
dir_must_exist(noise_dir)
noise_filepath = "../behavioural_stim/stimulus/wav/noise/noise.wav"
noise_filepath = "../behavioural_stim/stimulus/wav/noise/noise_norm.wav"
folders = os.listdir(base_dir)
folders = natsorted(folders)[1:15]
+14 -4
View File
@@ -21,6 +21,9 @@ import sounddevice as sd
import pdb
from config import socketio
from hearing_loss_sim import apply_hearing_loss_sim
from ITU_P56 import asl_P56
from pathlib import Path
import logging
logger = logging.getLogger(__name__)
@@ -143,6 +146,7 @@ class MatTestThread(BaseThread):
self.loadNoise(noiseFilepath, noiseRMSFilepath)
self.dev_mode = False
self.audio_cal = False
def displayInstructions(self):
@@ -185,6 +189,8 @@ class MatTestThread(BaseThread):
self.lists[0][currentSentenceInd],
self.listsRMS[0][currentSentenceInd]
)
if self.participant.parameters['hl_sim_active']:
self.y = apply_hearing_loss_sim(self.y, self.fs, channels=[0])
# Define words presented in the current trial
self.currentWords = self.listsString[0][currentSentenceInd]
@@ -193,7 +199,11 @@ class MatTestThread(BaseThread):
logger.info("{0:<25}".format("Current track index:") + f"{self.adTrInd}")
logger.info("{0:<25}".format("Current trial number:") + f"{self.trialN}")
logger.info("{0:<25}".format("Current SNR:") + f"{self.adaptiveTracks[self.adTrInd].snr}")
self.playStimulus(self.y, self.fs)
if self.audio_cal:
y, fs, fmt = sndio.read('./calibration/out/stimulus/mat_cal_stim.wav')
self.playStimulus(y, fs)
else:
self.playStimulus(self.y, self.fs)
self.waitForResponse()
self.checkSentencesAvailable()
if self.finishTest:
@@ -388,9 +398,9 @@ class MatTestThread(BaseThread):
# Get data for each sentence
for fp, words, level_file in zip(listAudiofiles, csv_reader, levels):
# Read in audio file and calculate it's RMS
level = loadmat(level_file)
x, self.fs, _ = sndio.read(fp)
x_rms = np.sqrt(np.mean(x**2))
logger.info(f"Calculating level for {Path(fp).name}")
x_rms, _, _ = asl_P56(x, self.fs, 16.)
self.lists[-1].append(x)
self.listsRMS[-1].append(x_rms)
self.listsString[-1].append(words)
@@ -531,7 +541,7 @@ class AdaptiveTrack():
x_noise *= x_rms/self.noise_rms
y = x_noise
# Set speech to start 500ms after the noise, scaled to the desired SNR
sigStart = random.randint(self.fs, round(2*self.fs))
sigStart = random.randint(round(self.fs/2.), round(2*self.fs))
y[sigStart:sigStart+x.size] += x*snr_fs
y *= self.reduction_coef
return y
+3 -3
View File
@@ -20,13 +20,13 @@
<div class="form-group container-fluid">
<div class="row">
<div class="col text-center mb-3">
<button type="button" id="start_mat_train" class="btn btn-primary mx-3">Start matrix training data collection</button>
<button type="button" id="start_story_train" class="btn btn-primary mx-3">Start story training data collection</button>
</div>
<div class="col text-center mb-3">
<button type="button" id="load_mat_train_saved" class="btn btn-primary mx-3">Load saved session</button>
<button type="button" id="load_train_story_saved" class="btn btn-primary mx-3">Load saved session</button>
</div>
<div class="col text-center mb-3">
<button type="button" id="load_mat_train_backup" class="btn btn-primary mx-3">Load previous automatic backup</button>
<button type="button" id="load_train_story_backup" class="btn btn-primary mx-3">Load previous automatic backup</button>
</div>
</div>
<div class="row">
+1 -1
View File
@@ -74,7 +74,7 @@
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/pta_test">PTA</a>
<a class="dropdown-item" href="/tympanometry">Tympanometry</a>
<!--<a class="dropdown-item" href="/tympanometry">Tympanometry</a>-->
<a class="dropdown-item" href="/da/setup">Tone EEG recording</a>
<a class="dropdown-item" href="/matrix_test">Behavioral Matrix Test</a>
<a class="dropdown-item" href="/eeg">Decoder EEG recording</a>