diff --git a/package.json b/package.json
index d615d01ba6795d37bbdb2462e796180450f32006..d293d00de07edb67468d04e1030c09b769c83455 100644
--- a/package.json
+++ b/package.json
@@ -87,6 +87,7 @@
     "scratch-storage": "^0.2.0",
     "scratch-vm": "latest",
     "selenium-webdriver": "^3.5.0",
+    "startaudiocontext": "1.2.1",
     "style-loader": "^0.18.0",
     "svg-to-image": "1.1.3",
     "svg-url-loader": "2.1.0",
diff --git a/src/containers/sound-editor.jsx b/src/containers/sound-editor.jsx
index 67c4b1b5fdab808d0920decf7a2becd240a8d43f..4a1b98b565bd587bcae5e6e2414f4ee3e763c5cd 100644
--- a/src/containers/sound-editor.jsx
+++ b/src/containers/sound-editor.jsx
@@ -112,9 +112,9 @@ class SoundEditor extends React.Component {
     }
     handleEffect (name) {
         const effects = new AudioEffects(this.audioBufferPlayer.buffer, name);
-        effects.process().then(newBuffer => {
-            const samples = newBuffer.getChannelData(0);
-            const sampleRate = newBuffer.sampleRate;
+        effects.process(({renderedBuffer}) => {
+            const samples = renderedBuffer.getChannelData(0);
+            const sampleRate = renderedBuffer.sampleRate;
             this.submitNewSamples(samples, sampleRate);
             this.handlePlay();
         });
diff --git a/src/lib/audio/audio-effects.js b/src/lib/audio/audio-effects.js
index 187c6ce6b9be659d404fc72e13bab33bcc413fd3..ead04bf504550f85c9837f3acb1c38adf18835d6 100644
--- a/src/lib/audio/audio-effects.js
+++ b/src/lib/audio/audio-effects.js
@@ -38,7 +38,7 @@ class AudioEffects {
             buffer.getChannelData(0).reverse();
             break;
         }
-
+        const OfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;
         this.audioContext = new OfflineAudioContext(1, sampleCount, buffer.sampleRate);
         this.buffer = buffer;
         this.source = this.audioContext.createBufferSource();
@@ -46,7 +46,7 @@ class AudioEffects {
         this.source.playbackRate.value = playbackRate;
         this.name = name;
     }
-    process () {
+    process (done) {
         // Some effects need to use more nodes and must expose an input and output
         let input;
         let output;
@@ -75,7 +75,8 @@ class AudioEffects {
 
         this.source.start();
 
-        return this.audioContext.startRendering();
+        this.audioContext.startRendering();
+        this.audioContext.oncomplete = done;
     }
 }
 
diff --git a/src/lib/audio/shared-audio-context.js b/src/lib/audio/shared-audio-context.js
index f125aa722c72fd13682aecbcc24793c484ec53be..64749f93e79165a34225bf28f228f6d34e872825 100644
--- a/src/lib/audio/shared-audio-context.js
+++ b/src/lib/audio/shared-audio-context.js
@@ -1,5 +1,9 @@
+import StartAudioContext from 'startaudiocontext';
+
 const AUDIO_CONTEXT = new (window.AudioContext || window.webkitAudioContext)();
 
+StartAudioContext(AUDIO_CONTEXT);
+
 /**
  * Wrap browser AudioContext because we shouldn't create more than one
  * @return {AudioContext} The singleton AudioContext
diff --git a/test/__mocks__/audio-effects.js b/test/__mocks__/audio-effects.js
index 70a77ee9a6394897f962a1ba465a3944313ce268..b8a4c6994b8e86f7859730464072b3eb09040bce 100644
--- a/test/__mocks__/audio-effects.js
+++ b/test/__mocks__/audio-effects.js
@@ -13,11 +13,9 @@ export default class MockAudioEffects {
     constructor (buffer, name) {
         this.buffer = buffer;
         this.name = name;
-        this._mockResult = {};
-        this._bufferPromise = new Promise(resolve => { // eslint-disable-line no-undef
-            this._finishProcessing = newBuffer => resolve(newBuffer);
+        this.process = jest.fn(done => {
+            this._finishProcessing = renderedBuffer => done({renderedBuffer});
         });
-        this.process = jest.fn(() => this._bufferPromise);
         MockAudioEffects.instance = this;
     }
 }
diff --git a/test/unit/containers/sound-editor.test.jsx b/test/unit/containers/sound-editor.test.jsx
index 819e38149adfb55e7f90c632aef71caa600b51c0..325488a250249f9a426926fb56ab367b519b4cae 100644
--- a/test/unit/containers/sound-editor.test.jsx
+++ b/test/unit/containers/sound-editor.test.jsx
@@ -111,7 +111,7 @@ describe('Sound Editor Container', () => {
         expect(vm.renameSound).toHaveBeenCalledWith(soundIndex, 'hello');
     });
 
-    test('it handles an effect by submitting the result and playing', done => {
+    test('it handles an effect by submitting the result and playing', () => {
         const wrapper = mountWithIntl(
             <SoundEditor
                 soundIndex={soundIndex}
@@ -121,11 +121,8 @@ describe('Sound Editor Container', () => {
         const component = wrapper.find(SoundEditorComponent);
         component.props().onReverse(); // Could be any of the effects, just testing the end result
         mockAudioEffects.instance._finishProcessing(soundBuffer);
-        process.nextTick(() => {
-            expect(mockAudioBufferPlayer.instance.play).toHaveBeenCalled();
-            expect(vm.updateSoundBuffer).toHaveBeenCalled();
-            done();
-        });
+        expect(mockAudioBufferPlayer.instance.play).toHaveBeenCalled();
+        expect(vm.updateSoundBuffer).toHaveBeenCalled();
     });
 
     test('it handles reverse effect correctly', () => {