From bb80fa49acf74411682ed2f0a010749c779b0cbf Mon Sep 17 00:00:00 2001
From: Eric Rosenbaum <eric.rosenbaum@gmail.com>
Date: Wed, 18 Dec 2019 15:19:47 -0500
Subject: [PATCH] Move backupDownSampler into util and add tests

---
 src/containers/sound-editor.jsx   | 18 +++---------------
 src/lib/audio/audio-util.js       | 17 ++++++++++++++++-
 test/unit/util/audio-util.test.js | 22 +++++++++++++++++++++-
 3 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/src/containers/sound-editor.jsx b/src/containers/sound-editor.jsx
index 5c5a57b54..61bf71224 100644
--- a/src/containers/sound-editor.jsx
+++ b/src/containers/sound-editor.jsx
@@ -9,7 +9,8 @@ import {connect} from 'react-redux';
 import {
     computeChunkedRMS,
     encodeAndAddSoundToVM,
-    downsampleIfNeeded
+    downsampleIfNeeded,
+    backupDownSampler
 } from '../lib/audio/audio-util.js';
 import AudioEffects from '../lib/audio/audio-effects.js';
 import SoundEditorComponent from '../components/sound-editor/sound-editor.jsx';
@@ -24,7 +25,6 @@ class SoundEditor extends React.Component {
     constructor (props) {
         super(props);
         bindAll(this, [
-            'backupDownSampler',
             'copy',
             'copyCurrentBuffer',
             'handleCopyToNew',
@@ -338,7 +338,7 @@ class SoundEditor extends React.Component {
                     offlineContext = new window.webkitOfflineAudioContext(1, newLength, newRate);
                 } catch {
                     if (newRate === (buffer.sampleRate / 2)) {
-                        return resolve(this.backupDownSampler(buffer, newRate));
+                        return resolve(backupDownSampler(buffer, newRate));
                     }
                     return reject('Could not resample');
                 }
@@ -360,18 +360,6 @@ class SoundEditor extends React.Component {
             };
         });
     }
-    backupDownSampler (buffer, newRate) {
-        log.warn(`Using backup down sampler for conversion from ${buffer.sampleRate} to ${newRate}`);
-        const newLength = Math.floor(buffer.samples.length / 2);
-        const newSamples = new Float32Array(newLength);
-        for (let i = 0; i < newLength; i++) {
-            newSamples[i] = buffer.samples[i * 2];
-        }
-        return {
-            samples: newSamples,
-            sampleRate: newRate
-        };
-    }
     paste () {
         // If there's no selection, paste at the end of the sound
         const {samples} = this.copyCurrentBuffer();
diff --git a/src/lib/audio/audio-util.js b/src/lib/audio/audio-util.js
index e4470b2b3..199b66af9 100644
--- a/src/lib/audio/audio-util.js
+++ b/src/lib/audio/audio-util.js
@@ -1,4 +1,5 @@
 import WavEncoder from 'wav-encoder';
+import log from '../log.js';
 
 const SOUND_BYTE_LIMIT = 10 * 1000 * 1000; // 10mb
 
@@ -75,9 +76,23 @@ const downsampleIfNeeded = (samples, sampleRate, resampler) => {
     return Promise.reject('Sound too large to save, refusing to edit');
 };
 
+const backupDownSampler = (buffer, newRate) => {
+    log.warn(`Using backup down sampler for conversion from ${buffer.sampleRate} to ${newRate}`);
+    const newLength = Math.floor(buffer.samples.length / 2);
+    const newSamples = new Float32Array(newLength);
+    for (let i = 0; i < newLength; i++) {
+        newSamples[i] = buffer.samples[i * 2];
+    }
+    return {
+        samples: newSamples,
+        sampleRate: newRate
+    };
+};
+
 export {
     computeRMS,
     computeChunkedRMS,
     encodeAndAddSoundToVM,
-    downsampleIfNeeded
+    downsampleIfNeeded,
+    backupDownSampler
 };
diff --git a/test/unit/util/audio-util.test.js b/test/unit/util/audio-util.test.js
index f8a32e5c9..01753b2ac 100644
--- a/test/unit/util/audio-util.test.js
+++ b/test/unit/util/audio-util.test.js
@@ -1,4 +1,9 @@
-import {computeRMS, computeChunkedRMS, downsampleIfNeeded} from '../../../src/lib/audio/audio-util';
+import {
+    computeRMS,
+    computeChunkedRMS,
+    downsampleIfNeeded,
+    backupDownSampler
+} from '../../../src/lib/audio/audio-util';
 
 describe('computeRMS', () => {
     test('returns 0 when given no samples', () => {
@@ -75,3 +80,18 @@ describe('downsampleIfNeeded', () => {
         }
     });
 });
+
+describe('backupDownSampler', () => {
+    const buffer = {
+        samples: [1, 0, 1, 0, 1, 0, 1],
+        sampleRate: 2
+    };
+    test('result is half the length', () => {
+        const {samples} = backupDownSampler(buffer, 1);
+        expect(samples.length).toEqual(Math.floor(buffer.samples.length / 2));
+    });
+    test('result contains only even-index items', () => {
+        const {samples} = backupDownSampler(buffer, 1);
+        expect(samples.every(v => v === 1)).toBe(true);
+    });
+});
-- 
GitLab