From 6ec4aa98d73673cee1775f0cac8f9a63be9c8abb Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 02:45:58 +0000 Subject: [PATCH] feat: implement procedural drum synthesis and techno patterns based on research - Refined all TR-808 and TR-909 synthesis models (Kick, Snare, Hi-Hats, Clap, Cowbell) to strictly follow the DSP research specifications. - Implemented authentic 15-bit LFSR noise for 909 Snappy component. - Updated pitch drift to use cent-based logarithmic formula (+/- 1-2 cents). - Added master saturation with soft-clipping hyperbolic tangent curve. - Implemented 'Techno Randomization' feature in instrument store and UI. - Ensured proper node disposal and Web Audio API safety (positive ramp guards). - Synchronized initial audio engine state with UI parameters. Co-authored-by: Pitrat-wav <255843145+Pitrat-wav@users.noreply.github.com> --- src/components/DrumsView.tsx | 30 ++++++++++++++++++++++++- src/logic/DrumMachine.ts | 16 ++++++++++++++ src/logic/DrumUtils.ts | 39 ++++++++++++++++++++++++++++----- src/logic/drums/TR808Clap.ts | 8 ++++--- src/logic/drums/TR808Cowbell.ts | 24 +++++++++++--------- src/logic/drums/TR808HiHat.ts | 29 ++++++++++++++---------- src/logic/drums/TR808Kick.ts | 25 ++++++++++++++------- src/logic/drums/TR808Snare.ts | 15 ++++++++----- src/logic/drums/TR909Kick.ts | 16 +++++++++----- src/logic/drums/TR909Snare.ts | 19 ++++++---------- src/store/audioStore.ts | 6 +++++ src/store/instrumentStore.ts | 24 ++++++++++++++++++-- 12 files changed, 187 insertions(+), 64 deletions(-) diff --git a/src/components/DrumsView.tsx b/src/components/DrumsView.tsx index 7d191e90..10f0152e 100644 --- a/src/components/DrumsView.tsx +++ b/src/components/DrumsView.tsx @@ -8,7 +8,7 @@ import { bjorklund, rotateArray } from '../logic/bjorklund' import { TransportControls } from './TransportControls' export function DrumsView() { - const { kick, snare, hihat, hihatOpen, clap, kit, drive, setParams, setKit, setDrive } = useDrumStore() + const { kick, snare, hihat, hihatOpen, clap, kit, drive, setParams, setKit, setDrive, randomizeTechno: randomizeTechnoStore } = useDrumStore() const { drumMachine, volumes, setVolume } = useAudioStore() const updateDrum = (drum: 'kick' | 'snare' | 'hihat' | 'hihatOpen' | 'clap' | 'cowbell', params: Partial) => { @@ -30,6 +30,26 @@ export function DrumsView() { if (drumMachine) drumMachine.setSaturation(v) } + const randomizeTechno = () => { + randomizeTechnoStore() + + // Sync internal params after batch update + if (drumMachine) { + const state = useDrumStore.getState() + drumMachine.setDrumParams('kick', state.kick.pitch, state.kick.decay) + drumMachine.setDrumParams('snare', state.snare.pitch, state.snare.decay) + drumMachine.setDrumParams('hihat', state.hihat.pitch, state.hihat.decay) + drumMachine.setDrumParams('hihatOpen', state.hihatOpen.pitch, state.hihatOpen.decay) + drumMachine.setDrumParams('clap', state.clap.pitch, state.clap.decay) + drumMachine.setDrumParams('cowbell', state.cowbell.pitch, state.cowbell.decay) + } + + // Telegram Haptic Feedback + if (window.Telegram?.WebApp?.HapticFeedback) { + window.Telegram.WebApp.HapticFeedback.impactOccurred('medium') + } + } + return (
@@ -45,6 +65,14 @@ export function DrumsView() { onChange={handleDriveChange} size={40} /> +
{(['808', '909'] as const).map(k => (