mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 10:40:54 +00:00
176 lines
4.2 KiB
JavaScript
176 lines
4.2 KiB
JavaScript
/**
|
|
* @file Track Player.
|
|
*
|
|
* @author Alain Pitiot
|
|
* @version 3.0.0b11
|
|
* @copyright (c) 2018 Ilixa Ltd. ({@link http://ilixa.com})
|
|
* @license Distributed under the terms of the MIT License
|
|
*/
|
|
|
|
import { SoundPlayer } from './SoundPlayer';
|
|
|
|
|
|
/**
|
|
* <p>This class handles the playback of sound tracks.</p>
|
|
*
|
|
* @name module:sound.TrackPlayer
|
|
* @class
|
|
* @extends SoundPlayer
|
|
* @param {Object} options
|
|
* @param {PsychoJS} options.psychoJS - the PsychoJS instance
|
|
* @param {Object} options.howl - the sound object (see {@link https://howlerjs.com/})
|
|
* @param {number} [options.startTime= 0] - start of playback (in seconds)
|
|
* @param {number} [options.stopTime= -1] - end of playback (in seconds)
|
|
* @param {boolean} [options.stereo= true] whether or not to play the sound or track in stereo
|
|
* @param {number} [options.volume= 1.0] - volume of the sound (must be between 0 and 1.0)
|
|
* @param {number} [options.loops= 0] - how many times to repeat the track or tone after it has played *
|
|
* @todo stopTime is currently not implemented (tracks will play from startTime to finish)
|
|
* @todo stereo is currently not implemented
|
|
*/
|
|
export class TrackPlayer extends SoundPlayer {
|
|
constructor({
|
|
psychoJS,
|
|
howl,
|
|
startTime = 0,
|
|
stopTime = -1,
|
|
stereo = true,
|
|
volume = 0,
|
|
loops = 0
|
|
} = {}) {
|
|
super(psychoJS);
|
|
|
|
this._addAttributes(TrackPlayer, howl, startTime, stopTime, stereo, loops, volume);
|
|
|
|
this._currentLoopIndex = -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* Determine whether this player can play the given sound.
|
|
*
|
|
* @name module:sound.TrackPlayer.accept
|
|
* @function
|
|
* @static
|
|
* @public
|
|
* @param {module:sound.Sound} - the sound
|
|
* @return {Object|undefined} an instance of TrackPlayer that can play the given sound or undefined otherwise
|
|
*/
|
|
static accept(sound) {
|
|
// if the sound's value is a string, we check whether it is the name of a resource:
|
|
if (typeof sound.value === 'string') {
|
|
const howl = sound.psychoJS.serverManager.getResource(sound.value);
|
|
if (typeof howl !== 'undefined') {
|
|
// build the player:
|
|
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:
|
|
return undefined;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the duration of the sound, in seconds.
|
|
*
|
|
* @name module:sound.TrackPlayer#getDuration
|
|
* @function
|
|
* @public
|
|
* @return {number} the duration of the track, in seconds
|
|
*/
|
|
getDuration()
|
|
{
|
|
return this._howl.duration();
|
|
}
|
|
|
|
|
|
/**
|
|
* Set the volume of the tone.
|
|
*
|
|
* @name module:sound.TrackPlayer#setVolume
|
|
* @function
|
|
* @public
|
|
* @param {Integer} volume - the volume of the track (must be between 0 and 1.0)
|
|
* @param {booleam} [mute= false] - whether or not to mute the track
|
|
*/
|
|
setVolume(volume, mute = false) {
|
|
this._volume = volume;
|
|
|
|
this._howl.volume(volume);
|
|
this._howl.mute(mute);
|
|
}
|
|
|
|
|
|
/**
|
|
* Set the number of loops.
|
|
*
|
|
* @name module:sound.TrackPlayer#setLoops
|
|
* @function
|
|
* @public
|
|
* @param {number} loops - how many times to repeat the track after it has played once. If loops == -1, the track will repeat indefinitely until stopped.
|
|
*/
|
|
setLoops(loops)
|
|
{
|
|
this._loops = loops;
|
|
this._currentLoopIndex = -1;
|
|
|
|
if (loops == 0)
|
|
this._howl.loop(false);
|
|
else
|
|
this._howl.loop(true);
|
|
}
|
|
|
|
|
|
/**
|
|
* Start playing the sound.
|
|
*
|
|
* @name module:sound.TrackPlayer#play
|
|
* @function
|
|
* @public
|
|
* @param {boolean} [loops] how many times to repeat the track after it has played once. If loops == -1, the track will repeat indefinitely until stopped.
|
|
*/
|
|
play(loops) {
|
|
if (typeof loops !== 'undefined')
|
|
this.setLoops(loops);
|
|
|
|
// handle repeats:
|
|
if (loops > 0) {
|
|
const self = this;
|
|
this._howl.on('end', (event) => {
|
|
++this._currentLoopIndex;
|
|
if (self._currentLoopIndex > self._loops)
|
|
self.stop();
|
|
else {
|
|
self._howl.seek(self._startTime);
|
|
self._howl.play();
|
|
}
|
|
});
|
|
}
|
|
|
|
this._howl.seek(this._startTime);
|
|
this._howl.play();
|
|
}
|
|
|
|
|
|
/**
|
|
* Stop playing the sound immediately.
|
|
*
|
|
* @name module:sound.TrackPlayer#stop
|
|
* @function
|
|
* @public
|
|
*/
|
|
stop() {
|
|
this._howl.stop();
|
|
this._howl.off('end');
|
|
}
|
|
|
|
} |