From 5ada2d648ffdaa0332541f0e6c966975cccdfe32 Mon Sep 17 00:00:00 2001 From: Robin Fernandes Date: Wed, 9 Aug 2023 10:41:10 +1000 Subject: [PATCH] Expose all biquad filter options. Make timeseries audio use shared biquad filter component. --- src/components/BiquadFilter.tsx | 47 ++++++++++++++++--- src/components/TimeSeriesUI.tsx | 82 ++------------------------------- 2 files changed, 44 insertions(+), 85 deletions(-) diff --git a/src/components/BiquadFilter.tsx b/src/components/BiquadFilter.tsx index 75f5be3..ffe7a77 100644 --- a/src/components/BiquadFilter.tsx +++ b/src/components/BiquadFilter.tsx @@ -1,8 +1,9 @@ +/* eslint-disable react/jsx-no-target-blank */ import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; //@ts-ignore -import { MenuItem, TextField, Tooltip } from '@mui/material'; +import { Link, MenuItem, TextField, Tooltip } from '@mui/material'; import { SmallTextField } from './SmallTextField'; import { useState } from 'react'; import { createAudioBufferCopy } from '../utils/utils'; @@ -16,7 +17,8 @@ export function BiquadFilter({ unfilteredAudioBuffer, updateAudioBuffer }: Biqua const [biquadFilterFreq, setBiquadFilterFreq] = useState(800); const [biquadFilterQ, setBiquadFilterQ] = useState(0.5); - const [biquadFilterType, setBiquadFilterType] = useState<"lowpass" | "highpass" | "bandpass">("lowpass"); + const [biquadFilterGain, setBiquadFilterGain] = useState(0); + const [biquadFilterType, setBiquadFilterType] = useState("lowpass"); const handleResetFilter = () => { @@ -41,6 +43,7 @@ export function BiquadFilter({ unfilteredAudioBuffer, updateAudioBuffer }: Biqua biquadFilter.type = biquadFilterType; biquadFilter.frequency.value = biquadFilterFreq; biquadFilter.Q.value = biquadFilterQ; + biquadFilter.gain.value = biquadFilterGain; source.connect(biquadFilter); biquadFilter.connect(context.destination); @@ -48,9 +51,8 @@ export function BiquadFilter({ unfilteredAudioBuffer, updateAudioBuffer }: Biqua context.startRendering().then(renderedBuffer => updateAudioBuffer(renderedBuffer)); } - return - Filter: + Filter (?): setBiquadFilterType(e.target.value as "lowpass" | "highpass" | "bandpass")} + onChange={(e) => setBiquadFilterType(e.target.value as BiquadFilterType) } select > lowpass highpass bandpass + lowshelf + highshelf + peaking + notch + allpass setBiquadFilterFreq(Number(e.target.value))} /> setBiquadFilterQ(Number(e.target.value))} /> + setBiquadFilterGain(Number(e.target.value))} + /> @@ -84,4 +99,22 @@ export function BiquadFilter({ unfilteredAudioBuffer, updateAudioBuffer }: Biqua ; -} \ No newline at end of file +} + + +function filterTypeToQLabel(biquadFilterType: BiquadFilterType): string { + switch(biquadFilterType) { + case "lowpass": + case "highpass": + return "Q (peak)"; + case "bandpass": + case "notch": + case "peaking": + return "Q (width)"; + case "allpass": + return "Q (phase)"; + case "lowshelf": + case "highshelf": + return "Q (unused)"; + } +} diff --git a/src/components/TimeSeriesUI.tsx b/src/components/TimeSeriesUI.tsx index c59495d..0cfe53a 100644 --- a/src/components/TimeSeriesUI.tsx +++ b/src/components/TimeSeriesUI.tsx @@ -34,6 +34,7 @@ import { channelToRgba, createAudioBufferCopy } from '../utils/utils'; import { SmallTextField } from './SmallTextField'; import { TabPanel } from './TabPanel'; import WavesurferAudioWaveform from './WavesurferWaveform'; +import { BiquadFilter } from './BiquadFilter'; type TimeSeriesUIProps = { lastFrame: number, @@ -98,10 +99,6 @@ export const TimeSeriesUI = (props: TimeSeriesUIProps) => { const [pitchMethod, setPitchMethod] = useState("default"); const pitchProgressRef = useRef(null); - const [biquadFilterFreq, setBiquadFilterFreq] = useState(800); - const [biquadFilterQ, setBiquadFilterQ] = useState(0.5); - const [biquadFilterType, setBiquadFilterType] = useState<"lowpass" | "highpass" | "bandpass">("lowpass"); - const [unfilteredAudioBuffer, setUnfilteredAudioBuffer] = useState(); const [audioBuffer, setAudioBuffer] = useState(); @@ -232,35 +229,6 @@ export const TimeSeriesUI = (props: TimeSeriesUIProps) => { } } - const handleResetBandPass = () => { - if (unfilteredAudioBuffer) { - setAudioBuffer(createAudioBufferCopy(unfilteredAudioBuffer)); - } - } - - const handleApplyBandPass = () => { - if (!unfilteredAudioBuffer) { - return; - } - - const audioData = unfilteredAudioBuffer.getChannelData(0); - const context = new OfflineAudioContext(1, audioData.length, unfilteredAudioBuffer.sampleRate); - const source = context.createBufferSource(); - const filteredBuffer = context.createBuffer(1, audioData.length, unfilteredAudioBuffer.sampleRate); - filteredBuffer.getChannelData(0).set(audioData); - source.buffer = filteredBuffer; - - const biquadFilter = context.createBiquadFilter(); - biquadFilter.type = biquadFilterType; - biquadFilter.frequency.value = biquadFilterFreq; - biquadFilter.Q.value = biquadFilterQ; - source.connect(biquadFilter); - biquadFilter.connect(context.destination); - - source.start(); - context.startRendering().then(renderedBuffer => setAudioBuffer(renderedBuffer)); - } - const handleLoadFromCSV = async (event: any) => { const file = event.target.files[0]; if (file && lastFrame) { @@ -477,41 +445,10 @@ export const TimeSeriesUI = (props: TimeSeriesUIProps) => { onChange={handleLoadFromAudio} /> {audioBuffer && <> - - Filter: - setBiquadFilterType(e.target.value as "lowpass" | "highpass" | "bandpass")} - select - > - lowpass - highpass - bandpass - - setBiquadFilterFreq(Number(e.target.value))} + setAudioBuffer(newAudioBuffer)} /> - setBiquadFilterQ(Number(e.target.value))} - /> - - - - - - - } {waveSuferWaveform} @@ -570,17 +507,6 @@ export const TimeSeriesUI = (props: TimeSeriesUIProps) => { Each row of the supplied file must be formatted like    timestamp,value    where the type of the timestamp can be milliseconds or frames as selected above. - - {/* - Previously Loaded TimeSeries - - */}

Processing

Modify the loaded data before adding it as a timeseries.