diff --git a/docs/Syntax.md b/docs/Syntax.md index a28f86f20b..f3313818a3 100644 --- a/docs/Syntax.md +++ b/docs/Syntax.md @@ -485,6 +485,7 @@ Note that when Snap! encodes a function to LISP syntax it automatically recogniz | | go back _ layers | **back** | | ` (back 1) ` | | **sound** | play sound _ | **play** | | ` (play nil) ` | | | play sound _ until done | **playAll** | | ` (playAll nil) ` | +| | stop sound _ | **stopSound** | | ` (stopSound nil) ` | | | stop all sounds | **stopSounds** | | ` (stopSounds) ` | | | play sound _ at _ Hz | **playAt** | | ` (playAt nil 44100) ` | | | _ of sound _ | **sound** | *reporter* | ` (sound [duration] nil) ` | diff --git a/src/objects.js b/src/objects.js index 0b461c59cc..7a40146efb 100644 --- a/src/objects.js +++ b/src/objects.js @@ -776,6 +776,13 @@ SpriteMorph.prototype.primitiveBlocks = function () { (prim t doPlaySoundAtRate target rate) (play (newSound (sound [samples] (get target)) (get rate))))` }, + doStopSound: { + type: 'command', + category: 'sound', + spec: 'stop sound %snd', + defaults: [''], + code: 'stopSound' + }, doStopAllSounds: { type: 'command', category: 'sound', @@ -3658,6 +3665,7 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push(block('playSound')); blocks.push(block('doPlaySoundUntilDone')); + blocks.push(block('doStopSound')); blocks.push(block('doStopAllSounds')); blocks.push('-'); blocks.push(block('doPlaySoundAtRate')); @@ -10908,6 +10916,7 @@ StageMorph.prototype.blockTemplates = function ( blocks.push(block('playSound')); blocks.push(block('doPlaySoundUntilDone')); + blocks.push(block('doStopSound')); blocks.push(block('doStopAllSounds')); blocks.push('-'); blocks.push(block('doPlaySoundAtRate')); @@ -11896,6 +11905,11 @@ StageMorph.prototype.addSound StageMorph.prototype.doPlaySound = SpriteMorph.prototype.doPlaySound; +StageMorph.prototype.stopSound = function (src) { + this.activeSounds.forEach(audio => {if (src === audio.src) audio.pause()}); + this.activeSounds = this.activeSounds.filter(audio => audio.src === src); +}; + StageMorph.prototype.stopAllActiveSounds = function () { this.activeSounds.forEach(audio => audio.pause()); this.activeSounds = []; diff --git a/src/threads.js b/src/threads.js index 24ba7a895b..7d65b6e70a 100644 --- a/src/threads.js +++ b/src/threads.js @@ -4021,6 +4021,17 @@ Process.prototype.doPlaySoundUntilDone = function (name) { this.pushContext(); }; +Process.prototype.doStopSound = function (name) { + var stage = this.homeContext.receiver.parentThatIsA(StageMorph); + var rcvr = this.blockReceiver(); + rcvr.shadowAttribute('sounds'); + + if (stage && rcvr.sounds.contents.some(sound => sound.name === name)) { + stage.stopSound(rcvr.sounds.contents.find( + sound => sound.name === name).audio.src); + } +}; + Process.prototype.doStopAllSounds = function () { var stage = this.homeContext.receiver.parentThatIsA(StageMorph); if (stage) {