Hi, I was working on this Line Bisection task using Psychopy. I keep running into the error regarding playing audio files. I’m fairly new to coding.
It runs fine with practice and training block, but it just crashes as soon as it gets to the test block.
In the test block 1, I’m trying to have randomly selected audio files prior to each trial of line bisection task, and there are 60 FLAC audio files for 60 line bisection trials. Each audio file is 5 second long, the file size ranging from 100 kb to 200 kb. The audio files are on my computer and I have also included the paths to the audio files in the code. I’ve set PTB as the audio backend and also installed the sounddevice plugin from within the software. I thought maybe the file amount was too much so I had changed the code to just 5 files just for it show the same error. Are there any solutions to it in the coding? or would I have to find alternatives?
I have added the error and code below. Thank you guys for your time!
The error:
Hello from the pygame community. Contribute - pygame wiki
Experiment cancelled
################ Experiment ended with exit code 0 [pid:18820] #################
Running: C:\Users\mofas\OneDrive\Desktop\line bisection 2nd round.py
pygame 2.1.0 (SDL 2.0.16, Python 3.8.10)
Hello from the pygame community. Contribute - pygame wiki
Traceback (most recent call last):
12.7684 WARNING Monitor specification not found. Creating a temporary one…
File “C:\Users\mofas\OneDrive\Desktop\line bisection 2nd round.py”, line 168, in
task_block_with_dynamic_audio(win0, no_test_trials_per_block, “Test Block 1”, audio=True)
File “C:\Users\mofas\OneDrive\Desktop\line bisection 2nd round.py”, line 84, in task_block_with_dynamic_audio
play_audio_dynamically(audio_files[audio_index])
File “C:\Users\mofas\OneDrive\Desktop\line bisection 2nd round.py”, line 69, in play_audio_dynamically
sound_file = SoundPTB(value=file_path, stereo=True)
File “C:\Program Files\PsychoPy\lib\site-packages\psychopy\sound\backend_ptb.py”, line 351, in init
self.setSound(value, secs=self.secs, octave=self.octave,
File “C:\Program Files\PsychoPy\lib\site-packages\psychopy\sound\backend_ptb.py”, line 440, in setSound
_SoundBase.setSound(self, value, secs, octave, hamming, log)
File “C:\Program Files\PsychoPy\lib\site-packages\psychopy\sound_base.py”, line 209, in setSound
self._setSndFromFile(p)
File “C:\Program Files\PsychoPy\lib\site-packages\psychopy\sound\backend_ptb.py”, line 473, in _setSndFromFile
sndArr = self.sndFile.read(
File “C:\Program Files\PsychoPy\lib\site-packages\soundfile.py”, line 863, in read
out = self._create_empty_array(frames, always_2d, dtype)
File “C:\Program Files\PsychoPy\lib\site-packages\soundfile.py”, line 1291, in _create_empty_array
return np.empty(shape, dtype, order=‘C’)
ValueError: array is too big; arr.size * arr.dtype.itemsize
is larger than the maximum possible size.
################ Experiment ended with exit code 1 [pid:25108] #################
The code:
Importing modules
import os
from datetime import datetime
from psychopy import logging, visual, core, event, clock, gui, prefs
from psychopy.sound.backend_ptb import SoundPTB
import numpy as np
from random import shuffle, randint
import pandas as pd
Set PTB as the preferred audio backend
prefs.hardware[‘audioLib’] = [‘ptb’]
Experiment configuration
no_practice_trials = 5
no_training_trials = 15
no_test_trials_per_block = 60
line_length_array = [378, 567, 756] # Line lengths in pixels
horizontal_range = (-400, 400) # Horizontal range for line positions (in pixels)
vertical_range = (-300, 300) # Vertical range for line positions (in pixels)
Audio Configuration
audio_path = r"C:\Users\mofas\OneDrive\Documents\Uni\2024 Fall - 2025 Winter\Honours project\Stimulis\Imagined"
audio_files = [os.path.join(audio_path, f"{i}.flac") for i in range(1, 61)] # 1-60 FLAC files
shuffle(audio_files) # Randomize order
Output data variables
output_data =
GUI for participant information
date_val = datetime.now().strftime(‘%d%m%Y’)
myDlg = gui.Dlg(title=“Line Bisection Task”)
myDlg.addText(‘Subject Info’)
myDlg.addField(‘Exp Date’, date_val)
myDlg.addField(‘SubID:’)
myDlg.addField(‘Sex:’, choices=[‘Male’, ‘Female’, ‘Prefer not to say’])
myDlg.addField(‘Age:’)
show_dlg = myDlg.show()
if not myDlg.OK:
print(‘Experiment cancelled’)
core.quit()
Save participant info
sub_id = show_dlg[1]
exp_date = show_dlg[0]
Window setup
win0 = visual.Window(size=(1024, 768), color=(0, 0, 0), fullscr=False, units=‘pix’)
Mouse setup
mymouse = event.Mouse(win=win0)
Function to draw a line at a random position
def draw_line(win, length):
x_pos = randint(*horizontal_range)
y_pos = randint(*vertical_range)
hor_line = visual.Rect(win,
width=length,
height=1,
units=‘pix’,
lineColor=[-1, -1, -1],
fillColor=[-1, -1, -1],
pos=(x_pos, y_pos))
hor_line.draw()
return (x_pos, y_pos)
Function to play a single audio file dynamically using PTB
def play_audio_dynamically(file_path):
sound_file = SoundPTB(value=file_path, stereo=True)
sound_file.play()
core.wait(sound_file.getDuration()) # Wait for the audio to finish
Task block function with dynamic audio playback
def task_block_with_dynamic_audio(win, num_trials, trial_type, audio=False):
global output_data
audio_index = 0
for trial in range(num_trials):
# Clear events and mouse state
event.clearEvents()
mymouse.clickReset()
# Play audio if enabled
if audio and audio_index < len(audio_files):
play_audio_dynamically(audio_files[audio_index])
audio_index += 1
# Randomly select a line length and draw it
line_length = np.random.choice(line_length_array)
(x_pos, y_pos) = draw_line(win, line_length)
win.flip()
# Wait for participant response
start_time = clock.getTime()
response_recorded = False
while not response_recorded:
buttons = mymouse.getPressed()
keys = event.getKeys()
if buttons[0]: # Left mouse button clicked
stop_time = clock.getTime()
response_time = round((stop_time - start_time) * 1000, 2)
mouse_x, mouse_y = mymouse.getPos()
# Calculate deviation
deviation = round(((mouse_x - x_pos) / line_length) * 100, 2)
# Save trial data
output_data.append({
"Trial Type": trial_type,
"Line Length (px)": line_length,
"Line Position (x, y)": (x_pos, y_pos),
"Mouse Click Position (x, y)": (mouse_x, mouse_y),
"Deviation (-100 to +100)": deviation,
"Response Time (ms)": response_time
})
response_recorded = True
# Add a short delay to prevent accidental double clicks
core.wait(0.2)
# Exit with ESC key
if 'escape' in keys:
save_data()
win.close()
core.quit()
core.wait(0.5)
Save data to CSV
def save_data():
df = pd.DataFrame(output_data)
output_file = f"{exp_date}_{sub_id}_line_bisection_task.csv"
df.to_csv(output_file, index=False)
print(f"Data saved to {output_file}")
Display instructions function
def display_instructions(win, text):
instruction = visual.TextStim(win,
text=text,
color=(-1, -1, -1),
height=32,
wrapWidth=800,
pos=(0, 0))
instruction.draw()
win.flip()
while True:
key = event.waitKeys()
if ‘return’ in key:
break
elif ‘escape’ in key:
save_data()
win.close()
core.quit()
Run the experiment
display_instructions(win0, “Welcome to the Line Bisection Task!\n\nPress ENTER to continue.”)
Practice block
display_instructions(win0, “Practice Block: 5 trials.\n\nPress ENTER to begin.”)
task_block_with_dynamic_audio(win0, no_practice_trials, “Practice”, audio=False)
Training block
display_instructions(win0, “Training Block: 15 trials.\n\nPress ENTER to begin.”)
task_block_with_dynamic_audio(win0, no_training_trials, “Training”, audio=False)
Test block 1
display_instructions(win0, “Test Block 1: 60 trials.\n\nPress ENTER to begin.”)
task_block_with_dynamic_audio(win0, no_test_trials_per_block, “Test Block 1”, audio=True)
Break
display_instructions(win0, “Take a 1-minute break. Press ENTER when ready to continue.”)
Test block 2
display_instructions(win0, “Test Block 2: 60 trials.\n\nPress ENTER to begin.”)
task_block_with_dynamic_audio(win0, no_test_trials_per_block, “Test Block 2”, audio=False)
End of experiment
display_instructions(win0, “Thank you for participating!\n\nPress ENTER to exit.”)
save_data()
win0.close()
core.quit()