Skip to content

Commit

Permalink
hotkey to play from captured position. Darkmode fixes for waveform.
Browse files Browse the repository at this point in the history
  • Loading branch information
rewbs committed Jul 20, 2023
1 parent 44ccd5f commit 11475ef
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/ParseqUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ const ParseqUI = (props) => {
// Resize grid to fit content and update graph view if last frame changes.
// TODO: UI optimisation: only need to do this keyframes have changed, could store a prevKeyframes and deepEquals against it.
if (keyframes) {
const gridContainer = document.querySelector(".ag-theme-alpine");
const gridContainer = document.querySelector("#grid-container");
if (gridContainer) {
if (gridHeight === 0) {
// auto-size grid to fit content
Expand Down
64 changes: 52 additions & 12 deletions src/components/AudioWaveform.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { SmallTextField } from "./SmallTextField";
import { TabPanel } from "./TabPanel";
import { BiquadFilter } from "./BiquadFilter";
import { useHotkeys } from 'react-hotkeys-hook'
import { SupportedColorScheme, experimental_extendTheme as extendTheme, useColorScheme } from "@mui/material/styles";
import { themeFactory } from "../theme";

type AudioWaveformProps = {
fps: number,
Expand Down Expand Up @@ -54,6 +56,10 @@ export function AudioWaveform(props: AudioWaveformProps) {
const [lastViewport, setLastViewport] = useState({ startFrame: 0, endFrame: 0 });
const [tab, setTab] = useState(1);

// if the user clicks on the waveform or pauses the track, we capture the position
// so that we can repeatedly play back from that position with ctrl+space
const [capturedPos, setCapturedPos] = useState<number>(0);

const [audioBuffer, setAudioBuffer] = useState<AudioBuffer>();
const [unfilteredAudioBuffer, setUnfilteredAudioBuffer] = useState<AudioBuffer>();
const [isAnalysing, setIsAnalysing] = useState(false);
Expand All @@ -77,7 +83,10 @@ export function AudioWaveform(props: AudioWaveformProps) {
/* eslint-disable @typescript-eslint/no-unused-vars */
const [showSpectrogram, setShowSpectrogram] = useState(false);


const theme = extendTheme(themeFactory());
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {colorScheme, setColorScheme } = useColorScheme();
const palette = theme.colorSchemes[(colorScheme||'light') as SupportedColorScheme].palette;

// Triggered when user makes viewport changes outside of wavesurfer, and we need to update wavesurfer.
const scrollToPosition = useCallback((startFrame: number) => {
Expand Down Expand Up @@ -149,6 +158,11 @@ export function AudioWaveform(props: AudioWaveformProps) {
setManualEvents(newMarkers);
}, [manualEvents]);

const handleClick = useCallback((event: any) => {
const time = wavesurferRef.current?.getCurrentTime();
setCapturedPos(time || 0);
}, []);

const handleMarkerDrop = useCallback((marker: Marker) => {
//console.log("In handleMarkerDrop", marker);
const draggedEventType = deduceMarkerType(marker);
Expand Down Expand Up @@ -233,6 +247,15 @@ export function AudioWaveform(props: AudioWaveformProps) {
}
}, [handleDoubleClick]);

useEffect(() => {
//wavesurferRef.current?.on("dblclick", handleDoubleClick);
wavesurferRef.current?.drawer?.on("lick", handleClick);
return () => {
//wavesurferRef.current?.un("dblclick", handleDoubleClick);
wavesurferRef.current?.drawer?.un("click", handleClick);
}
}, [handleClick]);

useEffect(() => {
wavesurferRef.current?.on("marker-drop", handleMarkerDrop);
return () => {
Expand Down Expand Up @@ -330,18 +353,20 @@ export function AudioWaveform(props: AudioWaveformProps) {
}
}

function playPause(fromStart:boolean = false) {
if (isPlaying) {
function playPause(from : number = -1, pauseIfPlaying = true) {
if (isPlaying && pauseIfPlaying) {
wavesurferRef.current?.pause();
setCapturedPos(wavesurferRef.current?.getCurrentTime() || 0);
} else {
if (fromStart) {
wavesurferRef.current?.seekTo(0);
if (from>=0) {
wavesurferRef.current?.setCurrentTime(from);
} if (!isPlaying) {
wavesurferRef.current?.play();
}
wavesurferRef.current?.play();
}
setIsPlaying(!isPlaying);
setIsPlaying(wavesurferRef.current?.isPlaying() ?? false );
updatePlaybackPos();
}
}

const updateMarkers = useCallback(() => {
wavesurferRef.current?.markers.clear();
Expand Down Expand Up @@ -477,6 +502,13 @@ export function AudioWaveform(props: AudioWaveformProps) {
container: "#timeline",
formatTimeCallback: formatTimeCallback,
timeInterval: timeInterval,
unlabeledNotchColor: palette.graphBorder.main,
primaryColor: palette.graphBorder.dark,
secondaryColor: palette.graphBorder.light,
primaryFontColor: palette.graphFont.main,
secondaryFontColor: palette.graphFont.light,
fontFamily: 'Arial',
fontSize: 10,
}));
wavesurferRef.current.initPlugin('timeline');
// HACK to force the timeline position to update.
Expand All @@ -488,7 +520,7 @@ export function AudioWaveform(props: AudioWaveformProps) {
// Force the wavesurfer to redraw the timeline
wavesurferRef.current.drawBuffer();
}
}, [formatTimeCallback, props.viewport.startFrame, scrollToPosition]);
}, [formatTimeCallback, props.viewport.startFrame, scrollToPosition, palette]);

const waveSurferPlugins = [
{
Expand Down Expand Up @@ -616,11 +648,15 @@ export function AudioWaveform(props: AudioWaveformProps) {

useHotkeys('space', () => {
playPause();
}, {preventDefault:true}, [isPlaying, updatePlaybackPos])
}, {preventDefault:true}, [playPause]);

useHotkeys('shift+space', () => {
playPause(true);
}, {preventDefault:true}, [isPlaying, updatePlaybackPos])
playPause(0, false);
}, {preventDefault:true}, [playPause]);

useHotkeys('ctrl+space', () => {
playPause(capturedPos, false);
}, {preventDefault:true}, [playPause, capturedPos]);

useHotkeys('shift+a', () => {
const time = wavesurferRef.current?.getCurrentTime();
Expand All @@ -631,6 +667,8 @@ export function AudioWaveform(props: AudioWaveformProps) {
}, {preventDefault:true}, [manualEvents])




return <>
<Grid container>
<Grid xs={12}>
Expand Down Expand Up @@ -675,6 +713,8 @@ export function AudioWaveform(props: AudioWaveformProps) {
minPxPerSec={10}
autoCenter={false}
interact={true}
cursorColor={palette.success.light}
cursorWidth={3}
/>
<div id="timeline" />
<div style={{display:showSpectrogram? 'block' : 'none'}} id="spectrogram" />
Expand Down
6 changes: 3 additions & 3 deletions src/components/ParseqGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ export const ParseqGrid = forwardRef(({ rangeSelection, onSelectRange, onGridRea
cellStyle: (params: any): any => {
if (isInRangeSelection(params)) {
return {
backgroundColor: theme.vars.palette.gridInfoField.light,
backgroundColor: theme.vars.palette.gridInfoField.dark,
borderRight: isSameCellPosition(params, params.api.getFocusedCell()) ? '' : '1px solid ' + theme.vars.palette.gridColSeparatorMajor.main
}
} else {
return {
backgroundColor: theme.vars.palette.gridInfoField.main,
backgroundColor: theme.vars.palette.gridInfoField.light,
borderRight: isSameCellPosition(params, params.api.getFocusedCell()) ? '' : '1px solid '+ theme.vars.palette.gridColSeparatorMajor.main
}
}
Expand Down Expand Up @@ -246,7 +246,7 @@ export const ParseqGrid = forwardRef(({ rangeSelection, onSelectRange, onGridRea
}), [fps, bpm]);


return <div className={colorScheme==='dark'?"ag-theme-alpine-dark":"ag-theme-alpine"} style={agGridStyle}>
return <div id='grid-container' className={colorScheme==='dark'?"ag-theme-alpine-dark":"ag-theme-alpine"} style={agGridStyle}>
{/* @ts-ignore */}
<AgGridReact
{...agGridProps}
Expand Down
2 changes: 1 addition & 1 deletion src/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const themeFactory = (): CssVarsThemeOptions => {
graphBorder: palette.augmentColor({ color: { main: 'rgba(0, 0, 0, 0.1)' } }),
graphBackground: palette.augmentColor({ color: { main: 'rgba(0, 0, 0, 0.1)' } }),
graphFont: palette.augmentColor({ color: { main: '#666' } }),
gridInfoField: palette.augmentColor({ color: { main: '#eee' } }),
gridInfoField: palette.augmentColor({ color: { main: '#e5e5e5' } }),
gridColSeparatorMajor: palette.augmentColor({ color: { main: '#000' } }),
gridColSeparatorMinor: palette.augmentColor({ color: { main: '#ccc' } }),
codeBackground: palette.augmentColor({ color: { main: '#ccc' } }),
Expand Down

0 comments on commit 11475ef

Please sign in to comment.