-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsdt.py
More file actions
112 lines (90 loc) · 4.32 KB
/
Copy pathsdt.py
File metadata and controls
112 lines (90 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/python
# -*- coding: utf-8 -*-a
# Psychophysical concepts by auditory demonstrations ---------------------------
# Basic demonstration of SDT. This just plays a tone in noise or just noise
# MN 2017-03-03, revised: 2017-10-03
# ------------------------------------------------------------------------------
import psychopy.visual, psychopy.event, psychopy.data, psychopy.gui
import numpy as np
import sounddevice as sd
import soundfile as sf
import time # function time-sleep()
import mn # User made functions, make sure mn.py is located in the working dir
# Display sound device, output device marked <
sd.default.device = "Analog (1+2) (Babyface Analog (1+2))" # "ASIO4ALL" #
# print 'Sound device ------------------------------------------------------------'
# print sd.query_devices()
# print '-------------------------------------------------------------------------'
def create_sn(ndur = 0.8, sdur = 0.4, snratio = -40, fs = 48000, rms = -20):
# Create noise and signal
noise = mn.create_wn(int(np.round(ndur * fs)))
signal = mn.create_sinusoid(freq = 1000, phase = 0, dur = sdur, fs = fs)
silence = np.zeros(int(np.round(((ndur - sdur) * fs)/2)))
signal = np.concatenate((silence, signal, silence))
signal = 10**(snratio/20.0) * signal # Set gain of signal relative to noise
# Combine noise and signal, and apply fade
combined = mn.fade(noise + signal, int(fs * 0.05))
combined = mn.set_gain(combined, rms)
# Make diotic
s = np.transpose(np.array([combined,combined]))
return s
def play_sequence(ratiolist, fs = 48000):
message1 = psychopy.visual.TextStim(win, pos = [0, 0.2], color = (-1, -1, -1),
text = "Listen for the tone", height = 0.07)
message2 = psychopy.visual.TextStim(win, pos = [0, -0.2], color = (-1, -1, -1),
text = "Hit a key to start", height = 0.05)
message1.draw()
message2.draw()
win.flip()
psychopy.event.waitKeys()
for j in trials:
message1.text = "Did you hear the tone?\n\n(integer + return to continue; Esc to abort)"
message2.text = "Signal level = %.1f: " % (j)
s = create_sn(snratio = j)
sd.play(s, fs)
time.sleep(len(s) / float(fs))
message1.draw()
if int(show_sn) == 1:
message2.draw()
win.flip()
# Collect response
response = None
all_keys = np.array([])
while response is None:
key = psychopy.event.waitKeys(
keyList=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'return', 'escape'])
all_keys = np.append(all_keys, key)
if key == ['return']:
r = all_keys[:-1] # Remove 'return' key
r = ''.join(r)
print 'sn-ratio = ' + str(round(j, 1)) + '; response = ' + r
response = r
elif key == ['escape']:
print '\n\nUser abort\n\n'
raise SystemExit # Abort experiment
else: pass
win.flip()
time.sleep(0.1)
# Dialog box decide sequence ---------------------------------------------------
id_dict = {'slevel': '-32', 'trials-s+n': '5', 'trials-n': '5', 'show sn': '0'}
dlg = psychopy.gui.DlgFromDict(id_dict, title = 'Enter ID number and Day of testing!')
if dlg.OK:
level = id_dict['slevel'] # Record id (str)
sn = id_dict['trials-s+n'] # Record id (str)
nn = id_dict['trials-n'] # Record id (str)
show_sn = id_dict['show sn']
else:
raise SystemExit # The user hit cancel, so exit
win = psychopy.visual.Window([600, 600], color = (0, 1, 0), pos = (0, 0),
allowGUI = False, monitor = 'testMonitor', units = 'norm')
# Trial sequence -----------------------------------------------------------
sn = np.repeat(float(level), float(sn))
nn = np.repeat(-999, float(nn))
trials = np.concatenate((sn, nn))
np.random.shuffle(trials)
# ------------------------------------------------------------------------------
fs = 48000
print '\n\n\n\n\n\n\n\n\n\n-----------------------------------------------------'
play_sequence(ratiolist = trials)
print '-----------------------------------------------------\n\n\n\n\n\n\n\n\n\n'