diff --git a/src/containers/sound-editor.jsx b/src/containers/sound-editor.jsx index 5c5a57b54992e5f7adedecef66f7df1304b490cd..61bf712248db07bcdba1a3c8a142a590f468c2d6 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 e4470b2b38700a124c956d86a301f412b15e2c1a..199b66af93d4e01cefeba9dced36cf35610408fc 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 f8a32e5c9eb78d03d2330b2142fde2448562360f..01753b2ac145c84db051770fd005f337c9366aaf 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); + }); +});