@jspsych/plugin-audio-keyboard-response 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.js","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nconst info = <const>{\n name: \"audio-keyboard-response\",\n parameters: {\n /** The audio file to be played. */\n stimulus: {\n type: ParameterType.AUDIO,\n pretty_name: \"Stimulus\",\n default: undefined,\n },\n /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */\n choices: {\n type: ParameterType.KEYS,\n pretty_name: \"Choices\",\n default: \"ALL_KEYS\",\n },\n /** Any content here will be displayed below the stimulus. */\n prompt: {\n type: ParameterType.HTML_STRING,\n pretty_name: \"Prompt\",\n default: null,\n },\n /** The maximum duration to wait for a response. */\n trial_duration: {\n type: ParameterType.INT,\n pretty_name: \"Trial duration\",\n default: null,\n },\n /** If true, the trial will end when user makes a response. */\n response_ends_trial: {\n type: ParameterType.BOOL,\n pretty_name: \"Response ends trial\",\n default: true,\n },\n /** If true, then the trial will end as soon as the audio file finishes playing. */\n trial_ends_after_audio: {\n type: ParameterType.BOOL,\n pretty_name: \"Trial ends after audio\",\n default: false,\n },\n /** If true, then responses are allowed while the audio is playing. If false, then the audio must finish playing before a response is accepted. */\n response_allowed_while_playing: {\n type: ParameterType.BOOL,\n pretty_name: \"Response allowed while playing\",\n default: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n * **audio-keyboard-response**\n *\n * jsPsych plugin for playing an audio file and getting a keyboard response\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/ audio-keyboard-response plugin documentation on jspsych.org}\n */\nclass AudioKeyboardResponsePlugin implements JsPsychPlugin<Info> {\n static info = info;\n private audio;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>, on_load: () => void) {\n // hold the .resolve() function from the Promise that ends the trial\n let trial_complete;\n\n // setup stimulus\n var context = this.jsPsych.pluginAPI.audioContext();\n\n // store response\n var response = {\n rt: null,\n key: null,\n };\n\n // record webaudio context start time\n var startTime;\n\n // load audio file\n this.jsPsych.pluginAPI\n .getAudioBuffer(trial.stimulus)\n .then((buffer) => {\n if (context !== null) {\n this.audio = context.createBufferSource();\n this.audio.buffer = buffer;\n this.audio.connect(context.destination);\n } else {\n this.audio = buffer;\n this.audio.currentTime = 0;\n }\n setupTrial();\n })\n .catch((err) => {\n console.error(\n `Failed to load audio file \"${trial.stimulus}\". Try checking the file path. We recommend using the preload plugin to load audio files.`\n );\n console.error(err);\n });\n\n const setupTrial = () => {\n // set up end event if trial needs it\n if (trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", end_trial);\n }\n\n // show prompt if there is one\n if (trial.prompt !== null) {\n display_element.innerHTML = trial.prompt;\n }\n\n // start audio\n if (context !== null) {\n startTime = context.currentTime;\n this.audio.start(startTime);\n } else {\n this.audio.play();\n }\n\n // start keyboard listener when trial starts or sound ends\n if (trial.response_allowed_while_playing) {\n setup_keyboard_listener();\n } else if (!trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", setup_keyboard_listener);\n }\n\n // end trial if time limit is set\n if (trial.trial_duration !== null) {\n this.jsPsych.pluginAPI.setTimeout(() => {\n end_trial();\n }, trial.trial_duration);\n }\n\n on_load();\n };\n\n // function to end trial when it is time\n const end_trial = () => {\n // kill any remaining setTimeout handlers\n this.jsPsych.pluginAPI.clearAllTimeouts();\n\n // stop the audio file if it is playing\n // remove end event listeners if they exist\n if (context !== null) {\n this.audio.stop();\n } else {\n this.audio.pause();\n }\n\n this.audio.removeEventListener(\"ended\", end_trial);\n this.audio.removeEventListener(\"ended\", setup_keyboard_listener);\n\n // kill keyboard listeners\n this.jsPsych.pluginAPI.cancelAllKeyboardResponses();\n\n // gather the data to store for the trial\n var trial_data = {\n rt: response.rt,\n stimulus: trial.stimulus,\n response: response.key,\n };\n\n // clear the display\n display_element.innerHTML = \"\";\n\n // move on to the next trial\n this.jsPsych.finishTrial(trial_data);\n\n trial_complete();\n };\n\n // function to handle responses by the subject\n function after_response(info) {\n // only record the first response\n if (response.key == null) {\n response = info;\n }\n\n if (trial.response_ends_trial) {\n end_trial();\n }\n }\n\n const setup_keyboard_listener = () => {\n // start the response listener\n if (context !== null) {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"audio\",\n persist: false,\n allow_held_key: false,\n audio_context: context,\n audio_context_start_time: startTime,\n });\n } else {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"performance\",\n persist: false,\n allow_held_key: false,\n });\n }\n };\n\n return new Promise((resolve) => {\n trial_complete = resolve;\n });\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n const respond = () => {\n if (data.rt !== null) {\n this.jsPsych.pluginAPI.pressKey(data.response, data.rt);\n }\n };\n\n this.trial(display_element, trial, () => {\n load_callback();\n if (!trial.response_allowed_while_playing) {\n this.audio.addEventListener(\"ended\", respond);\n } else {\n respond();\n }\n });\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const default_data = {\n stimulus: trial.stimulus,\n rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),\n response: this.jsPsych.pluginAPI.getValidKey(trial.choices),\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n}\n\nexport default AudioKeyboardResponsePlugin;\n"],"names":["ParameterType"],"mappings":"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"}
1
+ {"version":3,"file":"index.browser.js","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nconst info = <const>{\n name: \"audio-keyboard-response\",\n parameters: {\n /** The audio file to be played. */\n stimulus: {\n type: ParameterType.AUDIO,\n pretty_name: \"Stimulus\",\n default: undefined,\n },\n /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */\n choices: {\n type: ParameterType.KEYS,\n pretty_name: \"Choices\",\n default: \"ALL_KEYS\",\n },\n /** Any content here will be displayed below the stimulus. */\n prompt: {\n type: ParameterType.HTML_STRING,\n pretty_name: \"Prompt\",\n default: null,\n },\n /** The maximum duration to wait for a response. */\n trial_duration: {\n type: ParameterType.INT,\n pretty_name: \"Trial duration\",\n default: null,\n },\n /** If true, the trial will end when user makes a response. */\n response_ends_trial: {\n type: ParameterType.BOOL,\n pretty_name: \"Response ends trial\",\n default: true,\n },\n /** If true, then the trial will end as soon as the audio file finishes playing. */\n trial_ends_after_audio: {\n type: ParameterType.BOOL,\n pretty_name: \"Trial ends after audio\",\n default: false,\n },\n /** If true, then responses are allowed while the audio is playing. If false, then the audio must finish playing before a response is accepted. */\n response_allowed_while_playing: {\n type: ParameterType.BOOL,\n pretty_name: \"Response allowed while playing\",\n default: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n * **audio-keyboard-response**\n *\n * jsPsych plugin for playing an audio file and getting a keyboard response\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/ audio-keyboard-response plugin documentation on jspsych.org}\n */\nclass AudioKeyboardResponsePlugin implements JsPsychPlugin<Info> {\n static info = info;\n private audio;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>, on_load: () => void) {\n // hold the .resolve() function from the Promise that ends the trial\n let trial_complete;\n\n // setup stimulus\n var context = this.jsPsych.pluginAPI.audioContext();\n\n // store response\n var response = {\n rt: null,\n key: null,\n };\n\n // record webaudio context start time\n var startTime;\n\n // load audio file\n this.jsPsych.pluginAPI\n .getAudioBuffer(trial.stimulus)\n .then((buffer) => {\n if (context !== null) {\n this.audio = context.createBufferSource();\n this.audio.buffer = buffer;\n this.audio.connect(context.destination);\n } else {\n this.audio = buffer;\n this.audio.currentTime = 0;\n }\n setupTrial();\n })\n .catch((err) => {\n console.error(\n `Failed to load audio file \"${trial.stimulus}\". Try checking the file path. We recommend using the preload plugin to load audio files.`\n );\n console.error(err);\n });\n\n const setupTrial = () => {\n // set up end event if trial needs it\n if (trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", end_trial);\n }\n\n // show prompt if there is one\n if (trial.prompt !== null) {\n display_element.innerHTML = trial.prompt;\n }\n\n // start audio\n if (context !== null) {\n startTime = context.currentTime;\n this.audio.start(startTime);\n } else {\n this.audio.play();\n }\n\n // start keyboard listener when trial starts or sound ends\n if (trial.response_allowed_while_playing) {\n setup_keyboard_listener();\n } else if (!trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", setup_keyboard_listener);\n }\n\n // end trial if time limit is set\n if (trial.trial_duration !== null) {\n this.jsPsych.pluginAPI.setTimeout(() => {\n end_trial();\n }, trial.trial_duration);\n }\n\n on_load();\n };\n\n // function to end trial when it is time\n const end_trial = () => {\n // kill any remaining setTimeout handlers\n this.jsPsych.pluginAPI.clearAllTimeouts();\n\n // stop the audio file if it is playing\n // remove end event listeners if they exist\n if (context !== null) {\n this.audio.stop();\n } else {\n this.audio.pause();\n }\n\n this.audio.removeEventListener(\"ended\", end_trial);\n this.audio.removeEventListener(\"ended\", setup_keyboard_listener);\n\n // kill keyboard listeners\n this.jsPsych.pluginAPI.cancelAllKeyboardResponses();\n\n // gather the data to store for the trial\n var trial_data = {\n rt: response.rt,\n stimulus: trial.stimulus,\n response: response.key,\n };\n\n // clear the display\n display_element.innerHTML = \"\";\n\n // move on to the next trial\n this.jsPsych.finishTrial(trial_data);\n\n trial_complete();\n };\n\n // function to handle responses by the subject\n function after_response(info) {\n // only record the first response\n if (response.key == null) {\n response = info;\n }\n\n if (trial.response_ends_trial) {\n end_trial();\n }\n }\n\n const setup_keyboard_listener = () => {\n // start the response listener\n if (context !== null) {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"audio\",\n persist: false,\n allow_held_key: false,\n audio_context: context,\n audio_context_start_time: startTime,\n });\n } else {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"performance\",\n persist: false,\n allow_held_key: false,\n });\n }\n };\n\n return new Promise((resolve) => {\n trial_complete = resolve;\n });\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n const respond = () => {\n if (data.rt !== null) {\n this.jsPsych.pluginAPI.pressKey(data.response, data.rt);\n }\n };\n\n this.trial(display_element, trial, () => {\n load_callback();\n if (!trial.response_allowed_while_playing) {\n this.audio.addEventListener(\"ended\", respond);\n } else {\n respond();\n }\n });\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const default_data = {\n stimulus: trial.stimulus,\n rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),\n response: this.jsPsych.pluginAPI.getValidKey(trial.choices),\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n}\n\nexport default AudioKeyboardResponsePlugin;\n"],"names":["ParameterType"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var jsPsychAudioKeyboardResponse=function(e){"use strict";const t={name:"audio-keyboard-response",parameters:{stimulus:{type:e.ParameterType.AUDIO,pretty_name:"Stimulus",default:void 0},choices:{type:e.ParameterType.KEYS,pretty_name:"Choices",default:"ALL_KEYS"},prompt:{type:e.ParameterType.HTML_STRING,pretty_name:"Prompt",default:null},trial_duration:{type:e.ParameterType.INT,pretty_name:"Trial duration",default:null},response_ends_trial:{type:e.ParameterType.BOOL,pretty_name:"Response ends trial",default:!0},trial_ends_after_audio:{type:e.ParameterType.BOOL,pretty_name:"Trial ends after audio",default:!1},response_allowed_while_playing:{type:e.ParameterType.BOOL,pretty_name:"Response allowed while playing",default:!0}}};class s{constructor(e){this.jsPsych=e}trial(e,t,s){let i;var a,n=this.jsPsych.pluginAPI.audioContext(),l={rt:null,key:null};this.jsPsych.pluginAPI.getAudioBuffer(t.stimulus).then((e=>{null!==n?(this.audio=n.createBufferSource(),this.audio.buffer=e,this.audio.connect(n.destination)):(this.audio=e,this.audio.currentTime=0),r()})).catch((e=>{console.error(`Failed to load audio file "${t.stimulus}". Try checking the file path. We recommend using the preload plugin to load audio files.`),console.error(e)}));const r=()=>{t.trial_ends_after_audio&&this.audio.addEventListener("ended",o),null!==t.prompt&&(e.innerHTML=t.prompt),null!==n?(a=n.currentTime,this.audio.start(a)):this.audio.play(),t.response_allowed_while_playing?d():t.trial_ends_after_audio||this.audio.addEventListener("ended",d),null!==t.trial_duration&&this.jsPsych.pluginAPI.setTimeout((()=>{o()}),t.trial_duration),s()},o=()=>{this.jsPsych.pluginAPI.clearAllTimeouts(),null!==n?this.audio.stop():this.audio.pause(),this.audio.removeEventListener("ended",o),this.audio.removeEventListener("ended",d),this.jsPsych.pluginAPI.cancelAllKeyboardResponses();var s={rt:l.rt,stimulus:t.stimulus,response:l.key};e.innerHTML="",this.jsPsych.finishTrial(s),i()};function u(e){null==l.key&&(l=e),t.response_ends_trial&&o()}const d=()=>{null!==n?this.jsPsych.pluginAPI.getKeyboardResponse({callback_function:u,valid_responses:t.choices,rt_method:"audio",persist:!1,allow_held_key:!1,audio_context:n,audio_context_start_time:a}):this.jsPsych.pluginAPI.getKeyboardResponse({callback_function:u,valid_responses:t.choices,rt_method:"performance",persist:!1,allow_held_key:!1})};return new Promise((e=>{i=e}))}simulate(e,t,s,i){"data-only"==t&&(i(),this.simulate_data_only(e,s)),"visual"==t&&this.simulate_visual(e,s,i)}simulate_data_only(e,t){const s=this.create_simulation_data(e,t);this.jsPsych.finishTrial(s)}simulate_visual(e,t,s){const i=this.create_simulation_data(e,t),a=this.jsPsych.getDisplayElement(),n=()=>{null!==i.rt&&this.jsPsych.pluginAPI.pressKey(i.response,i.rt)};this.trial(a,e,(()=>{s(),e.response_allowed_while_playing?n():this.audio.addEventListener("ended",n)}))}create_simulation_data(e,t){const s={stimulus:e.stimulus,rt:this.jsPsych.randomization.sampleExGaussian(500,50,1/150,!0),response:this.jsPsych.pluginAPI.getValidKey(e.choices)},i=this.jsPsych.pluginAPI.mergeSimulationData(s,t);return this.jsPsych.pluginAPI.ensureSimulationDataConsistency(e,i),i}}return s.info=t,s}(jsPsychModule);
1
+ var jsPsychAudioKeyboardResponse=function(e){"use strict";function t(e,t){for(var a=0;a<t.length;a++){var i=t[a];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}var a={name:"audio-keyboard-response",parameters:{stimulus:{type:e.ParameterType.AUDIO,pretty_name:"Stimulus",default:void 0},choices:{type:e.ParameterType.KEYS,pretty_name:"Choices",default:"ALL_KEYS"},prompt:{type:e.ParameterType.HTML_STRING,pretty_name:"Prompt",default:null},trial_duration:{type:e.ParameterType.INT,pretty_name:"Trial duration",default:null},response_ends_trial:{type:e.ParameterType.BOOL,pretty_name:"Response ends trial",default:!0},trial_ends_after_audio:{type:e.ParameterType.BOOL,pretty_name:"Trial ends after audio",default:!1},response_allowed_while_playing:{type:e.ParameterType.BOOL,pretty_name:"Response allowed while playing",default:!0}}},i=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.jsPsych=t}var a,i,n;return a=e,i=[{key:"trial",value:function(e,t,a){var i,n,s=this,r=this.jsPsych.pluginAPI.audioContext(),l={rt:null,key:null};this.jsPsych.pluginAPI.getAudioBuffer(t.stimulus).then((function(e){null!==r?(s.audio=r.createBufferSource(),s.audio.buffer=e,s.audio.connect(r.destination)):(s.audio=e,s.audio.currentTime=0),o()})).catch((function(e){console.error('Failed to load audio file "'.concat(t.stimulus,'". Try checking the file path. We recommend using the preload plugin to load audio files.')),console.error(e)}));var o=function(){t.trial_ends_after_audio&&s.audio.addEventListener("ended",u),null!==t.prompt&&(e.innerHTML=t.prompt),null!==r?(n=r.currentTime,s.audio.start(n)):s.audio.play(),t.response_allowed_while_playing?c():t.trial_ends_after_audio||s.audio.addEventListener("ended",c),null!==t.trial_duration&&s.jsPsych.pluginAPI.setTimeout((function(){u()}),t.trial_duration),a()},u=function a(){s.jsPsych.pluginAPI.clearAllTimeouts(),null!==r?s.audio.stop():s.audio.pause(),s.audio.removeEventListener("ended",a),s.audio.removeEventListener("ended",c),s.jsPsych.pluginAPI.cancelAllKeyboardResponses();var n={rt:l.rt,stimulus:t.stimulus,response:l.key};e.innerHTML="",s.jsPsych.finishTrial(n),i()};function d(e){null==l.key&&(l=e),t.response_ends_trial&&u()}var c=function(){null!==r?s.jsPsych.pluginAPI.getKeyboardResponse({callback_function:d,valid_responses:t.choices,rt_method:"audio",persist:!1,allow_held_key:!1,audio_context:r,audio_context_start_time:n}):s.jsPsych.pluginAPI.getKeyboardResponse({callback_function:d,valid_responses:t.choices,rt_method:"performance",persist:!1,allow_held_key:!1})};return new Promise((function(e){i=e}))}},{key:"simulate",value:function(e,t,a,i){"data-only"==t&&(i(),this.simulate_data_only(e,a)),"visual"==t&&this.simulate_visual(e,a,i)}},{key:"simulate_data_only",value:function(e,t){var a=this.create_simulation_data(e,t);this.jsPsych.finishTrial(a)}},{key:"simulate_visual",value:function(e,t,a){var i=this,n=this.create_simulation_data(e,t),s=this.jsPsych.getDisplayElement(),r=function(){null!==n.rt&&i.jsPsych.pluginAPI.pressKey(n.response,n.rt)};this.trial(s,e,(function(){a(),e.response_allowed_while_playing?r():i.audio.addEventListener("ended",r)}))}},{key:"create_simulation_data",value:function(e,t){var a={stimulus:e.stimulus,rt:this.jsPsych.randomization.sampleExGaussian(500,50,1/150,!0),response:this.jsPsych.pluginAPI.getValidKey(e.choices)},i=this.jsPsych.pluginAPI.mergeSimulationData(a,t);return this.jsPsych.pluginAPI.ensureSimulationDataConsistency(e,i),i}}],i&&t(a.prototype,i),n&&t(a,n),Object.defineProperty(a,"prototype",{writable:!1}),e}();return i.info=a,i}(jsPsychModule);
2
2
  //# sourceMappingURL=index.browser.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.min.js","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nconst info = <const>{\n name: \"audio-keyboard-response\",\n parameters: {\n /** The audio file to be played. */\n stimulus: {\n type: ParameterType.AUDIO,\n pretty_name: \"Stimulus\",\n default: undefined,\n },\n /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */\n choices: {\n type: ParameterType.KEYS,\n pretty_name: \"Choices\",\n default: \"ALL_KEYS\",\n },\n /** Any content here will be displayed below the stimulus. */\n prompt: {\n type: ParameterType.HTML_STRING,\n pretty_name: \"Prompt\",\n default: null,\n },\n /** The maximum duration to wait for a response. */\n trial_duration: {\n type: ParameterType.INT,\n pretty_name: \"Trial duration\",\n default: null,\n },\n /** If true, the trial will end when user makes a response. */\n response_ends_trial: {\n type: ParameterType.BOOL,\n pretty_name: \"Response ends trial\",\n default: true,\n },\n /** If true, then the trial will end as soon as the audio file finishes playing. */\n trial_ends_after_audio: {\n type: ParameterType.BOOL,\n pretty_name: \"Trial ends after audio\",\n default: false,\n },\n /** If true, then responses are allowed while the audio is playing. If false, then the audio must finish playing before a response is accepted. */\n response_allowed_while_playing: {\n type: ParameterType.BOOL,\n pretty_name: \"Response allowed while playing\",\n default: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n * **audio-keyboard-response**\n *\n * jsPsych plugin for playing an audio file and getting a keyboard response\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/ audio-keyboard-response plugin documentation on jspsych.org}\n */\nclass AudioKeyboardResponsePlugin implements JsPsychPlugin<Info> {\n static info = info;\n private audio;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>, on_load: () => void) {\n // hold the .resolve() function from the Promise that ends the trial\n let trial_complete;\n\n // setup stimulus\n var context = this.jsPsych.pluginAPI.audioContext();\n\n // store response\n var response = {\n rt: null,\n key: null,\n };\n\n // record webaudio context start time\n var startTime;\n\n // load audio file\n this.jsPsych.pluginAPI\n .getAudioBuffer(trial.stimulus)\n .then((buffer) => {\n if (context !== null) {\n this.audio = context.createBufferSource();\n this.audio.buffer = buffer;\n this.audio.connect(context.destination);\n } else {\n this.audio = buffer;\n this.audio.currentTime = 0;\n }\n setupTrial();\n })\n .catch((err) => {\n console.error(\n `Failed to load audio file \"${trial.stimulus}\". Try checking the file path. We recommend using the preload plugin to load audio files.`\n );\n console.error(err);\n });\n\n const setupTrial = () => {\n // set up end event if trial needs it\n if (trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", end_trial);\n }\n\n // show prompt if there is one\n if (trial.prompt !== null) {\n display_element.innerHTML = trial.prompt;\n }\n\n // start audio\n if (context !== null) {\n startTime = context.currentTime;\n this.audio.start(startTime);\n } else {\n this.audio.play();\n }\n\n // start keyboard listener when trial starts or sound ends\n if (trial.response_allowed_while_playing) {\n setup_keyboard_listener();\n } else if (!trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", setup_keyboard_listener);\n }\n\n // end trial if time limit is set\n if (trial.trial_duration !== null) {\n this.jsPsych.pluginAPI.setTimeout(() => {\n end_trial();\n }, trial.trial_duration);\n }\n\n on_load();\n };\n\n // function to end trial when it is time\n const end_trial = () => {\n // kill any remaining setTimeout handlers\n this.jsPsych.pluginAPI.clearAllTimeouts();\n\n // stop the audio file if it is playing\n // remove end event listeners if they exist\n if (context !== null) {\n this.audio.stop();\n } else {\n this.audio.pause();\n }\n\n this.audio.removeEventListener(\"ended\", end_trial);\n this.audio.removeEventListener(\"ended\", setup_keyboard_listener);\n\n // kill keyboard listeners\n this.jsPsych.pluginAPI.cancelAllKeyboardResponses();\n\n // gather the data to store for the trial\n var trial_data = {\n rt: response.rt,\n stimulus: trial.stimulus,\n response: response.key,\n };\n\n // clear the display\n display_element.innerHTML = \"\";\n\n // move on to the next trial\n this.jsPsych.finishTrial(trial_data);\n\n trial_complete();\n };\n\n // function to handle responses by the subject\n function after_response(info) {\n // only record the first response\n if (response.key == null) {\n response = info;\n }\n\n if (trial.response_ends_trial) {\n end_trial();\n }\n }\n\n const setup_keyboard_listener = () => {\n // start the response listener\n if (context !== null) {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"audio\",\n persist: false,\n allow_held_key: false,\n audio_context: context,\n audio_context_start_time: startTime,\n });\n } else {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"performance\",\n persist: false,\n allow_held_key: false,\n });\n }\n };\n\n return new Promise((resolve) => {\n trial_complete = resolve;\n });\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n const respond = () => {\n if (data.rt !== null) {\n this.jsPsych.pluginAPI.pressKey(data.response, data.rt);\n }\n };\n\n this.trial(display_element, trial, () => {\n load_callback();\n if (!trial.response_allowed_while_playing) {\n this.audio.addEventListener(\"ended\", respond);\n } else {\n respond();\n }\n });\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const default_data = {\n stimulus: trial.stimulus,\n rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),\n response: this.jsPsych.pluginAPI.getValidKey(trial.choices),\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n}\n\nexport default AudioKeyboardResponsePlugin;\n"],"names":["info","name","parameters","stimulus","type","ParameterType","AUDIO","pretty_name","default","undefined","choices","KEYS","prompt","HTML_STRING","trial_duration","INT","response_ends_trial","BOOL","trial_ends_after_audio","response_allowed_while_playing","AudioKeyboardResponsePlugin","constructor","jsPsych","this","trial","display_element","on_load","trial_complete","startTime","context","pluginAPI","audioContext","response","rt","key","getAudioBuffer","then","buffer","audio","createBufferSource","connect","destination","currentTime","setupTrial","catch","err","console","error","addEventListener","end_trial","innerHTML","start","play","setup_keyboard_listener","setTimeout","clearAllTimeouts","stop","pause","removeEventListener","cancelAllKeyboardResponses","trial_data","finishTrial","after_response","getKeyboardResponse","callback_function","valid_responses","rt_method","persist","allow_held_key","audio_context","audio_context_start_time","Promise","resolve","simulate","simulation_mode","simulation_options","load_callback","simulate_data_only","simulate_visual","data","create_simulation_data","getDisplayElement","respond","pressKey","default_data","randomization","sampleExGaussian","getValidKey","mergeSimulationData","ensureSimulationDataConsistency"],"mappings":"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"}
1
+ {"version":3,"file":"index.browser.min.js","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nconst info = <const>{\n name: \"audio-keyboard-response\",\n parameters: {\n /** The audio file to be played. */\n stimulus: {\n type: ParameterType.AUDIO,\n pretty_name: \"Stimulus\",\n default: undefined,\n },\n /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */\n choices: {\n type: ParameterType.KEYS,\n pretty_name: \"Choices\",\n default: \"ALL_KEYS\",\n },\n /** Any content here will be displayed below the stimulus. */\n prompt: {\n type: ParameterType.HTML_STRING,\n pretty_name: \"Prompt\",\n default: null,\n },\n /** The maximum duration to wait for a response. */\n trial_duration: {\n type: ParameterType.INT,\n pretty_name: \"Trial duration\",\n default: null,\n },\n /** If true, the trial will end when user makes a response. */\n response_ends_trial: {\n type: ParameterType.BOOL,\n pretty_name: \"Response ends trial\",\n default: true,\n },\n /** If true, then the trial will end as soon as the audio file finishes playing. */\n trial_ends_after_audio: {\n type: ParameterType.BOOL,\n pretty_name: \"Trial ends after audio\",\n default: false,\n },\n /** If true, then responses are allowed while the audio is playing. If false, then the audio must finish playing before a response is accepted. */\n response_allowed_while_playing: {\n type: ParameterType.BOOL,\n pretty_name: \"Response allowed while playing\",\n default: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n * **audio-keyboard-response**\n *\n * jsPsych plugin for playing an audio file and getting a keyboard response\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/ audio-keyboard-response plugin documentation on jspsych.org}\n */\nclass AudioKeyboardResponsePlugin implements JsPsychPlugin<Info> {\n static info = info;\n private audio;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>, on_load: () => void) {\n // hold the .resolve() function from the Promise that ends the trial\n let trial_complete;\n\n // setup stimulus\n var context = this.jsPsych.pluginAPI.audioContext();\n\n // store response\n var response = {\n rt: null,\n key: null,\n };\n\n // record webaudio context start time\n var startTime;\n\n // load audio file\n this.jsPsych.pluginAPI\n .getAudioBuffer(trial.stimulus)\n .then((buffer) => {\n if (context !== null) {\n this.audio = context.createBufferSource();\n this.audio.buffer = buffer;\n this.audio.connect(context.destination);\n } else {\n this.audio = buffer;\n this.audio.currentTime = 0;\n }\n setupTrial();\n })\n .catch((err) => {\n console.error(\n `Failed to load audio file \"${trial.stimulus}\". Try checking the file path. We recommend using the preload plugin to load audio files.`\n );\n console.error(err);\n });\n\n const setupTrial = () => {\n // set up end event if trial needs it\n if (trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", end_trial);\n }\n\n // show prompt if there is one\n if (trial.prompt !== null) {\n display_element.innerHTML = trial.prompt;\n }\n\n // start audio\n if (context !== null) {\n startTime = context.currentTime;\n this.audio.start(startTime);\n } else {\n this.audio.play();\n }\n\n // start keyboard listener when trial starts or sound ends\n if (trial.response_allowed_while_playing) {\n setup_keyboard_listener();\n } else if (!trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", setup_keyboard_listener);\n }\n\n // end trial if time limit is set\n if (trial.trial_duration !== null) {\n this.jsPsych.pluginAPI.setTimeout(() => {\n end_trial();\n }, trial.trial_duration);\n }\n\n on_load();\n };\n\n // function to end trial when it is time\n const end_trial = () => {\n // kill any remaining setTimeout handlers\n this.jsPsych.pluginAPI.clearAllTimeouts();\n\n // stop the audio file if it is playing\n // remove end event listeners if they exist\n if (context !== null) {\n this.audio.stop();\n } else {\n this.audio.pause();\n }\n\n this.audio.removeEventListener(\"ended\", end_trial);\n this.audio.removeEventListener(\"ended\", setup_keyboard_listener);\n\n // kill keyboard listeners\n this.jsPsych.pluginAPI.cancelAllKeyboardResponses();\n\n // gather the data to store for the trial\n var trial_data = {\n rt: response.rt,\n stimulus: trial.stimulus,\n response: response.key,\n };\n\n // clear the display\n display_element.innerHTML = \"\";\n\n // move on to the next trial\n this.jsPsych.finishTrial(trial_data);\n\n trial_complete();\n };\n\n // function to handle responses by the subject\n function after_response(info) {\n // only record the first response\n if (response.key == null) {\n response = info;\n }\n\n if (trial.response_ends_trial) {\n end_trial();\n }\n }\n\n const setup_keyboard_listener = () => {\n // start the response listener\n if (context !== null) {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"audio\",\n persist: false,\n allow_held_key: false,\n audio_context: context,\n audio_context_start_time: startTime,\n });\n } else {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"performance\",\n persist: false,\n allow_held_key: false,\n });\n }\n };\n\n return new Promise((resolve) => {\n trial_complete = resolve;\n });\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n const respond = () => {\n if (data.rt !== null) {\n this.jsPsych.pluginAPI.pressKey(data.response, data.rt);\n }\n };\n\n this.trial(display_element, trial, () => {\n load_callback();\n if (!trial.response_allowed_while_playing) {\n this.audio.addEventListener(\"ended\", respond);\n } else {\n respond();\n }\n });\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const default_data = {\n stimulus: trial.stimulus,\n rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),\n response: this.jsPsych.pluginAPI.getValidKey(trial.choices),\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n}\n\nexport default AudioKeyboardResponsePlugin;\n"],"names":["info","name","parameters","stimulus","type","ParameterType","AUDIO","pretty_name","default","undefined","choices","KEYS","prompt","HTML_STRING","trial_duration","INT","response_ends_trial","BOOL","trial_ends_after_audio","response_allowed_while_playing","AudioKeyboardResponsePlugin","jsPsych","_classCallCheck","this","value","display_element","trial","on_load","trial_complete","startTime","_this","context","pluginAPI","audioContext","response","rt","key","getAudioBuffer","then","buffer","audio","createBufferSource","connect","destination","currentTime","setupTrial","err","console","error","addEventListener","end_trial","innerHTML","start","play","setup_keyboard_listener","setTimeout","clearAllTimeouts","stop","pause","removeEventListener","cancelAllKeyboardResponses","trial_data","finishTrial","after_response","getKeyboardResponse","callback_function","valid_responses","rt_method","persist","allow_held_key","audio_context","audio_context_start_time","Promise","resolve","simulation_mode","simulation_options","load_callback","simulate_data_only","simulate_visual","data","create_simulation_data","_this2","getDisplayElement","respond","pressKey","default_data","randomization","sampleExGaussian","getValidKey","mergeSimulationData","ensureSimulationDataConsistency"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nconst info = <const>{\n name: \"audio-keyboard-response\",\n parameters: {\n /** The audio file to be played. */\n stimulus: {\n type: ParameterType.AUDIO,\n pretty_name: \"Stimulus\",\n default: undefined,\n },\n /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */\n choices: {\n type: ParameterType.KEYS,\n pretty_name: \"Choices\",\n default: \"ALL_KEYS\",\n },\n /** Any content here will be displayed below the stimulus. */\n prompt: {\n type: ParameterType.HTML_STRING,\n pretty_name: \"Prompt\",\n default: null,\n },\n /** The maximum duration to wait for a response. */\n trial_duration: {\n type: ParameterType.INT,\n pretty_name: \"Trial duration\",\n default: null,\n },\n /** If true, the trial will end when user makes a response. */\n response_ends_trial: {\n type: ParameterType.BOOL,\n pretty_name: \"Response ends trial\",\n default: true,\n },\n /** If true, then the trial will end as soon as the audio file finishes playing. */\n trial_ends_after_audio: {\n type: ParameterType.BOOL,\n pretty_name: \"Trial ends after audio\",\n default: false,\n },\n /** If true, then responses are allowed while the audio is playing. If false, then the audio must finish playing before a response is accepted. */\n response_allowed_while_playing: {\n type: ParameterType.BOOL,\n pretty_name: \"Response allowed while playing\",\n default: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n * **audio-keyboard-response**\n *\n * jsPsych plugin for playing an audio file and getting a keyboard response\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/ audio-keyboard-response plugin documentation on jspsych.org}\n */\nclass AudioKeyboardResponsePlugin implements JsPsychPlugin<Info> {\n static info = info;\n private audio;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>, on_load: () => void) {\n // hold the .resolve() function from the Promise that ends the trial\n let trial_complete;\n\n // setup stimulus\n var context = this.jsPsych.pluginAPI.audioContext();\n\n // store response\n var response = {\n rt: null,\n key: null,\n };\n\n // record webaudio context start time\n var startTime;\n\n // load audio file\n this.jsPsych.pluginAPI\n .getAudioBuffer(trial.stimulus)\n .then((buffer) => {\n if (context !== null) {\n this.audio = context.createBufferSource();\n this.audio.buffer = buffer;\n this.audio.connect(context.destination);\n } else {\n this.audio = buffer;\n this.audio.currentTime = 0;\n }\n setupTrial();\n })\n .catch((err) => {\n console.error(\n `Failed to load audio file \"${trial.stimulus}\". Try checking the file path. We recommend using the preload plugin to load audio files.`\n );\n console.error(err);\n });\n\n const setupTrial = () => {\n // set up end event if trial needs it\n if (trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", end_trial);\n }\n\n // show prompt if there is one\n if (trial.prompt !== null) {\n display_element.innerHTML = trial.prompt;\n }\n\n // start audio\n if (context !== null) {\n startTime = context.currentTime;\n this.audio.start(startTime);\n } else {\n this.audio.play();\n }\n\n // start keyboard listener when trial starts or sound ends\n if (trial.response_allowed_while_playing) {\n setup_keyboard_listener();\n } else if (!trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", setup_keyboard_listener);\n }\n\n // end trial if time limit is set\n if (trial.trial_duration !== null) {\n this.jsPsych.pluginAPI.setTimeout(() => {\n end_trial();\n }, trial.trial_duration);\n }\n\n on_load();\n };\n\n // function to end trial when it is time\n const end_trial = () => {\n // kill any remaining setTimeout handlers\n this.jsPsych.pluginAPI.clearAllTimeouts();\n\n // stop the audio file if it is playing\n // remove end event listeners if they exist\n if (context !== null) {\n this.audio.stop();\n } else {\n this.audio.pause();\n }\n\n this.audio.removeEventListener(\"ended\", end_trial);\n this.audio.removeEventListener(\"ended\", setup_keyboard_listener);\n\n // kill keyboard listeners\n this.jsPsych.pluginAPI.cancelAllKeyboardResponses();\n\n // gather the data to store for the trial\n var trial_data = {\n rt: response.rt,\n stimulus: trial.stimulus,\n response: response.key,\n };\n\n // clear the display\n display_element.innerHTML = \"\";\n\n // move on to the next trial\n this.jsPsych.finishTrial(trial_data);\n\n trial_complete();\n };\n\n // function to handle responses by the subject\n function after_response(info) {\n // only record the first response\n if (response.key == null) {\n response = info;\n }\n\n if (trial.response_ends_trial) {\n end_trial();\n }\n }\n\n const setup_keyboard_listener = () => {\n // start the response listener\n if (context !== null) {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"audio\",\n persist: false,\n allow_held_key: false,\n audio_context: context,\n audio_context_start_time: startTime,\n });\n } else {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"performance\",\n persist: false,\n allow_held_key: false,\n });\n }\n };\n\n return new Promise((resolve) => {\n trial_complete = resolve;\n });\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n const respond = () => {\n if (data.rt !== null) {\n this.jsPsych.pluginAPI.pressKey(data.response, data.rt);\n }\n };\n\n this.trial(display_element, trial, () => {\n load_callback();\n if (!trial.response_allowed_while_playing) {\n this.audio.addEventListener(\"ended\", respond);\n } else {\n respond();\n }\n });\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const default_data = {\n stimulus: trial.stimulus,\n rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),\n response: this.jsPsych.pluginAPI.getValidKey(trial.choices),\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n}\n\nexport default AudioKeyboardResponsePlugin;\n"],"names":["ParameterType"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nconst info = <const>{\n name: \"audio-keyboard-response\",\n parameters: {\n /** The audio file to be played. */\n stimulus: {\n type: ParameterType.AUDIO,\n pretty_name: \"Stimulus\",\n default: undefined,\n },\n /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */\n choices: {\n type: ParameterType.KEYS,\n pretty_name: \"Choices\",\n default: \"ALL_KEYS\",\n },\n /** Any content here will be displayed below the stimulus. */\n prompt: {\n type: ParameterType.HTML_STRING,\n pretty_name: \"Prompt\",\n default: null,\n },\n /** The maximum duration to wait for a response. */\n trial_duration: {\n type: ParameterType.INT,\n pretty_name: \"Trial duration\",\n default: null,\n },\n /** If true, the trial will end when user makes a response. */\n response_ends_trial: {\n type: ParameterType.BOOL,\n pretty_name: \"Response ends trial\",\n default: true,\n },\n /** If true, then the trial will end as soon as the audio file finishes playing. */\n trial_ends_after_audio: {\n type: ParameterType.BOOL,\n pretty_name: \"Trial ends after audio\",\n default: false,\n },\n /** If true, then responses are allowed while the audio is playing. If false, then the audio must finish playing before a response is accepted. */\n response_allowed_while_playing: {\n type: ParameterType.BOOL,\n pretty_name: \"Response allowed while playing\",\n default: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n * **audio-keyboard-response**\n *\n * jsPsych plugin for playing an audio file and getting a keyboard response\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/ audio-keyboard-response plugin documentation on jspsych.org}\n */\nclass AudioKeyboardResponsePlugin implements JsPsychPlugin<Info> {\n static info = info;\n private audio;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>, on_load: () => void) {\n // hold the .resolve() function from the Promise that ends the trial\n let trial_complete;\n\n // setup stimulus\n var context = this.jsPsych.pluginAPI.audioContext();\n\n // store response\n var response = {\n rt: null,\n key: null,\n };\n\n // record webaudio context start time\n var startTime;\n\n // load audio file\n this.jsPsych.pluginAPI\n .getAudioBuffer(trial.stimulus)\n .then((buffer) => {\n if (context !== null) {\n this.audio = context.createBufferSource();\n this.audio.buffer = buffer;\n this.audio.connect(context.destination);\n } else {\n this.audio = buffer;\n this.audio.currentTime = 0;\n }\n setupTrial();\n })\n .catch((err) => {\n console.error(\n `Failed to load audio file \"${trial.stimulus}\". Try checking the file path. We recommend using the preload plugin to load audio files.`\n );\n console.error(err);\n });\n\n const setupTrial = () => {\n // set up end event if trial needs it\n if (trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", end_trial);\n }\n\n // show prompt if there is one\n if (trial.prompt !== null) {\n display_element.innerHTML = trial.prompt;\n }\n\n // start audio\n if (context !== null) {\n startTime = context.currentTime;\n this.audio.start(startTime);\n } else {\n this.audio.play();\n }\n\n // start keyboard listener when trial starts or sound ends\n if (trial.response_allowed_while_playing) {\n setup_keyboard_listener();\n } else if (!trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", setup_keyboard_listener);\n }\n\n // end trial if time limit is set\n if (trial.trial_duration !== null) {\n this.jsPsych.pluginAPI.setTimeout(() => {\n end_trial();\n }, trial.trial_duration);\n }\n\n on_load();\n };\n\n // function to end trial when it is time\n const end_trial = () => {\n // kill any remaining setTimeout handlers\n this.jsPsych.pluginAPI.clearAllTimeouts();\n\n // stop the audio file if it is playing\n // remove end event listeners if they exist\n if (context !== null) {\n this.audio.stop();\n } else {\n this.audio.pause();\n }\n\n this.audio.removeEventListener(\"ended\", end_trial);\n this.audio.removeEventListener(\"ended\", setup_keyboard_listener);\n\n // kill keyboard listeners\n this.jsPsych.pluginAPI.cancelAllKeyboardResponses();\n\n // gather the data to store for the trial\n var trial_data = {\n rt: response.rt,\n stimulus: trial.stimulus,\n response: response.key,\n };\n\n // clear the display\n display_element.innerHTML = \"\";\n\n // move on to the next trial\n this.jsPsych.finishTrial(trial_data);\n\n trial_complete();\n };\n\n // function to handle responses by the subject\n function after_response(info) {\n // only record the first response\n if (response.key == null) {\n response = info;\n }\n\n if (trial.response_ends_trial) {\n end_trial();\n }\n }\n\n const setup_keyboard_listener = () => {\n // start the response listener\n if (context !== null) {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"audio\",\n persist: false,\n allow_held_key: false,\n audio_context: context,\n audio_context_start_time: startTime,\n });\n } else {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"performance\",\n persist: false,\n allow_held_key: false,\n });\n }\n };\n\n return new Promise((resolve) => {\n trial_complete = resolve;\n });\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n const respond = () => {\n if (data.rt !== null) {\n this.jsPsych.pluginAPI.pressKey(data.response, data.rt);\n }\n };\n\n this.trial(display_element, trial, () => {\n load_callback();\n if (!trial.response_allowed_while_playing) {\n this.audio.addEventListener(\"ended\", respond);\n } else {\n respond();\n }\n });\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const default_data = {\n stimulus: trial.stimulus,\n rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),\n response: this.jsPsych.pluginAPI.getValidKey(trial.choices),\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n}\n\nexport default AudioKeyboardResponsePlugin;\n"],"names":["ParameterType"],"mappings":"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"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nconst info = <const>{\n name: \"audio-keyboard-response\",\n parameters: {\n /** The audio file to be played. */\n stimulus: {\n type: ParameterType.AUDIO,\n pretty_name: \"Stimulus\",\n default: undefined,\n },\n /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */\n choices: {\n type: ParameterType.KEYS,\n pretty_name: \"Choices\",\n default: \"ALL_KEYS\",\n },\n /** Any content here will be displayed below the stimulus. */\n prompt: {\n type: ParameterType.HTML_STRING,\n pretty_name: \"Prompt\",\n default: null,\n },\n /** The maximum duration to wait for a response. */\n trial_duration: {\n type: ParameterType.INT,\n pretty_name: \"Trial duration\",\n default: null,\n },\n /** If true, the trial will end when user makes a response. */\n response_ends_trial: {\n type: ParameterType.BOOL,\n pretty_name: \"Response ends trial\",\n default: true,\n },\n /** If true, then the trial will end as soon as the audio file finishes playing. */\n trial_ends_after_audio: {\n type: ParameterType.BOOL,\n pretty_name: \"Trial ends after audio\",\n default: false,\n },\n /** If true, then responses are allowed while the audio is playing. If false, then the audio must finish playing before a response is accepted. */\n response_allowed_while_playing: {\n type: ParameterType.BOOL,\n pretty_name: \"Response allowed while playing\",\n default: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n * **audio-keyboard-response**\n *\n * jsPsych plugin for playing an audio file and getting a keyboard response\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/ audio-keyboard-response plugin documentation on jspsych.org}\n */\nclass AudioKeyboardResponsePlugin implements JsPsychPlugin<Info> {\n static info = info;\n private audio;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>, on_load: () => void) {\n // hold the .resolve() function from the Promise that ends the trial\n let trial_complete;\n\n // setup stimulus\n var context = this.jsPsych.pluginAPI.audioContext();\n\n // store response\n var response = {\n rt: null,\n key: null,\n };\n\n // record webaudio context start time\n var startTime;\n\n // load audio file\n this.jsPsych.pluginAPI\n .getAudioBuffer(trial.stimulus)\n .then((buffer) => {\n if (context !== null) {\n this.audio = context.createBufferSource();\n this.audio.buffer = buffer;\n this.audio.connect(context.destination);\n } else {\n this.audio = buffer;\n this.audio.currentTime = 0;\n }\n setupTrial();\n })\n .catch((err) => {\n console.error(\n `Failed to load audio file \"${trial.stimulus}\". Try checking the file path. We recommend using the preload plugin to load audio files.`\n );\n console.error(err);\n });\n\n const setupTrial = () => {\n // set up end event if trial needs it\n if (trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", end_trial);\n }\n\n // show prompt if there is one\n if (trial.prompt !== null) {\n display_element.innerHTML = trial.prompt;\n }\n\n // start audio\n if (context !== null) {\n startTime = context.currentTime;\n this.audio.start(startTime);\n } else {\n this.audio.play();\n }\n\n // start keyboard listener when trial starts or sound ends\n if (trial.response_allowed_while_playing) {\n setup_keyboard_listener();\n } else if (!trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", setup_keyboard_listener);\n }\n\n // end trial if time limit is set\n if (trial.trial_duration !== null) {\n this.jsPsych.pluginAPI.setTimeout(() => {\n end_trial();\n }, trial.trial_duration);\n }\n\n on_load();\n };\n\n // function to end trial when it is time\n const end_trial = () => {\n // kill any remaining setTimeout handlers\n this.jsPsych.pluginAPI.clearAllTimeouts();\n\n // stop the audio file if it is playing\n // remove end event listeners if they exist\n if (context !== null) {\n this.audio.stop();\n } else {\n this.audio.pause();\n }\n\n this.audio.removeEventListener(\"ended\", end_trial);\n this.audio.removeEventListener(\"ended\", setup_keyboard_listener);\n\n // kill keyboard listeners\n this.jsPsych.pluginAPI.cancelAllKeyboardResponses();\n\n // gather the data to store for the trial\n var trial_data = {\n rt: response.rt,\n stimulus: trial.stimulus,\n response: response.key,\n };\n\n // clear the display\n display_element.innerHTML = \"\";\n\n // move on to the next trial\n this.jsPsych.finishTrial(trial_data);\n\n trial_complete();\n };\n\n // function to handle responses by the subject\n function after_response(info) {\n // only record the first response\n if (response.key == null) {\n response = info;\n }\n\n if (trial.response_ends_trial) {\n end_trial();\n }\n }\n\n const setup_keyboard_listener = () => {\n // start the response listener\n if (context !== null) {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"audio\",\n persist: false,\n allow_held_key: false,\n audio_context: context,\n audio_context_start_time: startTime,\n });\n } else {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"performance\",\n persist: false,\n allow_held_key: false,\n });\n }\n };\n\n return new Promise((resolve) => {\n trial_complete = resolve;\n });\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n const respond = () => {\n if (data.rt !== null) {\n this.jsPsych.pluginAPI.pressKey(data.response, data.rt);\n }\n };\n\n this.trial(display_element, trial, () => {\n load_callback();\n if (!trial.response_allowed_while_playing) {\n this.audio.addEventListener(\"ended\", respond);\n } else {\n respond();\n }\n });\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const default_data = {\n stimulus: trial.stimulus,\n rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),\n response: this.jsPsych.pluginAPI.getValidKey(trial.choices),\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n}\n\nexport default AudioKeyboardResponsePlugin;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nconst info = <const>{\n name: \"audio-keyboard-response\",\n parameters: {\n /** The audio file to be played. */\n stimulus: {\n type: ParameterType.AUDIO,\n pretty_name: \"Stimulus\",\n default: undefined,\n },\n /** Array containing the key(s) the subject is allowed to press to respond to the stimulus. */\n choices: {\n type: ParameterType.KEYS,\n pretty_name: \"Choices\",\n default: \"ALL_KEYS\",\n },\n /** Any content here will be displayed below the stimulus. */\n prompt: {\n type: ParameterType.HTML_STRING,\n pretty_name: \"Prompt\",\n default: null,\n },\n /** The maximum duration to wait for a response. */\n trial_duration: {\n type: ParameterType.INT,\n pretty_name: \"Trial duration\",\n default: null,\n },\n /** If true, the trial will end when user makes a response. */\n response_ends_trial: {\n type: ParameterType.BOOL,\n pretty_name: \"Response ends trial\",\n default: true,\n },\n /** If true, then the trial will end as soon as the audio file finishes playing. */\n trial_ends_after_audio: {\n type: ParameterType.BOOL,\n pretty_name: \"Trial ends after audio\",\n default: false,\n },\n /** If true, then responses are allowed while the audio is playing. If false, then the audio must finish playing before a response is accepted. */\n response_allowed_while_playing: {\n type: ParameterType.BOOL,\n pretty_name: \"Response allowed while playing\",\n default: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n * **audio-keyboard-response**\n *\n * jsPsych plugin for playing an audio file and getting a keyboard response\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/plugins/jspsych-audio-keyboard-response/ audio-keyboard-response plugin documentation on jspsych.org}\n */\nclass AudioKeyboardResponsePlugin implements JsPsychPlugin<Info> {\n static info = info;\n private audio;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>, on_load: () => void) {\n // hold the .resolve() function from the Promise that ends the trial\n let trial_complete;\n\n // setup stimulus\n var context = this.jsPsych.pluginAPI.audioContext();\n\n // store response\n var response = {\n rt: null,\n key: null,\n };\n\n // record webaudio context start time\n var startTime;\n\n // load audio file\n this.jsPsych.pluginAPI\n .getAudioBuffer(trial.stimulus)\n .then((buffer) => {\n if (context !== null) {\n this.audio = context.createBufferSource();\n this.audio.buffer = buffer;\n this.audio.connect(context.destination);\n } else {\n this.audio = buffer;\n this.audio.currentTime = 0;\n }\n setupTrial();\n })\n .catch((err) => {\n console.error(\n `Failed to load audio file \"${trial.stimulus}\". Try checking the file path. We recommend using the preload plugin to load audio files.`\n );\n console.error(err);\n });\n\n const setupTrial = () => {\n // set up end event if trial needs it\n if (trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", end_trial);\n }\n\n // show prompt if there is one\n if (trial.prompt !== null) {\n display_element.innerHTML = trial.prompt;\n }\n\n // start audio\n if (context !== null) {\n startTime = context.currentTime;\n this.audio.start(startTime);\n } else {\n this.audio.play();\n }\n\n // start keyboard listener when trial starts or sound ends\n if (trial.response_allowed_while_playing) {\n setup_keyboard_listener();\n } else if (!trial.trial_ends_after_audio) {\n this.audio.addEventListener(\"ended\", setup_keyboard_listener);\n }\n\n // end trial if time limit is set\n if (trial.trial_duration !== null) {\n this.jsPsych.pluginAPI.setTimeout(() => {\n end_trial();\n }, trial.trial_duration);\n }\n\n on_load();\n };\n\n // function to end trial when it is time\n const end_trial = () => {\n // kill any remaining setTimeout handlers\n this.jsPsych.pluginAPI.clearAllTimeouts();\n\n // stop the audio file if it is playing\n // remove end event listeners if they exist\n if (context !== null) {\n this.audio.stop();\n } else {\n this.audio.pause();\n }\n\n this.audio.removeEventListener(\"ended\", end_trial);\n this.audio.removeEventListener(\"ended\", setup_keyboard_listener);\n\n // kill keyboard listeners\n this.jsPsych.pluginAPI.cancelAllKeyboardResponses();\n\n // gather the data to store for the trial\n var trial_data = {\n rt: response.rt,\n stimulus: trial.stimulus,\n response: response.key,\n };\n\n // clear the display\n display_element.innerHTML = \"\";\n\n // move on to the next trial\n this.jsPsych.finishTrial(trial_data);\n\n trial_complete();\n };\n\n // function to handle responses by the subject\n function after_response(info) {\n // only record the first response\n if (response.key == null) {\n response = info;\n }\n\n if (trial.response_ends_trial) {\n end_trial();\n }\n }\n\n const setup_keyboard_listener = () => {\n // start the response listener\n if (context !== null) {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"audio\",\n persist: false,\n allow_held_key: false,\n audio_context: context,\n audio_context_start_time: startTime,\n });\n } else {\n this.jsPsych.pluginAPI.getKeyboardResponse({\n callback_function: after_response,\n valid_responses: trial.choices,\n rt_method: \"performance\",\n persist: false,\n allow_held_key: false,\n });\n }\n };\n\n return new Promise((resolve) => {\n trial_complete = resolve;\n });\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n const respond = () => {\n if (data.rt !== null) {\n this.jsPsych.pluginAPI.pressKey(data.response, data.rt);\n }\n };\n\n this.trial(display_element, trial, () => {\n load_callback();\n if (!trial.response_allowed_while_playing) {\n this.audio.addEventListener(\"ended\", respond);\n } else {\n respond();\n }\n });\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const default_data = {\n stimulus: trial.stimulus,\n rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true),\n response: this.jsPsych.pluginAPI.getValidKey(trial.choices),\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n}\n\nexport default AudioKeyboardResponsePlugin;\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jspsych/plugin-audio-keyboard-response",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "jsPsych plugin for playing an audio file and getting a keyboard response",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -37,7 +37,7 @@
37
37
  "jspsych": ">=7.1.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@jspsych/config": "^1.1.0",
40
+ "@jspsych/config": "^1.3.0",
41
41
  "@jspsych/test-utils": "^1.1.0"
42
42
  }
43
43
  }