Compare commits
2 Commits
jspsych@6.
...
23ec2b02b9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23ec2b02b9 | ||
|
|
2a130f79b8 |
@@ -11,8 +11,12 @@ We've implemented some generic methods for audio testing with jsPsych:
|
||||
|
||||
* A plugin to do alternative forced choice with sounds: [jspsych-audio-sequence-button-response](docs/jspsych-audio-sequence-button-response.md).
|
||||
* A plugin to do extend `audio-keyboard-response`: [jspsych-audio-keyboard-response-wait](docs/jspsych-audio-keyboard-response-wait.md).
|
||||
* A plugin to do extend `audio-keyboard-response`: [jspsych-audio-keyboard-response-clickable](plugins/jspsych-audio-keyboard-response-clickable.js).
|
||||
* A plugin to display a Coordinate Response Measure interface: [jspsych-crm](docs/jspsych-crm.md).
|
||||
* A plugin to do display a loading spinner while waiting for a (possible async) function to complete: [jspsych-waitfor-function](docs/jspsych-waitfor-function.md).
|
||||
* A plugin where html can be clickable: [jspsych-html-keyboard-response-clickable](plugins/jspsych-html-keyboard-response-clickable.js).
|
||||
* A plugin where images can be clickable: [jspsych-image-keyboard-response-clickable](plugins/jspsych-image-keyboard-response-clickable.js).
|
||||
* A plugin to deal with Safari's quirky behaviour: [jspsych-audio-safari-init](plugins/jspsych-audio-safari-init.js).
|
||||
|
||||
## Tools
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ The trial can end when the subject responds, when the audio file has finished pl
|
||||
|
||||
Note that the buttons are disabled during playing so the subject cannot press any button during that time.
|
||||
|
||||
Make sure to define a CSS style for `.jspsych-audio-sequence-button-response button.highlighted` to see the button light up, and you may have to use `!important` for it to show up.
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameters with a default value of *undefined* must be specified. Other parameters can be left unspecified if the default value is acceptable.
|
||||
@@ -72,6 +74,18 @@ The animation of the visual feedback can make use of [Semantic UI's transitions]
|
||||
|
||||
#### Three alternative forced choice (3AFC)
|
||||
|
||||
CSS:
|
||||
```css
|
||||
.jspsych-audio-sequence-button-response button {
|
||||
min-width: 5em;
|
||||
min-height: 4em;
|
||||
}
|
||||
.jspsych-audio-sequence-button-response button.highlighted {
|
||||
background-color: #ffff00 !important;
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```javascript
|
||||
var trial = {
|
||||
type: 'audio-button-response',
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/**
|
||||
* jspsych-audio-sequence-button-response
|
||||
* Etienne Gaudrain <etienne.gaudrain@cnrs.fr>
|
||||
* jspsych-audio-sequence-button-response for jsPsych v6.3
|
||||
* Etienne Gaudrain <etienne.gaudrain@cnrs.fr> 2021-10-15
|
||||
*
|
||||
* Plugin for playing a sequence of audio files and getting an HTML button response
|
||||
*
|
||||
* Based on jspsych-audio-button-response.
|
||||
*
|
||||
* 2022-03-19: Fixed bug that ISI was applied also to last item.
|
||||
**/
|
||||
|
||||
jsPsych.plugins["audio-sequence-button-response"] = (function() {
|
||||
@@ -103,11 +105,7 @@ jsPsych.plugins["audio-sequence-button-response"] = (function() {
|
||||
plugin.trial = function(display_element, trial) {
|
||||
|
||||
var context = jsPsych.pluginAPI.audioContext();
|
||||
if(context !== null) {
|
||||
var source;
|
||||
} else {
|
||||
var audio;
|
||||
}
|
||||
var audio;
|
||||
|
||||
if(trial.visual_feedback===true && trial.i_correct===null)
|
||||
throw "'i_correct' has to be defined if visual feedback is requested.";
|
||||
@@ -125,12 +123,6 @@ jsPsych.plugins["audio-sequence-button-response"] = (function() {
|
||||
play_next_audio.i = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
// We un-highlight the previous button
|
||||
if(play_next_audio.i>0)
|
||||
$(display_element).find('#jspsych-audio-sequence-button-response-' + (play_next_audio.i-1) +' button').toggleClass('highlighted');
|
||||
*/
|
||||
|
||||
// Is it the last stimulus, do we need to end trial?
|
||||
if(play_next_audio.i >= trial.stimuli.length) {
|
||||
$(display_element).find(".jspsych-audio-sequence-button-response button").removeClass("disabled").prop('disabled', false);
|
||||
@@ -141,34 +133,37 @@ jsPsych.plugins["audio-sequence-button-response"] = (function() {
|
||||
}
|
||||
|
||||
// Prepare the next sound to play
|
||||
if(context !== null) {
|
||||
source = context.createBufferSource();
|
||||
source.buffer = jsPsych.pluginAPI.getAudioBuffer(trial.stimuli[play_next_audio.i]);
|
||||
source.connect(context.destination);
|
||||
source.onended = function(){
|
||||
jsPsych.pluginAPI.getAudioBuffer(trial.stimuli[play_next_audio.i]).then(function(buffer){
|
||||
if(context !== null) {
|
||||
audio = context.createBufferSource();
|
||||
audio.buffer = buffer;
|
||||
audio.connect(context.destination);
|
||||
} else {
|
||||
audio = buffer;
|
||||
audio.currentTime = 0;
|
||||
}
|
||||
audio.addEventListener('ended', function _audio_ended(){
|
||||
$(display_element).find('.jspsych-audio-sequence-button-response button.highlighted').removeClass('highlighted');
|
||||
setTimeout(play_next_audio, trial.isi);
|
||||
};
|
||||
} else {
|
||||
audio = jsPsych.pluginAPI.getAudioBuffer(trial.stimuli[play_next_audio.i]);
|
||||
audio.currentTime = 0;
|
||||
audio.addEventListener('ended', function(){
|
||||
$(display_element).find('.jspsych-audio-sequence-button-response button.highlighted').removeClass('highlighted');
|
||||
setTimeout(play_next_audio, trial.isi);
|
||||
if(play_next_audio.i<trial.stimuli.length){
|
||||
setTimeout(play_next_audio, trial.isi);
|
||||
} else {
|
||||
setTimeout(play_next_audio, 0);
|
||||
}
|
||||
audio.removeEventListener('ended', _audio_ended);
|
||||
});
|
||||
}
|
||||
|
||||
// Highlight the current button
|
||||
$(display_element).find('#jspsych-audio-sequence-button-response-' + play_next_audio.i +' button').addClass('highlighted');
|
||||
// Highlight the current button
|
||||
$(display_element).find('#jspsych-audio-sequence-button-response-' + play_next_audio.i +' button').addClass('highlighted');
|
||||
|
||||
if(context !== null) {
|
||||
startTime = context.currentTime;
|
||||
source.start(startTime);
|
||||
} else {
|
||||
audio.play();
|
||||
}
|
||||
if(context !== null) {
|
||||
startTime = context.currentTime;
|
||||
audio.start(startTime);
|
||||
} else {
|
||||
audio.play();
|
||||
}
|
||||
|
||||
play_next_audio.i++;
|
||||
play_next_audio.i++;
|
||||
});
|
||||
}
|
||||
|
||||
//display buttons
|
||||
@@ -288,12 +283,11 @@ jsPsych.plugins["audio-sequence-button-response"] = (function() {
|
||||
// stop the audio file if it is playing
|
||||
// remove end event listeners if they exist
|
||||
if(context !== null) {
|
||||
source.stop();
|
||||
source.onended = function() {}
|
||||
audio.stop();
|
||||
} else {
|
||||
audio.pause();
|
||||
audio.removeEventListener('ended', end_trial);
|
||||
}
|
||||
audio.removeEventListener('ended', end_trial);
|
||||
|
||||
// kill any remaining setTimeout handlers
|
||||
jsPsych.pluginAPI.clearAllTimeouts();
|
||||
|
||||
BIN
tests/res/eg-syllables-bi01.wav
Normal file
BIN
tests/res/eg-syllables-bi01.wav
Normal file
Binary file not shown.
BIN
tests/res/eg-syllables-bu01.wav
Normal file
BIN
tests/res/eg-syllables-bu01.wav
Normal file
Binary file not shown.
BIN
tests/res/eg-syllables-di01.wav
Normal file
BIN
tests/res/eg-syllables-di01.wav
Normal file
Binary file not shown.
BIN
tests/res/eg-syllables-du01.wav
Normal file
BIN
tests/res/eg-syllables-du01.wav
Normal file
Binary file not shown.
64
tests/test_jspsych-audio-sequence-button-response.html
Normal file
64
tests/test_jspsych-audio-sequence-button-response.html
Normal file
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Test for jspsych-html-keyboard-response-clickable</title>
|
||||
<script src="https://cdn.jsdelivr.net/gh/jquery/jquery/dist/jquery.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/jspsych/jsPsych@6.3.1/jspsych.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/jspsych/jsPsych@6.3.1/plugins/jspsych-html-button-response.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/gh/jspsych/jsPsych@6.3.1/css/jspsych.css" rel="stylesheet" type="text/css">
|
||||
<script src="../plugins/jspsych-audio-sequence-button-response.js"></script>
|
||||
<style>
|
||||
.jspsych-audio-sequence-button-response button {
|
||||
min-width: 5em;
|
||||
min-height: 4em;
|
||||
}
|
||||
.jspsych-audio-sequence-button-response button.highlighted {
|
||||
background-color: #ffff00 !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function(event) {
|
||||
|
||||
var timeline = [];
|
||||
|
||||
timeline.push({
|
||||
type: 'html-button-response',
|
||||
choices: ['start'],
|
||||
stimulus: ""
|
||||
});
|
||||
|
||||
timeline.push({
|
||||
type: 'audio-sequence-button-response',
|
||||
choices: [' ', ' ', ' '],
|
||||
prompt: '<p>Prompt</p>',
|
||||
stimuli: ['res/eg-syllables-bi01.wav', 'res/eg-syllables-bu01.wav', 'res/eg-syllables-di01.wav'],
|
||||
trial_ends_after_audio: true,
|
||||
on_finish: function(){
|
||||
console.log("Trial is finished.");
|
||||
}
|
||||
});
|
||||
|
||||
timeline.push({
|
||||
type: 'audio-sequence-button-response',
|
||||
choices: [' ', ' ', ' '],
|
||||
prompt: '<p>Prompt</p>',
|
||||
stimuli: ['res/eg-syllables-bi01.wav', 'res/eg-syllables-bu01.wav', 'res/eg-syllables-di01.wav'],
|
||||
trial_ends_after_audio: true,
|
||||
on_finish: function(){
|
||||
console.log("Trial is finished.");
|
||||
}
|
||||
});
|
||||
|
||||
jsPsych.init({
|
||||
timeline: timeline
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user