diff --git a/src/blocks/scratch3_sound.js b/src/blocks/scratch3_sound.js
index aa227c513..20d137580 100644
--- a/src/blocks/scratch3_sound.js
+++ b/src/blocks/scratch3_sound.js
@@ -79,6 +79,7 @@ Scratch3SoundBlocks.prototype.playSound = function (args, util) {
     var index = this._getSoundIndex(args.SOUND_MENU, util);
     if (index >= 0) {
         var md5 = util.target.sprite.sounds[index].md5;
+        if (util.target.audioPlayer === null) return;
         util.target.audioPlayer.playSound(md5);
     }
 };
@@ -87,6 +88,7 @@ Scratch3SoundBlocks.prototype.playSoundAndWait = function (args, util) {
     var index = this._getSoundIndex(args.SOUND_MENU, util);
     if (index >= 0) {
         var md5 = util.target.sprite.sounds[index].md5;
+        if (util.target.audioPlayer === null) return;
         return util.target.audioPlayer.playSound(md5);
     }
 };
@@ -124,6 +126,7 @@ Scratch3SoundBlocks.prototype.getSoundIndexByName = function (soundName, util) {
 };
 
 Scratch3SoundBlocks.prototype.stopAllSounds = function (args, util) {
+    if (util.target.audioPlayer === null) return;
     util.target.audioPlayer.stopAllSounds();
 };
 
@@ -132,19 +135,23 @@ Scratch3SoundBlocks.prototype.playNoteForBeats = function (args, util) {
     var beats = Cast.toNumber(args.BEATS);
     var soundState = this._getSoundState(util.target);
     var inst = soundState.currentInstrument;
+    if (typeof this.runtime.audioEngine === 'undefined') return;
     return this.runtime.audioEngine.playNoteForBeatsWithInst(note, beats, inst);
 };
 
 Scratch3SoundBlocks.prototype.playDrumForBeats = function (args, util) {
     var drum = Cast.toNumber(args.DRUM);
     drum -= 1; // drums are one-indexed
+    if (typeof this.runtime.audioEngine === 'undefined') return;
     drum = MathUtil.wrapClamp(drum, 0, this.runtime.audioEngine.numDrums);
     var beats = Cast.toNumber(args.BEATS);
+    if (util.target.audioPlayer === null) return;
     return util.target.audioPlayer.playDrumForBeats(drum, beats);
 };
 
 Scratch3SoundBlocks.prototype.restForBeats = function (args) {
     var beats = Cast.toNumber(args.BEATS);
+    if (typeof this.runtime.audioEngine === 'undefined') return;
     return this.runtime.audioEngine.waitForBeats(beats);
 };
 
@@ -152,6 +159,7 @@ Scratch3SoundBlocks.prototype.setInstrument = function (args, util) {
     var soundState = this._getSoundState(util.target);
     var instNum = Cast.toNumber(args.INSTRUMENT);
     instNum -= 1; // instruments are one-indexed
+    if (typeof this.runtime.audioEngine === 'undefined') return;
     instNum = MathUtil.wrapClamp(instNum, 0, this.runtime.audioEngine.numInstruments);
     soundState.currentInstrument = instNum;
     return this.runtime.audioEngine.instrumentPlayer.loadInstrument(soundState.currentInstrument);
@@ -165,6 +173,7 @@ Scratch3SoundBlocks.prototype.setEffect = function (args, util) {
     if (!soundState.effects.hasOwnProperty(effect)) return;
 
     soundState.effects[effect] = value;
+    if (util.target.audioPlayer === null) return;
     util.target.audioPlayer.setEffect(effect, soundState.effects[effect]);
 };
 
@@ -176,6 +185,7 @@ Scratch3SoundBlocks.prototype.changeEffect = function (args, util) {
     if (!soundState.effects.hasOwnProperty(effect)) return;
 
     soundState.effects[effect] += value;
+    if (util.target.audioPlayer === null) return;
     util.target.audioPlayer.setEffect(effect, soundState.effects[effect]);
 };
 
@@ -184,6 +194,7 @@ Scratch3SoundBlocks.prototype.clearEffects = function (args, util) {
     for (var effect in soundState.effects) {
         soundState.effects[effect] = 0;
     }
+    if (util.target.audioPlayer === null) return;
     util.target.audioPlayer.clearEffects();
 };
 
@@ -202,6 +213,7 @@ Scratch3SoundBlocks.prototype._updateVolume = function (volume, util) {
     var soundState = this._getSoundState(util.target);
     volume = MathUtil.clamp(volume, 0, 100);
     soundState.volume = volume;
+    if (util.target.audioPlayer === null) return;
     util.target.audioPlayer.setVolume(soundState.volume);
 };
 
@@ -212,15 +224,18 @@ Scratch3SoundBlocks.prototype.getVolume = function (args, util) {
 
 Scratch3SoundBlocks.prototype.setTempo = function (args) {
     var value = Cast.toNumber(args.TEMPO);
+    if (typeof this.runtime.audioEngine === 'undefined') return;
     this.runtime.audioEngine.setTempo(value);
 };
 
 Scratch3SoundBlocks.prototype.changeTempo = function (args) {
     var value = Cast.toNumber(args.TEMPO);
+    if (typeof this.runtime.audioEngine === 'undefined') return;
     this.runtime.audioEngine.changeTempo(value);
 };
 
 Scratch3SoundBlocks.prototype.getTempo = function () {
+    if (typeof this.runtime.audioEngine === 'undefined') return;
     return this.runtime.audioEngine.currentTempo;
 };
 
diff --git a/test/fixtures/sound.sb2 b/test/fixtures/sound.sb2
new file mode 100644
index 000000000..dce594b37
Binary files /dev/null and b/test/fixtures/sound.sb2 differ
diff --git a/test/integration/sound.js b/test/integration/sound.js
new file mode 100644
index 000000000..dc1a58eee
--- /dev/null
+++ b/test/integration/sound.js
@@ -0,0 +1,35 @@
+var path = require('path');
+var test = require('tap').test;
+var extract = require('../fixtures/extract');
+var VirtualMachine = require('../../src/index');
+
+var uri = path.resolve(__dirname, '../fixtures/sound.sb2');
+var project = extract(uri);
+
+test('sound', function (t) {
+    var vm = new VirtualMachine();
+
+    // Evaluate playground data and exit
+    vm.on('playgroundData', function (e) {
+        var threads = JSON.parse(e.threads);
+        t.ok(threads.length > 0);
+        t.end();
+        process.nextTick(process.exit);
+    });
+
+    // Start VM, load project, and run
+    t.doesNotThrow(function () {
+        vm.start();
+        vm.clear();
+        vm.setCompatibilityMode(false);
+        vm.setTurboMode(false);
+        vm.loadProject(project);
+        vm.greenFlag();
+    });
+
+    // After two seconds, get playground data and stop
+    setTimeout(function () {
+        vm.getPlaygroundData();
+        vm.stopAll();
+    }, 2000);
+});