loop mechanism rework

This commit is contained in:
2025-10-06 02:24:34 +02:00
parent ac772054c9
commit 18766f3d8a
3 changed files with 42 additions and 8 deletions

View File

@ -18,7 +18,7 @@ import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts'
import { useTileParams } from './hooks/useTileParams' import { useTileParams } from './hooks/useTileParams'
import type { TileState } from './types/tiles' import type { TileState } from './types/tiles'
import { createTileStateFromCurrent, loadTileParams, randomizeTileParams } from './utils/tileState' import { createTileStateFromCurrent, loadTileParams, randomizeTileParams } from './utils/tileState'
import { DEFAULT_VARIABLES, PLAYBACK_ID, TILE_GRID, DEFAULT_DOWNLOAD_OPTIONS } from './constants/defaults' import { DEFAULT_VARIABLES, PLAYBACK_ID, TILE_GRID, DEFAULT_DOWNLOAD_OPTIONS, LOOP_DURATION } from './constants/defaults'
import { getTileId, getTileFromGrid, type FocusedTile } from './utils/tileHelpers' import { getTileId, getTileFromGrid, type FocusedTile } from './utils/tileHelpers'
function App() { function App() {
@ -38,6 +38,7 @@ function App() {
const [showHelp, setShowHelp] = useState(false) const [showHelp, setShowHelp] = useState(false)
const playbackManagerRef = useRef<PlaybackManager | null>(null) const playbackManagerRef = useRef<PlaybackManager | null>(null)
const downloadServiceRef = useRef<DownloadService>(new DownloadService()) const downloadServiceRef = useRef<DownloadService>(new DownloadService())
const switchTimerRef = useRef<number | null>(null)
const { saveCurrentTileParams } = useTileParams({ tiles, setTiles, customTile, setCustomTile, focusedTile }) const { saveCurrentTileParams } = useTileParams({ tiles, setTiles, customTile, setCustomTile, focusedTile })
@ -51,12 +52,40 @@ function App() {
effectSettings.setKey('masterVolume', engineValues.masterVolume) effectSettings.setKey('masterVolume', engineValues.masterVolume)
}, [engineValues.masterVolume]) }, [engineValues.masterVolume])
const clearSwitchTimer = () => {
if (switchTimerRef.current !== null) {
clearTimeout(switchTimerRef.current)
switchTimerRef.current = null
}
}
const startSwitchTimer = (queuedId: string) => {
clearSwitchTimer()
switchTimerRef.current = window.setTimeout(() => {
const [rowStr, colStr] = queuedId.split('-')
const row = parseInt(rowStr, 10)
const col = parseInt(colStr, 10)
const tile = getTileFromGrid(tiles, row, col)
if (tile) {
playFormula(tile.formula, queuedId)
}
}, engineValues.loopCount * 1000)
}
useEffect(() => {
return () => clearSwitchTimer()
}, [])
const handleRandom = () => { const handleRandom = () => {
clearSwitchTimer()
setTiles(generateTileGrid(TILE_GRID.SIZE, TILE_GRID.COLUMNS, engineValues.complexity)) setTiles(generateTileGrid(TILE_GRID.SIZE, TILE_GRID.COLUMNS, engineValues.complexity))
setQueued(null) setQueued(null)
} }
const handleRandomizeAllParams = () => { const handleRandomizeAllParams = () => {
clearSwitchTimer()
let newRandomized: TileState | null = null let newRandomized: TileState | null = null
if (playing === PLAYBACK_ID.CUSTOM) { if (playing === PLAYBACK_ID.CUSTOM) {
@ -111,7 +140,7 @@ function App() {
const playFormula = async (formula: string, id: string) => { const playFormula = async (formula: string, id: string) => {
const sampleRate = getSampleRateFromIndex(engineValues.sampleRate) const sampleRate = getSampleRateFromIndex(engineValues.sampleRate)
const duration = engineValues.loopDuration const duration = LOOP_DURATION
if (!playbackManagerRef.current) { if (!playbackManagerRef.current) {
playbackManagerRef.current = new PlaybackManager({ sampleRate, duration }) playbackManagerRef.current = new PlaybackManager({ sampleRate, duration })
@ -156,9 +185,11 @@ function App() {
} }
if (isDoubleClick || playing === null) { if (isDoubleClick || playing === null) {
clearSwitchTimer()
playFormula(tile.formula, id) playFormula(tile.formula, id)
} else { } else {
setQueued(id) setQueued(id)
startSwitchTimer(id)
} }
} }
@ -309,6 +340,7 @@ function App() {
} }
const handleStop = () => { const handleStop = () => {
clearSwitchTimer()
playbackManagerRef.current?.stop() playbackManagerRef.current?.stop()
setPlaying(null) setPlaying(null)
setQueued(null) setQueued(null)

View File

@ -15,13 +15,13 @@ export const ENGINE_CONTROLS: EffectConfig[] = [
unit: '' unit: ''
}, },
{ {
id: 'loopDuration', id: 'loopCount',
label: 'Loop', label: 'Loop',
min: 2, min: 1,
max: 8, max: 10,
default: 4, default: 2,
step: 2, step: 1,
unit: 's' unit: ''
}, },
{ {
id: 'complexity', id: 'complexity',

View File

@ -19,3 +19,5 @@ export const DEFAULT_DOWNLOAD_OPTIONS = {
DURATION: 4, DURATION: 4,
BIT_DEPTH: 24 BIT_DEPTH: 24
} as const } as const
export const LOOP_DURATION = 4