Skip to content

Commit 03d9f8f

Browse files
authored
Merge pull request scratchfoundation#5169 from LLK/recording-glitch
Use a larger buffer size for recording to prevent glitching
2 parents 5d006cf + 2b9550f commit 03d9f8f

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

src/components/record-modal/record-modal.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
border: 1px solid $ui-black-transparent;
2121
border-radius: 5px;
2222
padding: 3px;
23-
23+
/* Force these to be on their own render layer because they update often */
24+
transform: translateZ(0);
2425
}
26+
2527
.meter-container {
2628
margin-right: 5px;
2729
height: 180px;

src/containers/recording-step.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ class RecordingStep extends React.Component {
4444
alert(this.props.intl.formatMessage(messages.alertMsg)); // eslint-disable-line no-alert
4545
}
4646
handleLevelUpdate (level) {
47-
this.setState({level});
48-
if (this.props.recording) {
49-
this.setState({levels: (this.state.levels || []).concat([level])});
50-
}
47+
this.setState({
48+
level: level,
49+
levels: this.props.recording ? (this.state.levels || []).concat([level]) : this.state.levels
50+
});
5151
}
5252
handleRecord () {
5353
this.audioRecorder.startRecording();

src/lib/audio/audio-recorder.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import 'get-float-time-domain-data';
22
import getUserMedia from 'get-user-media-promise';
33
import SharedAudioContext from './shared-audio-context.js';
4-
import {computeRMS} from './audio-util.js';
4+
import {computeRMS, computeChunkedRMS} from './audio-util.js';
55

66
class AudioRecorder {
77
constructor () {
88
this.audioContext = new SharedAudioContext();
9-
this.bufferLength = 1024;
9+
this.bufferLength = 8192;
1010

1111
this.userMediaStream = null;
1212
this.mediaStreamSource = null;
@@ -51,7 +51,7 @@ class AudioRecorder {
5151
this.userMediaStream = userMediaStream;
5252
this.mediaStreamSource = this.audioContext.createMediaStreamSource(userMediaStream);
5353
this.sourceNode = this.audioContext.createGain();
54-
this.scriptProcessorNode = this.audioContext.createScriptProcessor(this.bufferLength, 2, 2);
54+
this.scriptProcessorNode = this.audioContext.createScriptProcessor(this.bufferLength, 1, 1);
5555

5656
this.scriptProcessorNode.onaudioprocess = processEvent => {
5757
if (this.recording && !this.disposed) {
@@ -68,9 +68,9 @@ class AudioRecorder {
6868

6969
const update = () => {
7070
if (this.disposed) return;
71-
requestAnimationFrame(update);
7271
this.analyserNode.getFloatTimeDomainData(dataArray);
7372
onUpdate(computeRMS(dataArray));
73+
requestAnimationFrame(update);
7474
};
7575

7676
requestAnimationFrame(update);
@@ -83,7 +83,16 @@ class AudioRecorder {
8383
}
8484

8585
stop () {
86-
const chunkLevels = this.buffers.map(buffer => computeRMS(buffer));
86+
const buffer = new Float32Array(this.buffers.length * this.bufferLength);
87+
88+
let offset = 0;
89+
for (let i = 0; i < this.buffers.length; i++) {
90+
const bufferChunk = this.buffers[i];
91+
buffer.set(bufferChunk, offset);
92+
offset += bufferChunk.length;
93+
}
94+
95+
const chunkLevels = computeChunkedRMS(buffer);
8796
const maxRMS = Math.max.apply(null, chunkLevels);
8897
const threshold = maxRMS / 8;
8998

@@ -105,15 +114,6 @@ class AudioRecorder {
105114
trimEnd = 1;
106115
}
107116

108-
const buffer = new Float32Array(this.buffers.length * this.bufferLength);
109-
110-
let offset = 0;
111-
for (let i = 0; i < this.buffers.length; i++) {
112-
const bufferChunk = this.buffers[i];
113-
buffer.set(bufferChunk, offset);
114-
offset += bufferChunk.length;
115-
}
116-
117117
return {
118118
levels: chunkLevels,
119119
samples: buffer,

0 commit comments

Comments
 (0)