Merge pull request #4339 from paulkaplan/prevent-large-sounds
Prevent creating sounds that are too big in the sound editor
This commit is contained in:
3 files changed
+34
-17
No files matched your search
@@ -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 () {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
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;
|
||||
|
||||
Reference in new issue
Block a user