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', () => {