@@ -19,6 +19,7 @@ import encoderPath from 'opus-recorder/dist/encoderWorker.min.js';
1919import { MatrixClient } from "matrix-js-sdk/src/client" ;
2020import CallMediaHandler from "../CallMediaHandler" ;
2121import { SimpleObservable } from "matrix-widget-api" ;
22+ import { percentageOf } from "../utils/numbers" ;
2223
2324const CHANNELS = 1 ; // stereo isn't important
2425const SAMPLE_RATE = 48000 ; // 48khz is what WebRTC uses. 12khz is where we lose quality.
@@ -133,23 +134,18 @@ export class VoiceRecorder {
133134 // The time domain is the input to the FFT, which means we use an array of the same
134135 // size. The time domain is also known as the audio waveform. We're ignoring the
135136 // output of the FFT here (frequency data) because we're not interested in it.
136- //
137- // We use bytes out of the analyser because floats have weird precision problems
138- // and are slightly more difficult to work with. The bytes are easy to work with,
139- // which is why we pick them (they're also more precise, but we care less about that).
140- const data = new Uint8Array ( this . recorderFFT . fftSize ) ;
141- this . recorderFFT . getByteTimeDomainData ( data ) ;
142-
143- // Because we're dealing with a uint array we need to do math a bit differently.
144- // If we just `Array.from()` the uint array, we end up with 1s and 0s, which aren't
145- // what we're after. Instead, we have to use a bit of manual looping to correctly end
146- // up with the right values
137+ const data = new Float32Array ( this . recorderFFT . fftSize ) ;
138+ this . recorderFFT . getFloatTimeDomainData ( data ) ;
139+
140+ // We can't just `Array.from()` the array because we're dealing with 32bit floats
141+ // and the built-in function won't consider that when converting between numbers.
142+ // However, the runtime will convert the float32 to a float64 during the math operations
143+ // which is why the loop works below. Note that a `.map()` call also doesn't work
144+ // and will instead return a Float32Array still.
147145 const translatedData : number [ ] = [ ] ;
148146 for ( let i = 0 ; i < data . length ; i ++ ) {
149- // All we're doing here is inverting the amplitude and putting the metric somewhere
150- // between zero and one. Without the inversion, lower values are "louder", which is
151- // not super helpful.
152- translatedData . push ( 1 - ( data [ i ] / 128.0 ) ) ;
147+ // We're clamping the values so we can do that math operation mentioned above.
148+ translatedData . push ( percentageOf ( data [ i ] , 0 , 1 ) ) ;
153149 }
154150
155151 this . observable . update ( {
0 commit comments