From 4deb919ec6822d4c7ec90169f2726bd4e67b6dae Mon Sep 17 00:00:00 2001
From: Paul Kaplan <pkaplan@media.mit.edu>
Date: Mon, 8 Jan 2018 11:17:52 -0500
Subject: [PATCH] Fix firefox detached buffer issues

---
 src/containers/sound-editor.jsx       | 11 ++++++++---
 test/__mocks__/audio-buffer-player.js |  3 +++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/containers/sound-editor.jsx b/src/containers/sound-editor.jsx
index 4be944a4a..49e2bff68 100644
--- a/src/containers/sound-editor.jsx
+++ b/src/containers/sound-editor.jsx
@@ -15,6 +15,7 @@ class SoundEditor extends React.Component {
     constructor (props) {
         super(props);
         bindAll(this, [
+            'copyCurrentSamples',
             'handleStoppedPlaying',
             'handleChangeName',
             'handlePlay',
@@ -67,7 +68,7 @@ class SoundEditor extends React.Component {
             if (this.undoStack.length >= UNDO_STACK_SIZE) {
                 this.undoStack.shift(); // Drop the first element off the array
             }
-            this.undoStack.push(this.props.samples.slice(0));
+            this.undoStack.push(this.copyCurrentSamples());
         }
         this.resetState(samples, sampleRate);
         this.props.onUpdateSoundBuffer(
@@ -115,6 +116,10 @@ class SoundEditor extends React.Component {
     effectFactory (name) {
         return () => this.handleEffect(name);
     }
+    copyCurrentSamples () {
+        // Cannot reliably use props.samples because it gets detached by Firefox
+        return this.audioBufferPlayer.buffer.getChannelData(0);
+    }
     handleEffect (name) {
         const effects = new AudioEffects(this.audioBufferPlayer.buffer, name);
         effects.process(({renderedBuffer}) => {
@@ -125,7 +130,7 @@ class SoundEditor extends React.Component {
         });
     }
     handleUndo () {
-        this.redoStack.push(this.props.samples.slice(0));
+        this.redoStack.push(this.copyCurrentSamples());
         const samples = this.undoStack.pop();
         if (samples) {
             this.submitNewSamples(samples, this.props.sampleRate, true);
@@ -135,7 +140,7 @@ class SoundEditor extends React.Component {
     handleRedo () {
         const samples = this.redoStack.pop();
         if (samples) {
-            this.undoStack.push(this.props.samples.slice(0));
+            this.undoStack.push(this.copyCurrentSamples());
             this.submitNewSamples(samples, this.props.sampleRate, true);
             this.handlePlay();
         }
diff --git a/test/__mocks__/audio-buffer-player.js b/test/__mocks__/audio-buffer-player.js
index dabf72bc3..476b2b649 100644
--- a/test/__mocks__/audio-buffer-player.js
+++ b/test/__mocks__/audio-buffer-player.js
@@ -2,6 +2,9 @@ export default class MockAudioBufferPlayer {
     constructor (samples, sampleRate) {
         this.samples = samples;
         this.sampleRate = sampleRate;
+        this.buffer = {
+            getChannelData: jest.fn(() => samples)
+        };
         this.play = jest.fn((trimStart, trimEnd, onUpdate) => {
             this.onUpdate = onUpdate;
         });
-- 
GitLab