Skip to content

Commit 2c1361e

Browse files
committed
first sounds
1 parent a045593 commit 2c1361e

File tree

2 files changed

+90
-5
lines changed

2 files changed

+90
-5
lines changed
Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
import json
2+
13
import pandas as pd
4+
import numpy as np
5+
import logging
6+
7+
from pybpodapi.state_machine import StateMachine
28

3-
import iblrig
4-
import iblrig.misc
5-
import iblrig.sound
9+
from iblrig import sound
610
from iblrig.base_tasks import BaseSession, BpodMixin
11+
from iblrig.misc import get_task_arguments
12+
13+
logger = logging.getLogger('iblrig')
714

815

916
class Session(BpodMixin, BaseSession):
@@ -12,10 +19,80 @@ class Session(BpodMixin, BaseSession):
1219
def __init__(self, *args, **kwargs):
1320
super().__init__(*args, **kwargs)
1421

15-
self.attenuation = pd.read_csv(self.get_task_directory().joinpath('attenuation.csv'))
22+
assert self.hardware_settings.device_sound.OUTPUT == 'harp', 'This task requires a Harp sound-card'
23+
assert self.task_params['n_freqs'] <= 31, 'Harp only supports up to 31 individual sounds'
24+
25+
# define frequencies (log spaced from freq_0 to freq_1, rounded to nearest integer)
26+
self.frequencies = np.logspace(
27+
np.log10(self.task_params['freq_0']),
28+
np.log10(self.task_params['freq_1']),
29+
num=self.task_params['n_freqs'],
30+
)
31+
self.frequencies = np.round(self.frequencies).astype(int)
32+
33+
# generate stimuli
34+
self.stimuli = []
35+
for f in self.frequencies:
36+
tmp = sound.make_sound(
37+
rate=self.task_params['fs'],
38+
frequency=f,
39+
duration=self.task_params['d_sound'],
40+
amplitude=self.task_params['amplitude'],
41+
fade=self.task_params['d_ramp'],
42+
chans='stereo',
43+
gain_db=0,
44+
)
45+
self.stimuli.append(tmp)
46+
self.indices = [i for i in range(2, len(self.stimuli) + 2)]
47+
48+
# self.attenuation = pd.read_csv(self.get_task_directory().joinpath('attenuation.csv'))
49+
50+
def start_mixin_sound(self):
51+
logger.info(f'Pushing {len(self.frequencies)} stimuli to Harp soundcard')
52+
sound.configure_sound_card(sounds=self.stimuli, indexes=self.indices, sample_rate=self.task_params['fs'])
53+
54+
module = self.bpod.sound_card
55+
module_port = f'Serial{module.serial_port if module is not None else "3"}'
56+
for idx, harp_index in enumerate(self.indices):
57+
bpod_message = [ord("P"), harp_index]
58+
bpod_action = (module_port, self.bpod._define_message(self.bpod.sound_card, bpod_message))
59+
self.bpod.actions.update({f'play_{idx}': bpod_action})
60+
61+
def start_hardware(self):
62+
self.start_mixin_bpod()
63+
self.start_mixin_sound()
64+
65+
def get_state_machine(self, sequence):
66+
sma = StateMachine(self.bpod)
67+
# table = self.sequence_table[self.sequence_table['sequence'] == sequence].reindex()
68+
69+
for i, frequency in enumerate(self.frequencies):
70+
sma.add_state(
71+
state_name=f"trigger_sound_{i}",
72+
state_timer=self.task_params['d_sound'] + self.task_params['d_pause'],
73+
output_actions=[self.bpod.actions[f'play_{i}']],
74+
state_change_conditions={
75+
"Tup": f"trigger_sound_{i + 1}",
76+
},
77+
)
78+
sma.add_state(
79+
state_name=f"trigger_sound_{i + 1}",
80+
state_timer=0.0,
81+
state_change_conditions={"Tup": "exit"},
82+
)
83+
return sma
84+
85+
def _run(self):
86+
logger.info("Sending spacers to BNC ports")
87+
self.send_spacers()
88+
89+
sma = self.get_state_machine(1)
90+
self.bpod.send_state_machine(sma)
91+
self.bpod.run_state_machine(sma)
92+
1693

1794

1895
if __name__ == '__main__': # pragma: no cover
19-
kwargs = iblrig.misc.get_task_arguments()
96+
kwargs = get_task_arguments()
2097
sess = Session(**kwargs)
2198
sess.run()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'freq_0': 2000 # lowest frequency to map (Hz)
2+
'freq_1': 16000 # highest frequency to map (Hz)
3+
'n_freqs': 30 # number of frequencies to map - Harp supports a maximum of 30 individual sounds
4+
'd_pause': 0.01 # duration of silence inbetween sound pulses (s)
5+
'd_sound': 0.15 # duration of sound pulse (s)
6+
'd_ramp': 0.01 # duration of Hanning ramp (s)
7+
'amplitude': 0.05 # initial amplitude of all stimuli prior to dB attenuation
8+
'fs': 192000 # sampling rate (Hz) - Harp supports 96000 Hz and 192000 Hz

0 commit comments

Comments
 (0)