Commit Graph

97 Commits

Author SHA1 Message Date
3dtours 815a6faaca fix: Synth button shown on section/audio tracks
Synth button was unconditional in TCP. Now gated:
track.midiItems?.length > 0 && !track.sections?.length
Section tracks: Synth hidden (sections are containers).
MIDI tracks: Synth shown.
Audio tracks: Synth hidden.
FX button stays unconditional for all track types.
2026-07-28 08:37:31 +07:00
3dtours 9befc20851 fix: section track inherits soundfont_id/bank/program via ...t spread
...t in fallback branch copied soundfont_id, soundfont_bank,
soundfont_program, instrument_source from parent MAIN track
even though instrumentProgram and synth_engine were nulled.
FluidSynth picks up these fields and auto-loads the SoundFont.
Fix: override all soundfont/synth fields to null/undefined.
2026-07-28 08:32:21 +07:00
3dtours 18e177fa2d revert: section tracks inherit parent instrument, auto-loads SF prog0
Previous fix f2ac70e inherited instrumentId/program/name
from parent MAIN track. This causes SECTION-TAB to auto-load
program 0 of whatever SoundFont is loaded on MAIN, even
though user didn't select any instrument for the section.
Section tracks now keep null instrument + synth_engine
undefined. User can still load instrument manually via
Synth button (routed by updateActiveTracks fix).
2026-07-28 08:27:27 +07:00
3dtours f2ac70eee0 fix: section sub-tracks nullify instrument instead of inheriting
handleEditSectionInTab fallback branch explicitly set
instrumentId: null, instrumentProgram: undefined,
instrumentName: null, overriding parent track's values
spread by ...t. Changed to inherit from parent track:
instrumentId: t.instrumentId || null,
instrumentProgram: t.instrumentProgram,
instrumentName: t.instrumentName || null
2026-07-28 08:18:43 +07:00
3dtours ed51cab765 fix: instrument load from PIANO_ROLL in SECTION-TAB writes to main
updateActiveTracksRef checks sessionTabs by currentActiveTab.
When activeTab is a PIANO_ROLL sub-tab (midi_xxx), none matches
-> falls to setTracks (main). Instrument changes are lost.
Fix: also check subTabs for PIANO_ROLL type, resolve parent
session tab via parent_tab_id, route to setSessionTabs.
2026-07-28 08:11:36 +07:00
3dtours 447504ea67 fix: Ctrl+Click on section/MIDI items toggled selection, locked item
Ctrl+Click handler toggled selection + set pending drag.
Once selected, drag system treated it as 'move selection'
instead of 'copy'. Removed selection toggle - Ctrl+Click
now only sets pending drag for copy operation.
2026-07-28 08:07:49 +07:00
3dtours e4d6405b37 fix: PIANO_ROLL activeTracks resolves main tracks, not section
When PIANO_ROLL sub-tab is opened from SECTION-TAB,
activeTab switches to midi_xxx, so activeTracks fell
back to main project tracks. Section trackIds don't
exist in main tracks -> dropdown empty, ghost layers
empty, instrument data wrong.
Fix: check subTabs for PIANO_ROLL type, resolve parent
section tab from parent_tab_id, return its tracks.
2026-07-28 08:01:22 +07:00
3dtours 2baf034852 fix: section tab clears midiItems, breaks ghost+dropdown
handleEditSectionInTab overwrote midiItems: [] when cloning
section.tracks, stripping all MIDI data from section context.
PianoRollTabEditor uses activeTracks which resolves section
tracks -- midiItems must be preserved for dropdown switcher,
ghost note extraction, and instrument settings to work.
2026-07-28 07:51:08 +07:00
3dtours 14e3a561a3 feat: instrument selector modal 2-column layout
Modal max-w-md -> max-w-4xl. Font 14px (text-sm).
Left column: soundfont list. Right column: instruments
of selected SF. All Instruments view when none selected.
Search filters both columns.
2026-07-28 07:20:01 +07:00
3dtours d0def4bf1e feat: auto-scan soundfont for Synth instrument list
Background daemon (30s interval) tracks scanned files via
sf_scan_state.json (size+mtime). Only inspects new/changed SFs.
Catalog served from scanner cache, no full re-scan per request.
Upload/delete trigger immediate re-scan.
2026-07-28 07:06:37 +07:00
3dtours fd24c2dcd8 feat: Ctrl+drag sweep select + multi-item copy/drag
- Ctrl+drag on empty space: sweep range selection overlay
- Mouseup selects all items (MIDI, sections, clips) in sweep
- Selected items rendered with amber border highlight
- Ctrl+drag on section/MIDI item: duplicates the item
- Drag selected items: moves entire selected group together
- Ctrl+drag selected items: duplicates the entire group
2026-07-27 21:46:20 +07:00
3dtours 80a5352645 feat: Ctrl+drag on ruler creates global selection
handleRulerMouseDown's Ctrl+click branch previously only
cleared selection. Now it sets selectionMode='global',
records drag start, and enables isDraggingRulerRef so the
existing document-level mousemove handler updates the
selection range in real-time.
2026-07-27 21:38:23 +07:00
3dtours 8beef7cb4d fix: multi-track ARM routes MIDI to all armed tracks
- Use filter(t => t.isArmed) instead of find() to route
  MIDI input to ALL armed tracks simultaneously
- Use getTrackMidiChannel per track instead of raw
  MIDI hardware channel (msg.data[0] & 0x0F)
- NoteOff, CC, PitchBend also routed to each armed
  track's dedicated channel
- Previous code sent to channel 0 + first armed track only
2026-07-27 21:31:10 +07:00
3dtours 081a17d537 docs: add _playNoteFluid else branch fix to wiki 2026-07-27 21:27:04 +07:00
3dtours b42190e6bc feat: implement md/41_INSTRUMENT.md spec
- PianoRollTabService: getParentTrackByItemId, buildActiveScope,
  getTrackMidiChannel helpers
- parent_track_id on all MIDI items for reverse track lookup
- handleSwitchMidiItem uses active_scope pattern
- Toolbar shows parent track context labels
- Channel assignment simplified to trackIndex % 16
- All playNote calls use unified getTrackMidiChannel
2026-07-27 20:48:14 +07:00
3dtours 40502eda86 fix: pass channel+synth_engine to playNote in all MIDI playback paths
6 call sites were missing channel parameter, causing FluidSynth
to use ch=0 for all tracks -> program_change on channel 0
overwrote instrument across tracks during playback.

Fixes: startTrackPlayback, section sub-track MIDI, playMidiPreviewNote,
piano roll Alt+scroll preview, note click preview, keybed preview.
2026-07-27 20:42:45 +07:00
3dtours f429f6b1d3 docs: verify instrument assignment rules for MAIN SESSION
All 4 rules confirmed working:
1. MIDI item inherits track instrument
2. Section item does NOT inherit
3. Track isolation preserved
4. Piano roll instrument change propagates back to track
2026-07-27 20:32:30 +07:00
3dtours 035d75e504 feat(piano-roll): ghost notes + dropdown item switcher + session sync
- MIDI ghost notes: all non-selected items rendered at 25% opacity
- Dropdown at tab title: switch active edit target across all tracks
- Session Sync mode (default): viewport aligned to session bars
- Isolated mode toggle: bar 0, no ghost notes
- Ghost toggle: show/hide ghost layer (only in session mode)
- Auto-scroll to session position in session sync mode
- Bar labels show absolute session bar numbers
2026-07-27 17:08:59 +07:00
3dtours 095a0680e8 fix(build): remove extra brace at L6795, Babel build now succeeds; feat(ai-copilot): rows=4, resize-y, cursor-aware ArrowUp/Down 2026-07-27 16:36:26 +07:00
3dtours 4ed0b1e5be fix(ai-copilot): patch trực tiếp app.precompiled.js rows=4 + cursor check cho ArrowUp/Down 2026-07-27 16:21:24 +07:00
3dtours 29206d62a3 fix(ai-copilot): tăng chiều cao prompt input rows=4 + resize-y, sửa ArrowUp/ArrowDown chỉ gọi history khi cursor ở đầu/cuối text 2026-07-27 16:16:26 +07:00
3dtours 57235e68d2 docs: wiki entry program_select fix 2026-07-27 16:16:00 +07:00
3dtours 15ec35d8d9 docs: wiki entry activeNotes array fix 2026-07-27 16:00:42 +07:00
3dtours 7a2ac3a851 docs: wiki entry multi-track ARM + activeNotes 2026-07-27 15:48:43 +07:00
3dtours ef1238b87d feat: migrate SpessaSynth → FluidSynth WASM (SF3 native, loop Gen 54 fix)
Replace SpessaSynth JS/AudioWorklet with FluidSynth C++ WASM
(@enikey87/fluidsynth-emscripten@0.1.1). CDN for dev, self-host
for prod. Fixes stuck Tremolo/Saxophone notes via compliant
Gen 44 loop mode processing. 100% audio parity with server
pyfluidsynth render (same C++ core).

- soundfontPlayer.js: FluidSynth WASM engine, preserve SonicSF API
- fluidsynthLoader.js: auto-select CDN (dev) vs self-host (prod)
- fluidsynth-bridge.js: PCM bridge AudioWorklet processor
- index.html: remove SpessaSynth importmap + module, add loader
- vendor/: libfluidsynth-2.3.0-sf3.js + .wasm (1.8MB self-host)
2026-07-27 12:48:30 +07:00
3dtours 18d2503cb9 fix: bypass SpessaSynth AudioWorklet MIDI pipeline for looped voice release
SpessaSynth 4.3.1 bug: looped voices (Tremolo Strings, Trumpet) ignore
release envelope + CC 120 when processed through MIDI message pipeline
(processMessage). Fix: send stopAll directly to worklet via
handleMessage post() bypass, plus noteOn(vel=0) as alternate note-off.
2026-07-27 12:27:51 +07:00
3dtours 187686aa82 chore: add wiki entry for CC120 fix 2026-07-27 12:12:15 +07:00
3dtours 9357e4fcc8 chore: add wiki log 2026-07-27 11:43:43 +07:00
3dtours 62ac2e2d88 chore: add wiki log 2026-07-27 11:22:01 +07:00
3dtours d5ef016d49 chore: add wiki log 2026-07-27 11:06:43 +07:00
3dtours 138d05698a chore: add wiki log 2026-07-27 10:12:59 +07:00
3dtours d18c0085b6 chore: add wiki log 2026-07-27 09:28:45 +07:00
3dtours 720d80dbf9 chore: add wiki log 2026-07-27 08:53:53 +07:00
3dtours bf0469558a chore: add wiki log 2026-07-27 08:41:48 +07:00
3dtours e739eb54bf chore: add wiki log 2026-07-27 08:25:58 +07:00
3dtours 6a409b954d chore: add wiki log 2026-07-27 08:21:26 +07:00
3dtours 5915049260 chore: add wiki log 2026-07-27 08:03:12 +07:00
3dtours e4dadb3158 chore: add wiki log 2026-07-26 22:03:56 +07:00
3dtours 3b6f1ad05a chore: add wiki log 2026-07-26 21:32:14 +07:00
3dtours 8155b4f2fa chore: add wiki log 2026-07-26 21:16:55 +07:00
3dtours 1daf355dd4 chore: add loop fix log 2026-07-26 21:03:24 +07:00
3dtours 87655f4275 chore: add timeline fix log 2026-07-26 20:47:28 +07:00
3dtours 63496f27f4 chore: add final wiki log 2026-07-26 20:17:04 +07:00
3dtours 0d1ef0f895 chore: add SpessaSynth fix log to wiki 2026-07-26 18:05:54 +07:00
3dtours 3d2930dca5 chore: add SF3+SpessaSynth log to wiki 2026-07-26 17:51:48 +07:00
3dtours bfd7146bfc chore: add fix log to wiki 2026-07-26 17:25:46 +07:00
3dtours 443e09b592 feat(midi): play selected instrument on armed main track via MIDI keyboard
When MIDI note-on received and no PIANO_ROLL sub-tab is armed,
fallback to armed track in main session. Read its synth_engine and
instrumentProgram to route audio through correct instrument.
Route to track gainNode if available.
2026-07-26 17:19:51 +07:00
3dtours 4ff2ce0b9c chore: add drum toggle log to wiki 2026-07-26 17:11:50 +07:00
3dtours 96aa76f194 chore: add fluidsynth fix log to wiki 2026-07-26 17:08:49 +07:00
3dtours 1059f67979 chore: add bugfix log to wiki 2026-07-26 17:00:36 +07:00