mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 18:50:54 +00:00
Merge pull request #529 from apitiot/2022.2.4
ENH Sound values can be changed without instantiating a new SoundPlayer
This commit is contained in:
commit
f8a2b10e88
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "psychojs",
|
"name": "psychojs",
|
||||||
"version": "2022.2.3",
|
"version": "2022.2.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Helps run in-browser neuroscience, psychology, and psychophysics experiments",
|
"description": "Helps run in-browser neuroscience, psychology, and psychophysics experiments",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -170,7 +170,7 @@ export class PsychoJS
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.info("[PsychoJS] Initialised.");
|
this.logger.info("[PsychoJS] Initialised.");
|
||||||
this.logger.info("[PsychoJS] @version 2022.2.1");
|
this.logger.info("[PsychoJS] @version 2022.2.4");
|
||||||
|
|
||||||
// hide the initialisation message:
|
// hide the initialisation message:
|
||||||
const root = document.getElementById("root");
|
const root = document.getElementById("root");
|
||||||
|
@ -53,28 +53,21 @@ export class AudioClipPlayer extends SoundPlayer
|
|||||||
/**
|
/**
|
||||||
* Determine whether this player can play the given sound.
|
* Determine whether this player can play the given sound.
|
||||||
*
|
*
|
||||||
* @param {module:sound.Sound} sound - the sound object, which should be an AudioClip
|
* @param {module:core.PsychoJS} psychoJS - the PsychoJS instance
|
||||||
* @return {Object|undefined} an instance of AudioClipPlayer if sound is an AudioClip or undefined otherwise
|
* @param {string} value - the sound value, which should be the name of an audio resource
|
||||||
|
* file
|
||||||
|
* @return {Object|boolean} argument needed to instantiate a AudioClipPlayer that can play the given sound
|
||||||
|
* or false otherwise
|
||||||
*/
|
*/
|
||||||
static accept(sound)
|
static accept(psychoJS, value)
|
||||||
{
|
{
|
||||||
if (sound.value instanceof AudioClip)
|
if (value instanceof AudioClip)
|
||||||
{
|
{
|
||||||
// build the player:
|
return { audioClip: value };
|
||||||
const player = new AudioClipPlayer({
|
|
||||||
psychoJS: sound.psychoJS,
|
|
||||||
audioClip: sound.value,
|
|
||||||
startTime: sound.startTime,
|
|
||||||
stopTime: sound.stopTime,
|
|
||||||
stereo: sound.stereo,
|
|
||||||
loops: sound.loops,
|
|
||||||
volume: sound.volume,
|
|
||||||
});
|
|
||||||
return player;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AudioClipPlayer is not an appropriate player for the given sound:
|
// AudioClipPlayer is not an appropriate player for the given sound:
|
||||||
return undefined;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,6 +122,23 @@ export class AudioClipPlayer extends SoundPlayer
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the audio clip.
|
||||||
|
*
|
||||||
|
* @param {Object} options.audioClip - the module:sound.AudioClip.
|
||||||
|
*/
|
||||||
|
setAudioClip(audioClip)
|
||||||
|
{
|
||||||
|
if (audioClip instanceof AudioClip)
|
||||||
|
{
|
||||||
|
if (this._audioClip !== undefined)
|
||||||
|
{
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
this._audioClip = audioClip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start playing the sound.
|
* Start playing the sound.
|
||||||
*
|
*
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/**
|
/**
|
||||||
* Sound stimulus.
|
* Sound stimulus.
|
||||||
*
|
*
|
||||||
* @author Alain Pitiot
|
* @author Alain Pitiot, Nikita Agafonov
|
||||||
* @version 2022.2.3
|
* @version 2022.2.3
|
||||||
* @copyright (c) 2017-2020 Ilixa Ltd. (http://ilixa.com) (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
|
* @copyright (c) 2017-2020 Ilixa Ltd. (http://ilixa.com) (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
|
||||||
* @license Distributed under the terms of the MIT License
|
* @license Distributed under the terms of the MIT License
|
||||||
@ -74,7 +74,6 @@ export class Sound extends PsychObject
|
|||||||
this._player = undefined;
|
this._player = undefined;
|
||||||
|
|
||||||
this._addAttribute("win", win);
|
this._addAttribute("win", win);
|
||||||
this._addAttribute("value", value);
|
|
||||||
this._addAttribute("octave", octave);
|
this._addAttribute("octave", octave);
|
||||||
this._addAttribute("secs", secs);
|
this._addAttribute("secs", secs);
|
||||||
this._addAttribute("startTime", startTime);
|
this._addAttribute("startTime", startTime);
|
||||||
@ -84,8 +83,9 @@ export class Sound extends PsychObject
|
|||||||
this._addAttribute("loops", loops);
|
this._addAttribute("loops", loops);
|
||||||
this._addAttribute("autoLog", autoLog);
|
this._addAttribute("autoLog", autoLog);
|
||||||
|
|
||||||
// identify an appropriate player:
|
// note: setValue will identify the appropriate SoundPlayer and possibly instantiate it
|
||||||
this._getPlayer();
|
// consequently _addAtribute("value") needs to be the last one so the other attributes are already set
|
||||||
|
this._addAttribute("value", value);
|
||||||
|
|
||||||
this.status = PsychoJS.Status.NOT_STARTED;
|
this.status = PsychoJS.Status.NOT_STARTED;
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ export class Sound extends PsychObject
|
|||||||
* Repeat calls to play may results in the sounds being played on top of each other.</p>
|
* Repeat calls to play may results in the sounds being played on top of each other.</p>
|
||||||
*
|
*
|
||||||
* @param {number} loops how many times to repeat the sound after it plays once. If loops == -1, the sound will repeat indefinitely until stopped.
|
* @param {number} loops how many times to repeat the sound after it plays once. If loops == -1, the sound will repeat indefinitely until stopped.
|
||||||
* @param {boolean} [log= true] whether or not to log
|
* @param {boolean} [log= true] whether to log
|
||||||
*/
|
*/
|
||||||
play(loops, log = true)
|
play(loops, log = true)
|
||||||
{
|
{
|
||||||
@ -109,7 +109,7 @@ export class Sound extends PsychObject
|
|||||||
* Stop playing the sound immediately.
|
* Stop playing the sound immediately.
|
||||||
*
|
*
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {boolean} [options.log= true] - whether or not to log
|
* @param {boolean} [options.log= true] - whether to log
|
||||||
*/
|
*/
|
||||||
stop({
|
stop({
|
||||||
log = true,
|
log = true,
|
||||||
@ -134,7 +134,7 @@ export class Sound extends PsychObject
|
|||||||
*
|
*
|
||||||
* @param {number} volume - the volume (values should be between 0 and 1)
|
* @param {number} volume - the volume (values should be between 0 and 1)
|
||||||
* @param {boolean} [mute= false] - whether or not to mute the sound
|
* @param {boolean} [mute= false] - whether or not to mute the sound
|
||||||
* @param {boolean} [log= true] - whether of not to log
|
* @param {boolean} [log= true] - whether to log
|
||||||
*/
|
*/
|
||||||
setVolume(volume, mute = false, log = true)
|
setVolume(volume, mute = false, log = true)
|
||||||
{
|
{
|
||||||
@ -147,38 +147,108 @@ export class Sound extends PsychObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the sound value on demand past initialisation.
|
* Set the sound value.
|
||||||
*
|
*
|
||||||
* @param {object} sound - a sound instance to replace the current one
|
* @param {object} sound - a sound instance to replace the current one
|
||||||
* @param {boolean} [log= true] - whether or not to log
|
* @param {boolean} [log= true] - whether to log
|
||||||
*/
|
*/
|
||||||
setSound(sound, log = true)
|
setSound(sound, log = true)
|
||||||
{
|
{
|
||||||
if (sound instanceof Sound)
|
if (!(sound instanceof Sound))
|
||||||
{
|
{
|
||||||
this._setAttribute("value", sound.value, log);
|
throw {
|
||||||
|
origin: "Sound.setSound",
|
||||||
|
context: "when setting the sound",
|
||||||
|
error: "the argument should be an instance of the Sound class.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof this._player !== "undefined")
|
this._setAttribute("value", sound.value, log);
|
||||||
|
|
||||||
|
if (typeof this._player !== "undefined")
|
||||||
|
{
|
||||||
|
this._player = this._player.constructor.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sound value.
|
||||||
|
*
|
||||||
|
* @param {number|string} [value = "C"] - the sound value
|
||||||
|
* @param {number} [octave = 4] - the octave corresponding to the tone (if applicable)
|
||||||
|
* @param {boolean} [log=true] - whether to log
|
||||||
|
*/
|
||||||
|
setValue(value = "C", octave = 4, log = true)
|
||||||
|
{
|
||||||
|
this._setAttribute("value", value, log);
|
||||||
|
|
||||||
|
const args = {
|
||||||
|
psychoJS: this._psychoJS,
|
||||||
|
stereo: this._stereo,
|
||||||
|
volume: this._volume,
|
||||||
|
loops: this._loops,
|
||||||
|
startTime: this._startTime,
|
||||||
|
stopTime: this._stopTime,
|
||||||
|
secs: this._secs
|
||||||
|
}
|
||||||
|
|
||||||
|
let playerArgs = TonePlayer.accept(value, octave);
|
||||||
|
if (typeof playerArgs !== "undefined")
|
||||||
|
{
|
||||||
|
if (this._player instanceof TonePlayer)
|
||||||
{
|
{
|
||||||
this._player = this._player.constructor.accept(this);
|
this._player.setTone(value, octave);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._player = new TonePlayer(Object.assign(args, playerArgs));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Be fluent?
|
playerArgs = TrackPlayer.accept(this._psychoJS, value);
|
||||||
return this;
|
if (playerArgs !== false)
|
||||||
|
{
|
||||||
|
if (this._player instanceof TrackPlayer)
|
||||||
|
{
|
||||||
|
this._player.setTrack(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._player = new TrackPlayer(Object.assign(args, playerArgs));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerArgs = AudioClipPlayer.accept(this._psychoJS, value);
|
||||||
|
if (typeof playerArgs !== "undefined")
|
||||||
|
{
|
||||||
|
if (this._player instanceof AudioClipPlayer)
|
||||||
|
{
|
||||||
|
this._player.setAudioClip(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._player = new AudioClipPlayer(Object.assign(args, playerArgs));
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw {
|
throw {
|
||||||
origin: "Sound.setSound",
|
origin: "Sound.setValue",
|
||||||
context: "when replacing the current sound",
|
context: "when setting the sound value",
|
||||||
error: "invalid input, need an instance of the Sound class.",
|
error: "could not find an appropriate player.",
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the number of loops.
|
* Set the number of loops.
|
||||||
*
|
*
|
||||||
* @param {number} [loops=0] - how many times to repeat the sound after it has played once. If loops == -1, the sound will repeat indefinitely until stopped.
|
* @param {number} [loops=0] - how many times to repeat the sound after it has played once. If loops == -1, the sound will repeat indefinitely until stopped.
|
||||||
* @param {boolean} [log=true] - whether of not to log
|
* @param {boolean} [log=true] - whether to log
|
||||||
*/
|
*/
|
||||||
setLoops(loops = 0, log = true)
|
setLoops(loops = 0, log = true)
|
||||||
{
|
{
|
||||||
@ -194,7 +264,7 @@ export class Sound extends PsychObject
|
|||||||
* Set the duration (in seconds)
|
* Set the duration (in seconds)
|
||||||
*
|
*
|
||||||
* @param {number} [secs=0.5] - duration of the tone (in seconds) If secs == -1, the sound will play indefinitely.
|
* @param {number} [secs=0.5] - duration of the tone (in seconds) If secs == -1, the sound will play indefinitely.
|
||||||
* @param {boolean} [log=true] - whether or not to log
|
* @param {boolean} [log=true] - whether to log
|
||||||
*/
|
*/
|
||||||
setSecs(secs = 0.5, log = true)
|
setSecs(secs = 0.5, log = true)
|
||||||
{
|
{
|
||||||
|
@ -26,22 +26,6 @@ export class SoundPlayer extends PsychObject
|
|||||||
super(psychoJS);
|
super(psychoJS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether this player can play the given sound.
|
|
||||||
*
|
|
||||||
* @abstract
|
|
||||||
* @param {module:sound.Sound} - the sound
|
|
||||||
* @return {Object|undefined} an instance of the SoundPlayer that can play the sound, or undefined if none could be found
|
|
||||||
*/
|
|
||||||
static accept(sound)
|
|
||||||
{
|
|
||||||
throw {
|
|
||||||
origin: "SoundPlayer.accept",
|
|
||||||
context: "when evaluating whether this player can play a given sound",
|
|
||||||
error: "this method is abstract and should not be called.",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start playing the sound.
|
* Start playing the sound.
|
||||||
*
|
*
|
||||||
|
@ -24,7 +24,7 @@ export class TonePlayer extends SoundPlayer
|
|||||||
* @memberOf module:sound
|
* @memberOf module:sound
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {module:core.PsychoJS} options.psychoJS - the PsychoJS instance
|
* @param {module:core.PsychoJS} options.psychoJS - the PsychoJS instance
|
||||||
* @param {number} [options.duration_s= 0.5] - duration of the tone (in seconds). If duration_s == -1, the sound will play indefinitely.
|
* @param {number} [options.secs= 0.5] - duration of the tone (in seconds). If secs == -1, the sound will play indefinitely.
|
||||||
* @param {string|number} [options.note= 'C4'] - note (if string) or frequency (if number)
|
* @param {string|number} [options.note= 'C4'] - note (if string) or frequency (if number)
|
||||||
* @param {number} [options.volume= 1.0] - volume of the tone (must be between 0 and 1.0)
|
* @param {number} [options.volume= 1.0] - volume of the tone (must be between 0 and 1.0)
|
||||||
* @param {number} [options.loops= 0] - how many times to repeat the tone after it has played once. If loops == -1, the tone will repeat indefinitely until stopped.
|
* @param {number} [options.loops= 0] - how many times to repeat the tone after it has played once. If loops == -1, the tone will repeat indefinitely until stopped.
|
||||||
@ -32,7 +32,7 @@ export class TonePlayer extends SoundPlayer
|
|||||||
constructor({
|
constructor({
|
||||||
psychoJS,
|
psychoJS,
|
||||||
note = "C4",
|
note = "C4",
|
||||||
duration_s = 0.5,
|
secs = 0.5,
|
||||||
volume = 1.0,
|
volume = 1.0,
|
||||||
loops = 0,
|
loops = 0,
|
||||||
soundLibrary = TonePlayer.SoundLibrary.TONE_JS,
|
soundLibrary = TonePlayer.SoundLibrary.TONE_JS,
|
||||||
@ -42,7 +42,7 @@ export class TonePlayer extends SoundPlayer
|
|||||||
super(psychoJS);
|
super(psychoJS);
|
||||||
|
|
||||||
this._addAttribute("note", note);
|
this._addAttribute("note", note);
|
||||||
this._addAttribute("duration_s", duration_s);
|
this._addAttribute("duration_s", secs);
|
||||||
this._addAttribute("volume", volume);
|
this._addAttribute("volume", volume);
|
||||||
this._addAttribute("loops", loops);
|
this._addAttribute("loops", loops);
|
||||||
this._addAttribute("soundLibrary", soundLibrary);
|
this._addAttribute("soundLibrary", soundLibrary);
|
||||||
@ -66,25 +66,21 @@ export class TonePlayer extends SoundPlayer
|
|||||||
* <p>Note: if TonePlayer accepts the sound but Tone.js is not available, e.g. if the browser is IE11,
|
* <p>Note: if TonePlayer accepts the sound but Tone.js is not available, e.g. if the browser is IE11,
|
||||||
* we throw an exception.</p>
|
* we throw an exception.</p>
|
||||||
*
|
*
|
||||||
* @param {module:sound.Sound} sound - the sound
|
* @param {string|number} value - potential frequency or note
|
||||||
* @return {Object|undefined} an instance of TonePlayer that can play the given sound or undefined otherwise
|
* @param {number} octave - the octave corresponding to the tone
|
||||||
|
* @return {Object|boolean} argument needed to instantiate a TonePlayer that can play the given sound
|
||||||
|
* or false otherwise
|
||||||
*/
|
*/
|
||||||
static accept(sound)
|
static accept(value, octave)
|
||||||
{
|
{
|
||||||
// if the sound's value is an integer, we interpret it as a frequency:
|
// if the sound's value is an integer, we interpret it as a frequency:
|
||||||
if (isNumeric(sound.value))
|
if (isNumeric(value))
|
||||||
{
|
{
|
||||||
return new TonePlayer({
|
return { note: value }
|
||||||
psychoJS: sound.psychoJS,
|
|
||||||
note: sound.value,
|
|
||||||
duration_s: sound.secs,
|
|
||||||
volume: sound.volume,
|
|
||||||
loops: sound.loops,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the sound's value is a string, we check whether it is a note:
|
// if the sound's value is a string, we check whether it is a note:
|
||||||
if (typeof sound.value === "string")
|
if (typeof value === "string")
|
||||||
{
|
{
|
||||||
// mapping between the PsychoPY notes and the standard ones:
|
// mapping between the PsychoPY notes and the standard ones:
|
||||||
let psychopyToToneMap = new Map();
|
let psychopyToToneMap = new Map();
|
||||||
@ -96,21 +92,15 @@ export class TonePlayer extends SoundPlayer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check whether the sound's value is a recognised note:
|
// check whether the sound's value is a recognised note:
|
||||||
const note = psychopyToToneMap.get(sound.value);
|
const note = psychopyToToneMap.get(value);
|
||||||
if (typeof note !== "undefined")
|
if (typeof note !== "undefined")
|
||||||
{
|
{
|
||||||
return new TonePlayer({
|
return { note: note + octave };
|
||||||
psychoJS: sound.psychoJS,
|
|
||||||
note: note + sound.octave,
|
|
||||||
duration_s: sound.secs,
|
|
||||||
volume: sound.volume,
|
|
||||||
loops: sound.loops,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TonePlayer is not an appropriate player for the given sound:
|
// the value does not seem to correspond to a tone we can play:
|
||||||
return undefined;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,11 +116,11 @@ export class TonePlayer extends SoundPlayer
|
|||||||
/**
|
/**
|
||||||
* Set the duration of the tone.
|
* Set the duration of the tone.
|
||||||
*
|
*
|
||||||
* @param {number} duration_s - the duration of the tone (in seconds) If duration_s == -1, the sound will play indefinitely.
|
* @param {number} secs - the duration of the tone (in seconds) If secs == -1, the sound will play indefinitely.
|
||||||
*/
|
*/
|
||||||
setDuration(duration_s)
|
setDuration(secs)
|
||||||
{
|
{
|
||||||
this.duration_s = duration_s;
|
this.duration_s = secs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,6 +162,23 @@ export class TonePlayer extends SoundPlayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the note for tone.
|
||||||
|
*
|
||||||
|
* @param {string|number} value - potential frequency or note
|
||||||
|
* @param {number} octave - the octave corresponding to the tone
|
||||||
|
*/
|
||||||
|
setTone(value = "C", octave = 4)
|
||||||
|
{
|
||||||
|
const args = TonePlayer.accept(value, octave);
|
||||||
|
this._note = args.note;
|
||||||
|
|
||||||
|
if (typeof this._synth !== "undefined")
|
||||||
|
{
|
||||||
|
this._synth.setNote(this._note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start playing the sound.
|
* Start playing the sound.
|
||||||
*
|
*
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { SoundPlayer } from "./SoundPlayer.js";
|
import { SoundPlayer } from "./SoundPlayer.js";
|
||||||
|
import { Howl } from "howler";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>This class handles the playback of sound tracks.</p>
|
* <p>This class handles the playback of sound tracks.</p>
|
||||||
@ -54,34 +55,43 @@ export class TrackPlayer extends SoundPlayer
|
|||||||
/**
|
/**
|
||||||
* Determine whether this player can play the given sound.
|
* Determine whether this player can play the given sound.
|
||||||
*
|
*
|
||||||
* @param {module:sound.Sound} sound - the sound, which should be the name of an audio resource
|
* @param {string} value - the sound, which should be the name of an audio resource file
|
||||||
* file
|
* @return {boolean} whether or not value is supported
|
||||||
* @return {Object|undefined} an instance of TrackPlayer that can play the given track or undefined otherwise
|
|
||||||
*/
|
*/
|
||||||
static accept(sound)
|
static checkValueSupport (value)
|
||||||
{
|
{
|
||||||
// if the sound's value is a string, we check whether it is the name of a resource:
|
if (typeof value === "string")
|
||||||
if (typeof sound.value === "string")
|
|
||||||
{
|
{
|
||||||
const howl = sound.psychoJS.serverManager.getResource(sound.value);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether this player can play the given sound.
|
||||||
|
*
|
||||||
|
* @param {module:core.PsychoJS} psychoJS - the PsychoJS instance
|
||||||
|
* @param {string} value - the sound value, which should be the name of an audio resource
|
||||||
|
* file
|
||||||
|
* @return {Object|boolean} argument needed to instantiate a TrackPlayer that can play the given sound
|
||||||
|
* or false otherwise
|
||||||
|
*/
|
||||||
|
static accept(psychoJS, value)
|
||||||
|
{
|
||||||
|
// value should be a string:
|
||||||
|
if (typeof value === "string")
|
||||||
|
{
|
||||||
|
// check whether the value is the name of a resource:
|
||||||
|
const howl = psychoJS.serverManager.getResource(value);
|
||||||
if (typeof howl !== "undefined")
|
if (typeof howl !== "undefined")
|
||||||
{
|
{
|
||||||
// build the player:
|
return { howl };
|
||||||
const player = new TrackPlayer({
|
|
||||||
psychoJS: sound.psychoJS,
|
|
||||||
howl: howl,
|
|
||||||
startTime: sound.startTime,
|
|
||||||
stopTime: sound.stopTime,
|
|
||||||
stereo: sound.stereo,
|
|
||||||
loops: sound.loops,
|
|
||||||
volume: sound.volume,
|
|
||||||
});
|
|
||||||
return player;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TonePlayer is not an appropriate player for the given sound:
|
// TonePlayer is not an appropriate player for the given sound:
|
||||||
return undefined;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,6 +152,36 @@ export class TrackPlayer extends SoundPlayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set new track to play.
|
||||||
|
*
|
||||||
|
* @param {Object|string} track - a track resource name or Howl object (see {@link https://howlerjs.com/})
|
||||||
|
*/
|
||||||
|
setTrack(track)
|
||||||
|
{
|
||||||
|
let newHowl = undefined;
|
||||||
|
|
||||||
|
if (typeof track === "string")
|
||||||
|
{
|
||||||
|
newHowl = this.psychoJS.serverManager.getResource(track);
|
||||||
|
}
|
||||||
|
else if (track instanceof Howl)
|
||||||
|
{
|
||||||
|
newHowl = track;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newHowl !== undefined)
|
||||||
|
{
|
||||||
|
this._howl.once("fade", (id) =>
|
||||||
|
{
|
||||||
|
this._howl.stop(id);
|
||||||
|
this._howl.off("end");
|
||||||
|
this._howl = newHowl;
|
||||||
|
});
|
||||||
|
this._howl.fade(this._howl.volume(), 0, 17, this._id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start playing the sound.
|
* Start playing the sound.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user