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 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-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 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 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
|
## 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.
|
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
|
||||||
|
|
||||||
Parameters with a default value of *undefined* must be specified. Other parameters can be left unspecified if the default value is acceptable.
|
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)
|
#### 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
|
```javascript
|
||||||
var trial = {
|
var trial = {
|
||||||
type: 'audio-button-response',
|
type: 'audio-button-response',
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* jspsych-audio-sequence-button-response
|
* jspsych-audio-sequence-button-response for jsPsych v6.3
|
||||||
* Etienne Gaudrain <etienne.gaudrain@cnrs.fr>
|
* Etienne Gaudrain <etienne.gaudrain@cnrs.fr> 2021-10-15
|
||||||
*
|
*
|
||||||
* Plugin for playing a sequence of audio files and getting an HTML button response
|
* Plugin for playing a sequence of audio files and getting an HTML button response
|
||||||
*
|
*
|
||||||
* Based on jspsych-audio-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() {
|
jsPsych.plugins["audio-sequence-button-response"] = (function() {
|
||||||
@@ -103,11 +105,7 @@ jsPsych.plugins["audio-sequence-button-response"] = (function() {
|
|||||||
plugin.trial = function(display_element, trial) {
|
plugin.trial = function(display_element, trial) {
|
||||||
|
|
||||||
var context = jsPsych.pluginAPI.audioContext();
|
var context = jsPsych.pluginAPI.audioContext();
|
||||||
if(context !== null) {
|
var audio;
|
||||||
var source;
|
|
||||||
} else {
|
|
||||||
var audio;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(trial.visual_feedback===true && trial.i_correct===null)
|
if(trial.visual_feedback===true && trial.i_correct===null)
|
||||||
throw "'i_correct' has to be defined if visual feedback is requested.";
|
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;
|
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?
|
// Is it the last stimulus, do we need to end trial?
|
||||||
if(play_next_audio.i >= trial.stimuli.length) {
|
if(play_next_audio.i >= trial.stimuli.length) {
|
||||||
$(display_element).find(".jspsych-audio-sequence-button-response button").removeClass("disabled").prop('disabled', false);
|
$(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
|
// Prepare the next sound to play
|
||||||
if(context !== null) {
|
jsPsych.pluginAPI.getAudioBuffer(trial.stimuli[play_next_audio.i]).then(function(buffer){
|
||||||
source = context.createBufferSource();
|
if(context !== null) {
|
||||||
source.buffer = jsPsych.pluginAPI.getAudioBuffer(trial.stimuli[play_next_audio.i]);
|
audio = context.createBufferSource();
|
||||||
source.connect(context.destination);
|
audio.buffer = buffer;
|
||||||
source.onended = function(){
|
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');
|
$(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 {
|
} else {
|
||||||
audio = jsPsych.pluginAPI.getAudioBuffer(trial.stimuli[play_next_audio.i]);
|
setTimeout(play_next_audio, 0);
|
||||||
audio.currentTime = 0;
|
}
|
||||||
audio.addEventListener('ended', function(){
|
audio.removeEventListener('ended', _audio_ended);
|
||||||
$(display_element).find('.jspsych-audio-sequence-button-response button.highlighted').removeClass('highlighted');
|
|
||||||
setTimeout(play_next_audio, trial.isi);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Highlight the current button
|
// Highlight the current button
|
||||||
$(display_element).find('#jspsych-audio-sequence-button-response-' + play_next_audio.i +' button').addClass('highlighted');
|
$(display_element).find('#jspsych-audio-sequence-button-response-' + play_next_audio.i +' button').addClass('highlighted');
|
||||||
|
|
||||||
if(context !== null) {
|
if(context !== null) {
|
||||||
startTime = context.currentTime;
|
startTime = context.currentTime;
|
||||||
source.start(startTime);
|
audio.start(startTime);
|
||||||
} else {
|
} else {
|
||||||
audio.play();
|
audio.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
play_next_audio.i++;
|
play_next_audio.i++;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//display buttons
|
//display buttons
|
||||||
@@ -288,12 +283,11 @@ jsPsych.plugins["audio-sequence-button-response"] = (function() {
|
|||||||
// stop the audio file if it is playing
|
// stop the audio file if it is playing
|
||||||
// remove end event listeners if they exist
|
// remove end event listeners if they exist
|
||||||
if(context !== null) {
|
if(context !== null) {
|
||||||
source.stop();
|
audio.stop();
|
||||||
source.onended = function() {}
|
|
||||||
} else {
|
} else {
|
||||||
audio.pause();
|
audio.pause();
|
||||||
audio.removeEventListener('ended', end_trial);
|
|
||||||
}
|
}
|
||||||
|
audio.removeEventListener('ended', end_trial);
|
||||||
|
|
||||||
// kill any remaining setTimeout handlers
|
// kill any remaining setTimeout handlers
|
||||||
jsPsych.pluginAPI.clearAllTimeouts();
|
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