Loading sounds on the fly

URL of experiment: https://pavlovia.org/theoceanistea/gap-detection

Description of the problem:
I found out about being able to load resources as needed. This seems like a solution to the problem of not wanting the participant to load every wav file they might need to hear before starting the experiment.

When I load the resource noise.wav from the html folder at the head of the program, it plays. But when I load it on the fly using downloadResources, it gives me the error,

Unfortunately we encountered the following error:

  • when finding a player for the sound
  • could not find an appropriate player.

Try to run the experiment again. If the error persists, contact the experiment designer.

How can I avoid this?

Thanks,
Jon

1 Like

Can anyone help with this one? Iā€™ve tried switching to mp3, but same error.

Ok, I finally fixed it. I think the task was going on before the loading finished. My fix was to load the sound file during the previous routine, which lasts for 5+ seconds and apparently leaves enough time for the file to load.

I was wrong. The fixed that actually fixed it was changing to the command

psychoJS._serverManager.downloadResources

rather than psychoJS.downloadResources. I think thereā€™s a problem with the source code defining psychoJS.downloadResources? Maybe a missing underscore? Iā€™m just learning javascript, so Iā€™m not sure.

How does this actually work?

Iā€™d like to suppress downloading all the resources at the beginning of the experiment and then download the set of 7 wav files I actually need during the experiment.

Iā€™d like to be able to do this via code components rather than editing the js files directly.

Best wishes,

Wakefield

Hi Wakefield,
Iā€™m still a little confused about this, but it looks like everything in the html/resources folder is automatically downloaded (unless you change the js code), and everything else is ignored. If you then insert

psychoJS._serverManager.downloadResources([
{ name: [filename], path: [filename+(path relative to html folder) OR (web address)] }
]);

at the beginning of a routine, you can use the file [filename] after that. BUTā€¦ Iā€™ve been pulling files from another website, and it takes time to get the file, and the code does not wait for the file to load, so there needs to be a sufficient delay between the download call and the use of the file.

Thatā€™s all Iā€™ve figured out so far.

Thanks for your help earlier, hope Iā€™m being helpful here!
Jon

PS. Now Iā€™m not sure thereā€™s actually a problem with the regular psychoJS.downloadResources command ā€“ I think it was just a problem with it blocking as described here:

But now that Iā€™ve got it working, Iā€™ll just stick with psychoJS._serverManager.downloadResources. Call me superstitious.

Iā€™ve tried
psychoJS._serverManager.downloadResources([
{ name: [ā€œ01F_HA_O.jpgā€], path: [(ā€œNim-Face-Stimuli/01F_HA_O.jpgā€)] }
]);

Any ideas?

I first tried to put the images in a sub folder from the Python code and used ā€¦/Nim-Face-Stimuli/01F_HA_O.jpg but then I thought that maybe the files have to be in the html folder or below it.

I get an unknown resource error:

  • when setting the image of ImageStim: images
  • when getting the value of resource: Nim-Face-Stimuli/01F_HA_O.jpg
  • unknown resource

Sorted. I needed

 psychoJS.downloadResources([
{ name: '01F_HA_O.jpg', path: 'Nim-Face-Stimuli/01F_HA_O.jpg' },
{ name: '01F_NE_C.jpg', path: 'Nim-Face-Stimuli/01F_NE_C.jpg' }
]);

The error occurs when itā€™s specified twice.

Iā€™ve also confirmed that the files donā€™t need to be in/below the html folder

1 Like

Hi,

This topic is very helpful for my case too

However, the auditory files I would like to load are listed in a specific column of a .csv file.
I tried to run the function with the following code

psychoJS.downloadResources([
{ name: 'XXX.csv', path: 'YYY/XXX.csv' },
]);

However, it does not work.

Do I need to specify each file in the psychoJS.downloadResources()?
Or is there any easy way to load all the files listed in a specific column of a .csv file.

Thanks!

If you load the contents of your csv intro arrays or a Trial Handler then you could set up a loop to append dictionary entries so you can use downloadResources. The code youā€™ve written looks like itā€™s asking PsychoJS to download the csv file, not things references in it.

Thanks @wakecarter!
Would you mind to provide a reference or an example? Sorry that I am very new to Javascript.
Thanks in advance!

Hereā€™s some JS code that downloads the last three sound files from each of two arrays.

shuffle(naturalSpeech);
shuffle(repeatedSpeech);

wordsLeft = naturalSpeech.length;

psychoJS.downloadResources([
{ name: (naturalSpeech[wordsLeft-1]), path: ("../CS/" + naturalSpeech[wordsLeft-1]) },
{ name: (naturalSpeech[wordsLeft-2]), path: ("../CS/" + naturalSpeech[wordsLeft-2]) },
{ name: (naturalSpeech[wordsLeft-3]), path: ("../CS/" + naturalSpeech[wordsLeft-3]) },
{ name: (repeatedSpeech[wordsLeft-1]), path: ("../SS/" + repeatedSpeech[wordsLeft-1]) },
{ name: (repeatedSpeech[wordsLeft-2]), path: ("../SS/" + repeatedSpeech[wordsLeft-2]) },
{ name: (repeatedSpeech[wordsLeft-3]), path: ("../SS/" + repeatedSpeech[wordsLeft-3]) }
]);


Looking at it now, Iā€™m not sure I needed wordsLeft because [-1] already refers to the final item in an array.

If you arenā€™t sure how to load csv/Excel files into an array, please look at my template file. Brookes Template 2020

You should also be able to create a loop to build the dictionary,

e.g. Begin Experiment = resourceList = []

Begin Routine (within a loop)
resourceList.push({ name: (var1+".extension"), path: ("ā€¦/stimulusFolder/"+var1+".extension")});

then (but make sure you give time for them to load)

psychoJS.downloadResources(resourceList);

1 Like

Thanks it works!

A little addition to the approach above, since Iā€™ll point @Zhaleh to this thread. A nice way of checking whether a resource has been downloaded is as followed:

Step 1. Have a routine for downloading resources, maybe add a text like ā€œOne moment pleaseā€ to keep your participant informed.

Step 2. Add a code component.
Step 2a. In the begin routine tab of that code component, call PsychoJS to download the resource. For example:

psychoJS.downloadResources([
  { name: 'my_sound.mp3', path: 'sounds/my_sound.mp3' }
]);

Step 2b. In the each frame tab, keep checking whether the sound has downloaded. Once it does, finish the routine, and you can use the sound in a successive routine. Below we use the following trick: if psychoJS.serverManager.getResource('my_sound.mp3') does not throw an error, the resource is available.

try {
    psychoJS.serverManager.getResource('my_sound.mp3');
    continueRoutine = false;
} catch (e) {}

The example above is an adaptation of: Thomas Pronk / demo_font Ā· GitLab

1 Like