Hi everyone,
I have two questions, but the first one is the most important:
- Does checking the status of a sound object (created with the preferences for audioLib set to ‘ptb’) give me an indication of the lag of this sound. This depends on how the status of a sound component is set under the hood and whether the time point when the status attribute is set to -1 is linked to the offset of the sound. It would be very helpful, if I could use this knowledge of the lag for every sound to correct for it in my reaction time measurements.
from psychopy import prefs
prefs.hardware['audioLib'] = 'ptb'
prefs.hardware['audioLatencyMode'] = '4'
import psychtoolbox as ptb
from psychopy import sound
from psychopy.constants import PLAYING
from psychopy.hardware import keyboard
from psychopy import core
# create a default keyboard
defaultKeyboard = keyboard.Keyboard()
# create sound and get time
s_len = 0.01
s1_sound = sound.Sound('G', secs=s_len, stereo=True, hamming=True, name='s1_sound')
s1_onset = 2.5
s1_offset = s1_onset + s_len
PTB_start = ptb.GetSecs()
# play the sound
s1_sound.play(when=PTB_start + s1_onset)
while s1_sound.status == PLAYING:
if defaultKeyboard.getKeys(keyList=["escape"]):
core.quit()
# print the delay
print('Delay: {}'.format( ptb.GetSecs() - PTB_start - s1_offset) )
core.wait(2)
- In my experiment, I play pairs of sounds. If I check the offset of the sounds, I see a systematic difference in lag for the first and the second sound. The first sound seems to finish earlier, the second seems to finish later than scheduled. Should I account for this systematic difference in lags by adjusting the scheduled sound onset times?
I know that I could improve latencies with a better sound card, and I will run the actual experiment on a PC with a better sound card, but I think my questions are valid irrespective of the sound card.
Here a simplified version of the relevant part of the experiment:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from psychopy import prefs
prefs.hardware['audioLib'] = 'ptb'
prefs.hardware['audioLatencyMode'] = '4'
import psychtoolbox as ptb
from psychopy import sound, visual, core
from psychopy.constants import PLAYING
from psychopy.hardware import keyboard
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
from os import getcwd
# Setup the Window
win = visual.Window(
size=[1536, 864], fullscr=True, screen=0,
winType='pyglet', allowGUI=False, allowStencil=False,
monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
blendMode='avg', useFBO=True,
units='height')
# create a default keyboard
defaultKeyboard = keyboard.Keyboard()
# Initialize sounds
s_len = 0.01
s1_sound = sound.Sound('G', secs=s_len, stereo=True, hamming=True, name='s1_sound')
s2_sound = sound.Sound('A', secs=s_len, stereo=True, hamming=True, name='sound_2')
s1_onset = 2.5; s1_offset = s1_onset + s_len
s2_onset = 3; s2_offset = s2_onset + s_len
s1_delay = []
s2_delay = []
PTB_start = ptb.GetSecs()
for thisTrial in range(30):
s1_sound.stop()
s2_sound.stop()
s1_sound.play(when=PTB_start + s1_onset)
s2_sound.play(when=PTB_start+ s2_onset)
while s1_sound.status == PLAYING:
if defaultKeyboard.getKeys(keyList=["escape"]):
core.quit()
s1_delay.append(ptb.GetSecs() - PTB_start - s1_offset)
while s2_sound.status == PLAYING:
if defaultKeyboard.getKeys(keyList=["escape"]):
core.quit()
s2_delay.append(ptb.GetSecs() - PTB_start - s2_offset)
PTB_start = ptb.GetSecs()
# print descriptive statistics of offset latencies
for delayList, stim in [(s1_delay, 's1'), (s2_delay, 's2')]:
print('{}: mean={:.0f} ms, sd={:.0f} ms'.format(
stim,
sum(delayList)/len(delayList)*1000,
np.std(delayList)*1000))
# compare offset latencies
ttest = stats.ttest_ind(s1_delay, s2_delay)
print('t-test: t={:.3f}, p={:.3f}'.format(ttest.statistic, ttest.pvalue))
# boxplots
fig1, ax1 = plt.subplots()
ax1.boxplot([np.array(s1_delay)*1000, np.array(s2_delay)*1000])
plt.ylabel('lag in ms')
plt.xticks([0, 1, 2], ['', 's1', 's2'])
figPath = getcwd() + '\\compare_latencies_soundPTB.png'
plt.savefig(figPath)
print('Figure saved to: {}'.format(figPath))
core.quit()
The output of my script:
s1: mean=-19 ms, sd=3 ms
s2: mean=26 ms, sd=3 ms
t-test: t=-51.632, p=0.000