diff --git a/src/import/load-sound.js b/src/import/load-sound.js
index 548eb3276..639fcc2af 100644
--- a/src/import/load-sound.js
+++ b/src/import/load-sound.js
@@ -8,10 +8,10 @@ const log = require('../util/log');
  * @property {Buffer} data - sound data will be written here once loaded.
  * @param {!Asset} soundAsset - the asset loaded from storage.
  * @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
- * @param {Sprite} sprite - Scratch sprite to add sounds to.
+ * @param {SoundBank} soundBank - Scratch Audio SoundBank to add sounds to.
  * @returns {!Promise} - a promise which will resolve to the sound when ready.
  */
-const loadSoundFromAsset = function (sound, soundAsset, runtime, sprite) {
+const loadSoundFromAsset = function (sound, soundAsset, runtime, soundBank) {
     sound.assetId = soundAsset.assetId;
     if (!runtime.audioEngine) {
         log.error('No audio engine present; cannot load sound asset: ', sound.md5);
@@ -30,8 +30,8 @@ const loadSoundFromAsset = function (sound, soundAsset, runtime, sprite) {
         sound.rate = soundBuffer.sampleRate;
         sound.sampleCount = soundBuffer.length;
 
-        if (sprite.soundBank !== null) {
-            sprite.soundBank.addSoundPlayer(soundPlayer);
+        if (soundBank !== null) {
+            soundBank.addSoundPlayer(soundPlayer);
         }
 
         return sound;
@@ -44,10 +44,10 @@ const loadSoundFromAsset = function (sound, soundAsset, runtime, sprite) {
  * @property {string} md5 - the MD5 and extension of the sound to be loaded.
  * @property {Buffer} data - sound data will be written here once loaded.
  * @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
- * @param {Sprite} sprite - Scratch sprite to add sounds to.
+ * @param {SoundBank} soundBank - Scratch Audio SoundBank to add sounds to.
  * @returns {!Promise} - a promise which will resolve to the sound when ready.
  */
-const loadSound = function (sound, runtime, sprite) {
+const loadSound = function (sound, runtime, soundBank) {
     if (!runtime.storage) {
         log.error('No storage module present; cannot load sound asset: ', sound.md5);
         return Promise.resolve(sound);
@@ -61,7 +61,7 @@ const loadSound = function (sound, runtime, sprite) {
         runtime.storage.load(runtime.storage.AssetType.Sound, md5, ext)
     ).then(soundAsset => {
         sound.asset = soundAsset;
-        return loadSoundFromAsset(sound, soundAsset, runtime, sprite);
+        return loadSoundFromAsset(sound, soundAsset, runtime, soundBank);
     });
 };
 
diff --git a/src/serialization/sb2.js b/src/serialization/sb2.js
index 42a612b4c..b3dc19eef 100644
--- a/src/serialization/sb2.js
+++ b/src/serialization/sb2.js
@@ -399,9 +399,10 @@ const parseMonitorObject = (object, runtime, targets, extensions) => {
  * @param {!Runtime} runtime - Runtime object to load all structures into.
  * @param {boolean} topLevel - Whether this is the top-level object (stage).
  * @param {?object} zip - Optional zipped assets for local file import
- * @return {?{costumePromises:Array.<Promise>,soundPromises:Array.<Promise>,children:object}}
+ * @return {?{costumePromises:Array.<Promise>,soundPromises:Array.<Promise>,soundBank:SoundBank,children:object}}
  *   Object of arrays of promises and child objects for asset objects used in
- *   Sprites. null for unsupported objects.
+ *   Sprites. As well as a SoundBank for the sound assets. null for unsupported
+ *   objects.
  */
 const parseScratchAssets = function (object, runtime, topLevel, zip) {
     if (!object.hasOwnProperty('objName')) {
@@ -409,7 +410,12 @@ const parseScratchAssets = function (object, runtime, topLevel, zip) {
         return null;
     }
 
-    const assets = {costumePromises: [], soundPromises: [], children: []};
+    const assets = {
+        costumePromises: [],
+        soundPromises: [],
+        soundBank: runtime.audioEngine && runtime.audioEngine.createBank(),
+        children: []
+    };
 
     // Costumes from JSON.
     const costumePromises = assets.costumePromises;
@@ -457,7 +463,7 @@ const parseScratchAssets = function (object, runtime, topLevel, zip) {
         }
     }
     // Sounds from JSON
-    const soundPromises = assets.soundPromises;
+    const {soundBank, soundPromises} = assets;
     if (object.hasOwnProperty('sounds')) {
         for (let s = 0; s < object.sounds.length; s++) {
             const soundSource = object.sounds[s];
@@ -486,7 +492,10 @@ const parseScratchAssets = function (object, runtime, topLevel, zip) {
             // the file name of the sound should be the soundID (provided from the project.json)
             // followed by the file ext
             const assetFileName = `${soundSource.soundID}.${ext}`;
-            soundPromises.push(deserializeSound(sound, runtime, zip, assetFileName).then(() => sound));
+            soundPromises.push(
+                deserializeSound(sound, runtime, zip, assetFileName)
+                    .then(() => loadSound(sound, runtime, soundBank))
+            );
         }
     }
 
@@ -546,11 +555,7 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip,
     // Costumes from JSON.
     const costumePromises = assets.costumePromises;
     // Sounds from JSON
-    const soundPromises = assets.soundPromises;
-    for (let s = 0; s < soundPromises.length; s++) {
-        soundPromises[s] = soundPromises[s]
-            .then(sound => loadSound(sound, runtime, sprite));
-    }
+    const {soundBank, soundPromises} = assets;
 
     // Create the first clone, and load its run-state from JSON.
     const target = sprite.createClone(topLevel ? StageLayering.BACKGROUND_LAYER : StageLayering.SPRITE_LAYER);
@@ -738,6 +743,8 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip,
 
     Promise.all(soundPromises).then(sounds => {
         sprite.sounds = sounds;
+        // Make sure if soundBank is undefined, sprite.soundBank is then null.
+        sprite.soundBank = soundBank || null;
     });
 
     // The stage will have child objects; recursively process them.
diff --git a/src/serialization/sb3.js b/src/serialization/sb3.js
index 6aa592c73..2cafa5920 100644
--- a/src/serialization/sb3.js
+++ b/src/serialization/sb3.js
@@ -914,7 +914,7 @@ const parseScratchObject = function (object, runtime, extensions, zip) {
         // any translation that needs to happen will happen in the process
         // of building up the costume object into an sb3 format
         return deserializeSound(sound, runtime, zip)
-            .then(() => loadSound(sound, runtime, sprite));
+            .then(() => loadSound(sound, runtime, sprite.soundBank));
         // Only attempt to load the sound after the deserialization
         // process has been completed.
     });
diff --git a/src/sprites/sprite.js b/src/sprites/sprite.js
index 6874f91bf..07b94673c 100644
--- a/src/sprites/sprite.js
+++ b/src/sprites/sprite.js
@@ -153,7 +153,7 @@ class Sprite {
         newSprite.sounds = this.sounds.map(sound => {
             const newSound = Object.assign({}, sound);
             const soundAsset = sound.asset;
-            assetPromises.push(loadSoundFromAsset(newSound, soundAsset, this.runtime, newSprite));
+            assetPromises.push(loadSoundFromAsset(newSound, soundAsset, this.runtime, newSprite.soundBank));
             return newSound;
         });
 
diff --git a/src/virtual-machine.js b/src/virtual-machine.js
index e762ce196..b610d193e 100644
--- a/src/virtual-machine.js
+++ b/src/virtual-machine.js
@@ -678,7 +678,7 @@ class VirtualMachine extends EventEmitter {
     duplicateSound (soundIndex) {
         const originalSound = this.editingTarget.getSounds()[soundIndex];
         const clone = Object.assign({}, originalSound);
-        return loadSound(clone, this.runtime, this.editingTarget.sprite).then(() => {
+        return loadSound(clone, this.runtime, this.editingTarget.sprite.soundBank).then(() => {
             this.editingTarget.addSound(clone, soundIndex + 1);
             this.emitTargetsUpdate();
         });
@@ -723,7 +723,7 @@ class VirtualMachine extends EventEmitter {
         const target = optTargetId ? this.runtime.getTargetById(optTargetId) :
             this.editingTarget;
         if (target) {
-            return loadSound(soundObject, this.runtime, target.sprite).then(() => {
+            return loadSound(soundObject, this.runtime, target.sprite.soundBank).then(() => {
                 target.addSound(soundObject);
                 this.emitTargetsUpdate();
             });
@@ -1250,7 +1250,7 @@ class VirtualMachine extends EventEmitter {
         const originalSound = this.editingTarget.getSounds()[soundIndex];
         const clone = Object.assign({}, originalSound);
         const target = this.runtime.getTargetById(targetId);
-        return loadSound(clone, this.runtime, target.sprite).then(() => {
+        return loadSound(clone, this.runtime, target.sprite.soundBank).then(() => {
             if (target) {
                 target.addSound(clone);
                 this.emitTargetsUpdate();