Skip to content
Snippets Groups Projects
Unverified Commit 4d136c72 authored by Paul Kaplan's avatar Paul Kaplan Committed by GitHub
Browse files

Merge pull request #4339 from paulkaplan/prevent-large-sounds

Prevent creating sounds that are too big in the sound editor
parents 50a95419 6fa6b027
Branches
Tags
No related merge requests found
......@@ -5,7 +5,7 @@ import WavEncoder from 'wav-encoder';
import {connect} from 'react-redux';
import {computeChunkedRMS} from '../lib/audio/audio-util.js';
import {computeChunkedRMS, SOUND_BYTE_LIMIT} from '../lib/audio/audio-util.js';
import AudioEffects from '../lib/audio/audio-effects.js';
import SoundEditorComponent from '../components/sound-editor/sound-editor.jsx';
import AudioBufferPlayer from '../lib/audio/audio-buffer-player.js';
......@@ -65,13 +65,6 @@ class SoundEditor extends React.Component {
});
}
submitNewSamples (samples, sampleRate, skipUndo) {
if (!skipUndo) {
this.redoStack = [];
if (this.undoStack.length >= UNDO_STACK_SIZE) {
this.undoStack.shift(); // Drop the first element off the array
}
this.undoStack.push(this.copyCurrentBuffer());
}
// Encode the new sound into a wav so that it can be stored
let wavBuffer = null;
try {
......@@ -79,18 +72,38 @@ class SoundEditor extends React.Component {
sampleRate: sampleRate,
channelData: [samples]
});
if (wavBuffer.byteLength > SOUND_BYTE_LIMIT) {
// Cancel the sound update by setting to null
wavBuffer = null;
log.error(`Refusing to encode sound larger than ${SOUND_BYTE_LIMIT} bytes`);
}
} catch (e) {
// This error state is mostly for the mock sounds used during testing.
// Any incorrect sound buffer trying to get interpretd as a Wav file
// should yield this error.
// This can also happen if the sound is too be allocated in memory.
log.error(`Encountered error while trying to encode sound update: ${e}`);
}
this.resetState(samples, sampleRate);
this.props.vm.updateSoundBuffer(
this.props.soundIndex,
this.audioBufferPlayer.buffer,
wavBuffer ? new Uint8Array(wavBuffer) : new Uint8Array());
// Do not submit sound if it could not be encoded (i.e. if too large)
if (wavBuffer) {
if (!skipUndo) {
this.redoStack = [];
if (this.undoStack.length >= UNDO_STACK_SIZE) {
this.undoStack.shift(); // Drop the first element off the array
}
this.undoStack.push(this.copyCurrentBuffer());
}
this.resetState(samples, sampleRate);
this.props.vm.updateSoundBuffer(
this.props.soundIndex,
this.audioBufferPlayer.buffer,
new Uint8Array(wavBuffer));
return true; // Update succeeded
}
return false; // Update failed
}
handlePlay () {
this.audioBufferPlayer.play(
......@@ -147,8 +160,8 @@ class SoundEditor extends React.Component {
effects.process(({renderedBuffer}) => {
const samples = renderedBuffer.getChannelData(0);
const sampleRate = renderedBuffer.sampleRate;
this.submitNewSamples(samples, sampleRate);
this.handlePlay();
const success = this.submitNewSamples(samples, sampleRate);
if (success) this.handlePlay();
});
}
handleUndo () {
......
const SOUND_BYTE_LIMIT = 10 * 1000 * 1000; // 10mb
const computeRMS = function (samples, scaling = 0.55) {
if (samples.length === 0) return 0;
// Calculate RMS, adapted from https://github.com/Tonejs/Tone.js/blob/master/Tone/component/Meter.js#L88
......@@ -23,5 +25,6 @@ const computeChunkedRMS = function (samples, chunkSize = 1024) {
export {
computeRMS,
computeChunkedRMS
computeChunkedRMS,
SOUND_BYTE_LIMIT
};
......@@ -3,7 +3,8 @@ export default class MockAudioBufferPlayer {
this.samples = samples;
this.sampleRate = sampleRate;
this.buffer = {
getChannelData: jest.fn(() => samples)
getChannelData: jest.fn(() => samples),
sampleRate: sampleRate
};
this.play = jest.fn((trimStart, trimEnd, onUpdate) => {
this.onUpdate = onUpdate;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment