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 type { TileState } from './types/tiles'
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'
function App() {
@ -38,6 +38,7 @@ function App() {
const [showHelp, setShowHelp] = useState(false)
const playbackManagerRef = useRef<PlaybackManager | null>(null)
const downloadServiceRef = useRef<DownloadService>(new DownloadService())
const switchTimerRef = useRef<number | null>(null)
const { saveCurrentTileParams } = useTileParams({ tiles, setTiles, customTile, setCustomTile, focusedTile })
@ -51,12 +52,40 @@ function App() {
effectSettings.setKey('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 = () => {
clearSwitchTimer()
setTiles(generateTileGrid(TILE_GRID.SIZE, TILE_GRID.COLUMNS, engineValues.complexity))
setQueued(null)
}
const handleRandomizeAllParams = () => {
clearSwitchTimer()
let newRandomized: TileState | null = null
if (playing === PLAYBACK_ID.CUSTOM) {
@ -111,7 +140,7 @@ function App() {
const playFormula = async (formula: string, id: string) => {
const sampleRate = getSampleRateFromIndex(engineValues.sampleRate)
const duration = engineValues.loopDuration
const duration = LOOP_DURATION
if (!playbackManagerRef.current) {
playbackManagerRef.current = new PlaybackManager({ sampleRate, duration })
@ -156,9 +185,11 @@ function App() {
}
if (isDoubleClick || playing === null) {
clearSwitchTimer()
playFormula(tile.formula, id)
} else {
setQueued(id)
startSwitchTimer(id)
}
}
@ -309,6 +340,7 @@ function App() {
}
const handleStop = () => {
clearSwitchTimer()
playbackManagerRef.current?.stop()
setPlaying(null)
setQueued(null)

View File

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

View File

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