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

Merge pull request #1383 from paulkaplan/fix-safari-audio

Fix several safari audio issues
parents 9163f73a 85f2aeed
No related branches found
No related tags found
No related merge requests found
......@@ -16,7 +16,7 @@ class SoundEditor extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'copyCurrentSamples',
'copyCurrentBuffer',
'handleStoppedPlaying',
'handleChangeName',
'handlePlay',
......@@ -70,7 +70,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.copyCurrentSamples());
this.undoStack.push(this.copyCurrentBuffer());
}
this.resetState(samples, sampleRate);
this.props.onUpdateSoundBuffer(
......@@ -102,12 +102,12 @@ class SoundEditor extends React.Component {
if (this.state.trimStart === null && this.state.trimEnd === null) {
this.setState({trimEnd: 0.95, trimStart: 0.05});
} else {
const samples = this.copyCurrentSamples();
const {samples, sampleRate} = this.copyCurrentBuffer();
const sampleCount = samples.length;
const startIndex = Math.floor(this.state.trimStart * sampleCount);
const endIndex = Math.floor(this.state.trimEnd * sampleCount);
const clippedSamples = samples.slice(startIndex, endIndex);
this.submitNewSamples(clippedSamples, this.props.sampleRate);
this.submitNewSamples(clippedSamples, sampleRate);
}
}
handleUpdateTrimEnd (trimEnd) {
......@@ -119,9 +119,12 @@ class SoundEditor extends React.Component {
effectFactory (name) {
return () => this.handleEffect(name);
}
copyCurrentSamples () {
copyCurrentBuffer () {
// Cannot reliably use props.samples because it gets detached by Firefox
return this.audioBufferPlayer.buffer.getChannelData(0);
return {
samples: this.audioBufferPlayer.buffer.getChannelData(0),
sampleRate: this.audioBufferPlayer.buffer.sampleRate
};
}
handleEffect (name) {
const effects = new AudioEffects(this.audioBufferPlayer.buffer, name);
......@@ -133,18 +136,18 @@ class SoundEditor extends React.Component {
});
}
handleUndo () {
this.redoStack.push(this.copyCurrentSamples());
const samples = this.undoStack.pop();
this.redoStack.push(this.copyCurrentBuffer());
const {samples, sampleRate} = this.undoStack.pop();
if (samples) {
this.submitNewSamples(samples, this.props.sampleRate, true);
this.submitNewSamples(samples, sampleRate, true);
this.handlePlay();
}
}
handleRedo () {
const samples = this.redoStack.pop();
const {samples, sampleRate} = this.redoStack.pop();
if (samples) {
this.undoStack.push(this.copyCurrentSamples());
this.submitNewSamples(samples, this.props.sampleRate, true);
this.undoStack.push(this.copyCurrentBuffer());
this.submitNewSamples(samples, sampleRate, true);
this.handlePlay();
}
}
......
......@@ -45,7 +45,13 @@ class AudioBufferPlayer {
stop () {
if (this.source) {
this.source.onended = null; // Do not call onEnded callback if manually stopped
this.source.stop();
try {
this.source.stop();
} catch (e) {
// This is probably Safari, which dies when you call stop more than once
// which the spec says is allowed: https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode
console.log('Caught error while stopping buffer source node.'); // eslint-disable-line no-console
}
}
}
}
......
......@@ -38,8 +38,14 @@ class AudioEffects {
buffer.getChannelData(0).reverse();
break;
}
const OfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;
this.audioContext = new OfflineAudioContext(1, sampleCount, buffer.sampleRate);
if (window.OfflineAudioContext) {
this.audioContext = new window.OfflineAudioContext(1, sampleCount, buffer.sampleRate);
} else {
// Need to use webkitOfflineAudioContext, which doesn't support all sample rates.
// Resample by adjusting sample count to make room and set offline context to desired sample rate.
const sampleScale = 44100 / buffer.sampleRate;
this.audioContext = new window.webkitOfflineAudioContext(1, sampleScale * sampleCount, 44100);
}
this.buffer = buffer;
this.source = this.audioContext.createBufferSource();
this.source.buffer = this.buffer;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment