more calibration and VU diddling
This commit is contained in:
parent
c157a656ea
commit
c15a1f99df
2 changed files with 55 additions and 30 deletions
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import Modal from "react-modal";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { RootState } from "../rootReducer";
|
||||
|
@ -7,42 +7,69 @@ import * as MixerState from "./state";
|
|||
import { VUMeter } from "./VUMeter";
|
||||
|
||||
export function MicCalibrationModal() {
|
||||
const state = useSelector(
|
||||
(state: RootState) => state.mixer.mic.calibration
|
||||
);
|
||||
const state = useSelector((state: RootState) => state.mixer.mic);
|
||||
const rafRef = useRef<number | null>(null);
|
||||
const [peak, setPeak] = useState(-Infinity);
|
||||
|
||||
const animate = () => {
|
||||
if (state) {
|
||||
if (state.calibration) {
|
||||
const result = MixerState.getMicAnalysis();
|
||||
console.log(result);
|
||||
setPeak(result);
|
||||
requestAnimationFrame(animate);
|
||||
rafRef.current = requestAnimationFrame(animate);
|
||||
} else if (rafRef.current !== null) {
|
||||
cancelAnimationFrame(rafRef.current);
|
||||
rafRef.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
requestAnimationFrame(animate);
|
||||
}, [state]);
|
||||
if (state.calibration) {
|
||||
rafRef.current = requestAnimationFrame(animate);
|
||||
} else if (rafRef.current !== null) {
|
||||
cancelAnimationFrame(rafRef.current);
|
||||
rafRef.current = null;
|
||||
}
|
||||
}, [state.calibration]);
|
||||
const dispatch = useDispatch();
|
||||
return (
|
||||
<Modal
|
||||
isOpen={state}
|
||||
isOpen={state.calibration}
|
||||
onRequestClose={() => dispatch(MixerState.stopMicCalibration())}
|
||||
>
|
||||
{state !== null && (
|
||||
{state.calibration && (
|
||||
<>
|
||||
<b>
|
||||
Speak into the microphone at a normal volume. Adjust the
|
||||
gain slider until the bar below is green when you're speaking.
|
||||
gain slider until the bar below is green when you're
|
||||
speaking.
|
||||
</b>
|
||||
<div>
|
||||
<VUMeter
|
||||
width={400}
|
||||
height={40}
|
||||
value={peak}
|
||||
range={[-70, 0]}
|
||||
greenRange={[-3.5, -1.5]}
|
||||
greenRange={[-20, -7]}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type="range"
|
||||
min={1 / 10}
|
||||
max={3}
|
||||
step={0.05}
|
||||
value={state.gain}
|
||||
onChange={e =>
|
||||
dispatch(
|
||||
MixerState.setMicLevels({
|
||||
volume: parseFloat(e.target.value),
|
||||
gain: parseFloat(e.target.value)
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
<b>{state.gain.toFixed(1)}</b>
|
||||
</div>
|
||||
<button
|
||||
onClick={() =>
|
||||
dispatch(MixerState.stopMicCalibration())
|
||||
|
|
|
@ -14,8 +14,6 @@ import { RootState } from "../rootReducer";
|
|||
import WaveSurfer from "wavesurfer.js";
|
||||
import { createLoudnessMeasurement } from "./loudness";
|
||||
|
||||
console.log(Between);
|
||||
|
||||
const audioContext = new AudioContext();
|
||||
const wavesurfers: WaveSurfer[] = [];
|
||||
const playerGainTweens: Array<{
|
||||
|
@ -283,6 +281,8 @@ const mixerState = createSlice({
|
|||
|
||||
export default mixerState.reducer;
|
||||
|
||||
export const { setMicLevels } = mixerState.actions;
|
||||
|
||||
export const load = (
|
||||
player: number,
|
||||
item: PlanItem | Track | AuxItem
|
||||
|
@ -649,8 +649,6 @@ export const openMicrophone = (micID: string): AppThunk => async (
|
|||
.connect(micGain)
|
||||
.connect(micCompressor)
|
||||
.connect(finalCompressor);
|
||||
// TODO remove this
|
||||
micCompressor.connect(audioContext.destination);
|
||||
dispatch(mixerState.actions.micOpen(micID));
|
||||
};
|
||||
|
||||
|
@ -689,6 +687,7 @@ export const startMicCalibration = (): AppThunk => async (
|
|||
input = micCompressor!;
|
||||
}
|
||||
analyser = audioContext.createAnalyser();
|
||||
analyser.fftSize = 8192;
|
||||
input.connect(analyser);
|
||||
};
|
||||
|
||||
|
@ -701,15 +700,14 @@ export function getMicAnalysis() {
|
|||
if (!float) {
|
||||
float = new Float32Array(analyser.fftSize);
|
||||
}
|
||||
analyser.getFloatFrequencyData(float);
|
||||
let peak = -Infinity;
|
||||
analyser.getFloatTimeDomainData(float);
|
||||
let sumOfSquares = 0;
|
||||
let peak = 0;
|
||||
for (let i = 0; i < float.length; i++) {
|
||||
const dbFS = float[i];
|
||||
if (dbFS > peak && dbFS !== 0) {
|
||||
peak = dbFS;
|
||||
peak = Math.max(peak, float[i]**2)
|
||||
sumOfSquares += float[i]**2;
|
||||
}
|
||||
}
|
||||
return peak;
|
||||
return 10 * Math.log10(peak);
|
||||
}
|
||||
|
||||
export const stopMicCalibration = (): AppThunk => (dispatch, getState) => {
|
||||
|
|
Loading…
Reference in a new issue