Work in progress! Very early stage and actively developed.
daw.ts
is a Digital Audio Workstation (DAW) application built with TypeScript, React, Zustand, and leveraging the Web Audio browser API.
Designed for high-performance audio processing with live editing capabilities.
-
Clone the repository:
git clone https://github.com/yannmazita/daw.ts.git
-
Install dependencies:
npm install
-
Start the application (development server)
npm run dev
Engine Layer Diagram
graph TD
EM[Engine Manager] --> CE[Composition Engine]
CE[Composition Engine] -- Updates --> ZS[Zustand Store]
CE --> ME[Mix Engine]
CE --> TE[Transport Engine]
CE --> SE[Sampler Engine]
CE --> CLE[Clip Engine]
CE --> AE[Automation Engine]
ME --> MRS[Mix Routing Service]
ME --> MPS[Mix Parameter Service]
ME --> MTS[Mix Track Service]
SE --> SIS[Sampler Instrument Service]
SE --> FLS[File Loader Service]
SE --> SPS[SFZ Player Service]
CLE --> CMS[Clip MIDI Service]
CLE --> CAS[Clip Audio Service]
TE --> TC[Transport Clock]
EM --> AC[Audio Context]
style EM fill:#808080,stroke:#333,stroke-dasharray: 5 5
style CE fill:#6a89cc,stroke:#333
style ZS fill:#4a69bd,stroke:#333
style AC fill:#4a69bd,stroke:#333
style ME fill:#6a89cc,stroke:#333
style SE fill:#6a89cc,stroke:#333
style CLE fill:#6a89cc,stroke:#333
style TE fill:#6a89cc,stroke:#333
style AE fill:#6a89cc,stroke:#333
State Management
sequenceDiagram
participant UI Component
participant CompositionService
participant Engine (e.g. MixEngine)
participant Zustand Store
UI Component->>CompositionService: Action (e.g. createTrack)
CompositionService->>Engine: Engine method call
Engine->>Engine: Modify audio nodes (Web Audio API)
CompositionService->>Zustand Store: Immutable state update (via `useEngineStore.setState`)
Zustand Store->>UI Component: Re-render components using state selectors
Conceptual Audio Graph Diagram
Each input/output node is a Gain node allowing to update gain.
graph LR
subgraph MasterTrack
MT_Input(Master Input) --> MT_Pan(Pan)
MT_Pan --> MT_Gain(Gain)
MT_Gain --> MT_Output(Destination)
end
subgraph Track["Track (MIDI/Audio)"]
Track_Input(Track Input) --> BypassCheck{SoundChain Active?}
BypassCheck -- Yes --> SC_Input
BypassCheck -- No --> Track_Pan(Pan)
SC_Output --> Track_Pan
Track_Pan --> Track_Output(Track Output)
Track_InstrumentInput([Instrument Input - MIDI or Audio]) --> Track_Input
Track_ClipOutput([Clip Output - Audio or MIDI]) --> Track_InstrumentInput
end
subgraph SoundChain
SC_Input(SoundChain Input) --> Chain1_Input
subgraph Chain1["Chain 1"]
Chain1_Input(Input) --> Chain1_Instrument["Instrument (SamplerEngine)"]
Chain1_Instrument --> Chain1_Effects{Effects}
Chain1_Effects --> Chain1_Pan(Pan)
Chain1_Pan --> Chain1_Output(Output)
end
Chain1_Output --> Chain2_Input
subgraph Chain2["Chain 2"]
Chain2_Input(Input) --> Chain2_Instrument["Instrument (SamplerEngine)"]
Chain2_Instrument --> Chain2_Effects{Effects}
Chain2_Effects --> Chain2_Pan(Pan)
Chain2_Pan --> Chain2_Output(Output)
end
Chain2_Output --> ChainN_Input
subgraph ChainN["Chain n"]
ChainN_Input(Input) --> ChainN_Instrument["Instrument (SamplerEngine)"]
ChainN_Instrument --> ChainN_Effects{Effects}
ChainN_Effects --> ChainN_Pan(Pan)
ChainN_Pan --> ChainN_Output(Output)
end
ChainN_Output --> SC_Output(SoundChain Output)
end
subgraph ReturnTrack
RT_Input(Return Input) --> RT_Pan(Pan)
RT_Pan --> RT_Output(Return Output)
end
subgraph Send
Send_Output(Send Output)
end
%% Main Mix Routing
Track_Output --> MT_Input
RT_Output --> MT_Input
Send_Output --> RT_Input
style MasterTrack fill:#8854d0,stroke:#333,stroke-width:2px
style Track fill:#6a89cc,stroke:#333,stroke-width:2px
style SoundChain fill:#38ada9,stroke:#333,stroke-width:2px
style Chain1 fill:#78e08f,stroke:#333,stroke-width:2px
style Chain2 fill:#78e08f,stroke:#333,stroke-width:2px
style ChainN fill:#78e08f,stroke:#333,stroke-width:2px
style ReturnTrack fill:#fa983a,stroke:#333,stroke-width:2px
style Send fill:#eb2f06,stroke:#333,stroke-width:2px
style Track_InstrumentInput dashed
style Track_ClipOutput dashed
Detailed Engine description
- Orchestrates all engine interactions, provides unified API for the UI.
- Dedicated services for engines.
Not fully implemented yet. Responsibilites not yet defined, it should handle automation lanes.
- MIDI and audio clip management.
- Clip scheduling.
- Dedicated services for MIDI clips and Audio clips.
- Handles audio routing and signal processing
- Track, send, and return management.
- Complex instruments and effects with chains and sound chains.
- Dedicated services for routing, parameter control and track lifecycle management.
- SFZ instrument loading/parsing
- Sample pooling with LRU caching
- Dedicated services for sample loading/caching, SFZ region handling and instrument instance management.
- High-precision scheduling.
- Tempo and time signature control.
- Dedicated clock service.
- MIDI event routing system
- Clip transport synchronization
- Sample-accurate scheduling
- Clip visualisation
- FileSystemDirectoryHandle fallback as only FileWithDirectoryAndFileHandle (Blink) is properly used.
- Automation
- UI enhancements
Contributions are welcome! Current priority areas:
- MIDI scheduling
- Automation
- Performance optimization