feat: composition tests (8/8), memory leak fixes, ws-commands modular, docs update
composition-store.test.ts: 8 tests (CRUD, persistence, filtering) Memory: 30min Map cleanup, userStats cap 1000, async startup ws-commands: 1362→23 LOC dispatcher + 3 modules PLAN lots 192-200, README 53 commands, FEATURE_MAP, AGENTS Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
# PLAN.md — KXKM_Clown
|
||||
|
||||
Updated: 2026-03-20T18:00:00Z
|
||||
Updated: 2026-03-20T22:00:00Z
|
||||
|
||||
## Summary
|
||||
|
||||
- **165+ lots executed** (24-177) in session 2026-03-19/20
|
||||
- **170+ lots executed** (24-191) in session 2026-03-19/20
|
||||
- **425 tests**, 0 fail
|
||||
- **43 commands**, 13 services, 9 spec docs
|
||||
- **53 commands**, 13 services, 9 spec docs
|
||||
- **All SEC-01-05 resolved**
|
||||
- Ollama v0.18.2, qwen3.5:9b (256K ctx, adaptive thinking)
|
||||
- 35 music styles, 5 CSS themes, 32 ComfyUI checkpoints + 24 LoRAs
|
||||
- 35 music styles, 9 audio effects, 5 CSS themes, 32 ComfyUI checkpoints + 24 LoRAs
|
||||
- Composition pipeline: multi-track, voice, noise, effects, mix
|
||||
- TTFC 284ms
|
||||
- Next: lots 178+ (Compose pipeline, DAW integration, composition advanced)
|
||||
- Next: lots 192+ (ws-commands extraction, waveform viz, remix, MIDI, templates, collab, stems, DAW export)
|
||||
|
||||
---
|
||||
|
||||
@@ -648,87 +649,89 @@ Updated: 2026-03-20T12:00:00Z
|
||||
- Owner: Multimodal
|
||||
- Priority: P3
|
||||
|
||||
## lot-184-multi-track [planned]
|
||||
## lot-184-multi-track [done]
|
||||
- Description: Multi-track composition (layer multiple ACE-Step generations)
|
||||
- Owner: Multimodal
|
||||
- Priority: P2
|
||||
- Summary: /layer command, composition-store multi-track, track merge pipeline.
|
||||
|
||||
## lot-185-composition-ui [planned]
|
||||
## lot-185-composition-ui [done]
|
||||
- Description: Composition timeline UI (waveform view, track lanes)
|
||||
- Owner: Frontend
|
||||
- Priority: P2
|
||||
- Summary: CompositionView with track lanes, play/pause/seek, layer visualization.
|
||||
|
||||
## lot-186-arrangement [planned]
|
||||
## lot-186-arrangement [done]
|
||||
- Description: Arrangement tools (intro/verse/chorus structure)
|
||||
- Owner: Backend API + Frontend
|
||||
- Priority: P2
|
||||
- Summary: /comp structure command, section markers, arrangement presets.
|
||||
|
||||
## lot-187-mastering [planned]
|
||||
## lot-187-mastering [done]
|
||||
- Description: Auto-mastering pipeline (loudness normalization, limiting)
|
||||
- Owner: Multimodal
|
||||
- Priority: P3
|
||||
- Summary: /mix master command, loudness normalization, limiter, final WAV export.
|
||||
|
||||
## lot-188-stem-separation [planned]
|
||||
- Description: Stem separation (vocals, drums, bass, other)
|
||||
## lot-188-voice-composition [done]
|
||||
- Description: /voice command — TTS voiceover injected into composition timeline
|
||||
- Owner: Multimodal
|
||||
- Summary: /voice generates TTS audio, injects as track layer in composition.
|
||||
|
||||
## lot-189-noise-generator [done]
|
||||
- Description: /noise command — 5 noise types (white, pink, brown, rain, wind)
|
||||
- Owner: Multimodal
|
||||
- Summary: /noise generates ambient noise layers, 5 types available.
|
||||
|
||||
## lot-190-fx-pipeline [done]
|
||||
- Description: /fx command — 9 audio effects (reverb, delay, chorus, flanger, distortion, bitcrusher, EQ, compressor, tremolo)
|
||||
- Owner: Multimodal
|
||||
- Summary: 9 real-time audio effects applicable to any track or mix.
|
||||
|
||||
## lot-191-ambient-command [done]
|
||||
- Description: /ambient command — ambient scene generator (forest, ocean, city, space, cave)
|
||||
- Owner: Multimodal
|
||||
- Summary: /ambient generates layered ambient soundscapes from scene presets.
|
||||
|
||||
## lot-192-ws-commands-extraction [planned]
|
||||
- Description: ws-commands modular extraction (split monolithic command handler into per-command modules)
|
||||
- Owner: Backend API
|
||||
- Priority: P1
|
||||
|
||||
## lot-193-composition-tests [planned]
|
||||
- Description: Composition tests (unit tests for composition-store, /fx effects)
|
||||
- Owner: Backend API
|
||||
- Priority: P1
|
||||
|
||||
## lot-194-waveform-viz [planned]
|
||||
- Description: Waveform visualization (wavesurfer.js @wavesurfer/react or canvas)
|
||||
- Owner: Frontend
|
||||
- Priority: P2
|
||||
- Notes: wavesurfer.js v7+ has official @wavesurfer/react package (hook + component). Plugins: regions, timeline, spectrogram, minimap. MIT license.
|
||||
|
||||
## lot-195-remix [planned]
|
||||
- Description: /remix re-generate specific track in composition
|
||||
- Owner: Multimodal
|
||||
- Priority: P2
|
||||
|
||||
## lot-196-midi-export [planned]
|
||||
- Description: MIDI export from composition
|
||||
- Owner: Multimodal
|
||||
- Priority: P3
|
||||
|
||||
## lot-189-midi-export [planned]
|
||||
- Description: MIDI export from generated compositions
|
||||
- Owner: Multimodal
|
||||
- Priority: P3
|
||||
|
||||
## lot-190-composition-templates [planned]
|
||||
- Description: Composition templates (ambient, techno, orchestral presets)
|
||||
## lot-197-composition-templates [planned]
|
||||
- Description: Composition templates (preset multi-track arrangements: ambient, techno, orchestral, cinematic)
|
||||
- Owner: Backend API
|
||||
- Priority: P2
|
||||
|
||||
## lot-191-collab-composition [planned]
|
||||
- Description: Collaborative composition (multi-user timeline editing)
|
||||
## lot-198-collab-composition [planned]
|
||||
- Description: Collaborative composition (multiple users, shared composition, real-time sync)
|
||||
- Owner: Backend API + Frontend
|
||||
- Priority: P3
|
||||
|
||||
## lot-192-lyrics-gen [planned]
|
||||
- Description: Lyrics generation (LLM-driven, synced to composition)
|
||||
- Owner: Backend API
|
||||
- Priority: P3
|
||||
## lot-199-stem-separation [planned]
|
||||
- Description: Stem separation via Demucs v4 (htdemucs) — vocals, drums, bass, other, piano, guitar
|
||||
- Owner: Multimodal
|
||||
- Priority: P2
|
||||
- Notes: Demucs v4 (htdemucs) MIT license, pip install demucs, 6-stem mode (piano+guitar), SDR 9.20dB. htdemucs_ft for best quality. GPU recommended.
|
||||
|
||||
## lot-193-voice-composition [planned]
|
||||
- Description: Voice-driven composition (hum/sing to generate)
|
||||
## lot-200-daw-export [planned]
|
||||
- Description: Full DAW export (WAV stems + JSON project file with markers, effects, arrangement)
|
||||
- Owner: Multimodal
|
||||
- Priority: P3
|
||||
|
||||
## lot-194-fx-rack [planned]
|
||||
- Description: FX rack UI (drag-drop effects chain)
|
||||
- Owner: Frontend
|
||||
- Priority: P3
|
||||
|
||||
## lot-195-automation [planned]
|
||||
- Description: Parameter automation (volume, pan, effects over time)
|
||||
- Owner: Frontend + Backend API
|
||||
- Priority: P3
|
||||
|
||||
## lot-196-sample-library [planned]
|
||||
- Description: Sample library integration (one-shots, loops, foley)
|
||||
- Owner: Multimodal
|
||||
- Priority: P3
|
||||
|
||||
## lot-197-spectral-view [planned]
|
||||
- Description: Spectral analysis view for compositions
|
||||
- Owner: Frontend
|
||||
- Priority: P3
|
||||
|
||||
## lot-198-composition-history [planned]
|
||||
- Description: Composition version history (undo/redo, snapshots)
|
||||
- Owner: Backend API
|
||||
- Priority: P3
|
||||
|
||||
## lot-199-render-queue [planned]
|
||||
- Description: Render queue (batch export, format options)
|
||||
- Owner: Backend API + Multimodal
|
||||
- Priority: P3
|
||||
|
||||
## lot-200-composition-sharing [planned]
|
||||
- Description: Composition sharing (public links, embeds)
|
||||
- Owner: Backend API + Frontend
|
||||
- Priority: P3
|
||||
|
||||
@@ -55,6 +55,7 @@ Par defaut, Ollama est attendu en natif sur le host (port 11434).
|
||||
| SearXNG | 8080 | Recherche web self-hosted |
|
||||
| TTS Sidecar | 9100 | Piper + Chatterbox (dual backend) |
|
||||
| Qwen3-TTS | 9300 | Qwen3-TTS 0.6B CustomVoice (9 speakers) |
|
||||
| ACE-Step | 9400 | Generation musicale (35 styles, GPU) |
|
||||
| Reranker | 8787 | BGE/Jina reranking |
|
||||
| Docling | 5001 | Extraction PDF (tables, OCR) |
|
||||
| ComfyUI | 8188 | Generation images (32 checkpoints + 24 LoRAs) |
|
||||
@@ -74,10 +75,11 @@ Par defaut, Ollama est attendu en natif sur le host (port 11434).
|
||||
- **PDF** — Extraction via Docling/PyMuPDF (tables, layout, OCR)
|
||||
- **Recherche web** — SearXNG self-hosted + DuckDuckGo fallback
|
||||
- **Generation musicale** — `/compose` via ACE-Step 1.5 / MusicGen, 35 music styles
|
||||
- **Composition pipeline** — Multi-track (`/layer`), voice (`/voice`), noise (`/noise` 5 types), ambient (`/ambient`), effects (`/fx` 9 effects: reverb, delay, chorus, flanger, distortion, bitcrusher, EQ, compressor, tremolo), mix (`/mix`)
|
||||
- **Generation images** — `/imagine` via ComfyUI (32 checkpoints + 24 LoRAs, smart NLP selection)
|
||||
- **Memoire persona** — Faits et resume persistants, compaction LLM auto (750 MB)
|
||||
- **Inter-persona** — @mention directe, dialogue depth 3
|
||||
- **43 commandes slash** — /help, /nick, /who, /personas, /web, /clear, /status, /compose, /imagine, /voice, /memory, /context, /rag, /stats, /uptime, /model, /persona, /reload, /export, /changelog, /version, /dice, /roll, /flip, /ban, /unban, /mute, /unmute, /whisper, /history, /search, /react, /invite, /time, /date, /session, /speed, + more
|
||||
- **53 commandes slash** — /help, /nick, /who, /personas, /web, /clear, /status, /compose, /imagine, /voice, /noise, /ambient, /fx, /layer, /mix, /comp, /memory, /context, /rag, /stats, /uptime, /model, /persona, /reload, /export, /changelog, /version, /dice, /roll, /flip, /ban, /unban, /mute, /unmute, /whisper, /history, /search, /react, /invite, /time, /date, /session, /speed, + more
|
||||
- **Markdown chat** — Rendu Markdown (marked + DOMPurify) dans les messages
|
||||
- **Smart routing** — 5 domaines thematiques (musique, philosophie, tech, arts, science)
|
||||
- **Validation Zod** — 19 schemas sur toutes les routes API
|
||||
@@ -145,7 +147,7 @@ Par defaut, Ollama est attendu en natif sur le host (port 11434).
|
||||
| `PYTHON_BIN` | `python3` | Python avec libs ML (PyTorch, faster-whisper, piper-tts) |
|
||||
| `SCRIPTS_DIR` | `./scripts` | Chemin vers les scripts Python (TTS, STT, training) |
|
||||
|
||||
## Commandes slash (43)
|
||||
## Commandes slash (53)
|
||||
|
||||
| Commande | Description | Admin |
|
||||
| --- | --- | --- |
|
||||
@@ -178,6 +180,12 @@ Par defaut, Ollama est attendu en natif sur le host (port 11434).
|
||||
| `/date` | Date (FR locale) | non |
|
||||
| `/session` | Info session courante | non |
|
||||
| `/speed` | Diagnostics latence (TTFC, p50/p95) | non |
|
||||
| `/layer <prompt>` | Ajouter une couche audio a la composition | non |
|
||||
| `/mix` | Mixer les couches de la composition | non |
|
||||
| `/comp` | Gerer la composition (structure, info) | non |
|
||||
| `/noise <type>` | Generer bruit ambiant (white/pink/brown/rain/wind) | non |
|
||||
| `/ambient <scene>` | Scene ambiante (forest/ocean/city/space/cave) | non |
|
||||
| `/fx <effect>` | Appliquer effet audio (reverb/delay/chorus/flanger/distortion/bitcrusher/eq/compressor/tremolo) | non |
|
||||
| `/model` | Changer modele | oui |
|
||||
| `/persona` | Gerer personas | oui |
|
||||
| `/reload` | Recharger config | oui |
|
||||
@@ -326,6 +334,7 @@ kxkm_clown/
|
||||
| RBAC | n/a | operationnel |
|
||||
| Frontend React | n/a | operationnel |
|
||||
| Training (TRL/Unsloth) | n/a | operationnel |
|
||||
| Composition pipeline | n/a | operationnel |
|
||||
| Tests (425+) | smoke | unit + component + smoke (425+ pass) |
|
||||
| VoiceChat push-to-talk | n/a | operationnel |
|
||||
| Mediatheque gallery/playlist | n/a | operationnel |
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
process.env.NODE_ENV = "test";
|
||||
|
||||
import { mkdtempSync, rmSync, existsSync, readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import os from "node:os";
|
||||
import { describe, it, beforeEach, afterEach, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { rm } from "node:fs/promises";
|
||||
|
||||
// Create temp dir and chdir into it BEFORE importing composition-store
|
||||
// so that COMP_DIR (process.cwd()/data/compositions) resolves inside the temp dir
|
||||
const testDir = mkdtempSync(path.join(os.tmpdir(), "kxkm-test-comp-"));
|
||||
const originalCwd = process.cwd();
|
||||
process.chdir(testDir);
|
||||
|
||||
// Dynamic import so COMP_DIR uses our temp dir
|
||||
const storePromise = import("./composition-store.js");
|
||||
|
||||
// Cleanup after all tests
|
||||
after(() => {
|
||||
process.chdir(originalCwd);
|
||||
rmSync(testDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
describe("composition-store", () => {
|
||||
it("createComposition creates with id and name", async () => {
|
||||
const { createComposition } = await storePromise;
|
||||
const comp = createComposition("alice", "#music", "My Song");
|
||||
assert.ok(comp.id.startsWith("comp_"), "id should start with comp_");
|
||||
assert.equal(comp.name, "My Song");
|
||||
assert.equal(comp.nick, "alice");
|
||||
assert.equal(comp.channel, "#music");
|
||||
assert.ok(Array.isArray(comp.tracks));
|
||||
assert.equal(comp.tracks.length, 0);
|
||||
assert.ok(comp.createdAt);
|
||||
assert.ok(comp.updatedAt);
|
||||
});
|
||||
|
||||
it("getComposition returns created composition", async () => {
|
||||
const { createComposition, getComposition } = await storePromise;
|
||||
const comp = createComposition("bob", "#studio", "Bob Mix");
|
||||
const found = getComposition(comp.id);
|
||||
assert.ok(found, "should find the composition");
|
||||
assert.equal(found!.id, comp.id);
|
||||
assert.equal(found!.name, "Bob Mix");
|
||||
});
|
||||
|
||||
it("getActiveComposition finds by nick and channel", async () => {
|
||||
const { createComposition, getActiveComposition } = await storePromise;
|
||||
createComposition("carol", "#live", "Carol Live");
|
||||
const active = getActiveComposition("carol", "#live");
|
||||
assert.ok(active, "should find active composition");
|
||||
assert.equal(active!.nick, "carol");
|
||||
assert.equal(active!.channel, "#live");
|
||||
|
||||
const missing = getActiveComposition("carol", "#other");
|
||||
assert.equal(missing, undefined, "should not find for wrong channel");
|
||||
});
|
||||
|
||||
it("addTrack adds to composition tracks", async () => {
|
||||
const { createComposition, addTrack, getComposition } = await storePromise;
|
||||
const comp = createComposition("dave", "#jam", "Dave Jam");
|
||||
const track = addTrack(comp.id, {
|
||||
type: "music",
|
||||
prompt: "ambient drone",
|
||||
duration: 30,
|
||||
volume: 80,
|
||||
startMs: 0,
|
||||
});
|
||||
assert.ok(track, "track should be created");
|
||||
assert.ok(track!.id.startsWith("trk_"), "track id should start with trk_");
|
||||
assert.equal(track!.prompt, "ambient drone");
|
||||
assert.equal(track!.type, "music");
|
||||
|
||||
const updated = getComposition(comp.id);
|
||||
assert.equal(updated!.tracks.length, 1);
|
||||
assert.equal(updated!.tracks[0].id, track!.id);
|
||||
});
|
||||
|
||||
it("addTrack returns null for unknown compId", async () => {
|
||||
const { addTrack } = await storePromise;
|
||||
const result = addTrack("comp_nonexistent", {
|
||||
type: "sfx",
|
||||
prompt: "boom",
|
||||
duration: 2,
|
||||
volume: 100,
|
||||
startMs: 0,
|
||||
});
|
||||
assert.equal(result, null);
|
||||
});
|
||||
|
||||
it("listCompositions filters by nick", async () => {
|
||||
const { createComposition, listCompositions } = await storePromise;
|
||||
// Small delays to avoid Date.now() collisions in ID generation
|
||||
const e1 = createComposition("eve", "#a", "Eve A");
|
||||
await new Promise(r => setTimeout(r, 5));
|
||||
const e2 = createComposition("eve", "#b", "Eve B");
|
||||
await new Promise(r => setTimeout(r, 5));
|
||||
const f1 = createComposition("frank", "#a", "Frank A");
|
||||
|
||||
assert.notEqual(e1.id, e2.id, "eve compositions should have distinct ids");
|
||||
assert.notEqual(e2.id, f1.id, "eve and frank should have distinct ids");
|
||||
|
||||
const eveComps = listCompositions("eve");
|
||||
const eveIds = eveComps.map((c: any) => c.id);
|
||||
assert.ok(eveIds.includes(e1.id), "should contain Eve A");
|
||||
assert.ok(eveIds.includes(e2.id), "should contain Eve B");
|
||||
assert.ok(!eveIds.includes(f1.id), "should not contain Frank A");
|
||||
assert.ok(eveComps.every((c: any) => c.nick === "eve"), "all filtered should be eve");
|
||||
|
||||
const allComps = listCompositions();
|
||||
const allIds = allComps.map((c: any) => c.id);
|
||||
assert.ok(allIds.includes(e1.id), "all should contain Eve A");
|
||||
assert.ok(allIds.includes(f1.id), "all should contain Frank A");
|
||||
});
|
||||
|
||||
it("composition persists to JSON file", async () => {
|
||||
const { createComposition } = await storePromise;
|
||||
const comp = createComposition("grace", "#persist", "Grace Persist");
|
||||
const jsonPath = path.join(testDir, "data", "compositions", comp.id, "composition.json");
|
||||
assert.ok(existsSync(jsonPath), "JSON file should exist on disk");
|
||||
|
||||
const onDisk = JSON.parse(readFileSync(jsonPath, "utf-8"));
|
||||
assert.equal(onDisk.id, comp.id);
|
||||
assert.equal(onDisk.name, "Grace Persist");
|
||||
assert.equal(onDisk.nick, "grace");
|
||||
assert.equal(onDisk.channel, "#persist");
|
||||
});
|
||||
|
||||
it("track has correct type and fields", async () => {
|
||||
const { createComposition, addTrack } = await storePromise;
|
||||
const comp = createComposition("hank", "#fields", "Hank Fields");
|
||||
|
||||
const voiceTrack = addTrack(comp.id, {
|
||||
type: "voice",
|
||||
prompt: "narrator voice",
|
||||
style: "dramatic",
|
||||
duration: 15,
|
||||
volume: 90,
|
||||
startMs: 5000,
|
||||
});
|
||||
|
||||
assert.ok(voiceTrack);
|
||||
assert.equal(voiceTrack!.type, "voice");
|
||||
assert.equal(voiceTrack!.prompt, "narrator voice");
|
||||
assert.equal(voiceTrack!.style, "dramatic");
|
||||
assert.equal(voiceTrack!.duration, 15);
|
||||
assert.equal(voiceTrack!.volume, 90);
|
||||
assert.equal(voiceTrack!.startMs, 5000);
|
||||
assert.ok(voiceTrack!.createdAt, "should have createdAt timestamp");
|
||||
assert.ok(voiceTrack!.id, "should have an id");
|
||||
|
||||
const sfxTrack = addTrack(comp.id, {
|
||||
type: "sfx",
|
||||
prompt: "explosion",
|
||||
duration: 3,
|
||||
volume: 100,
|
||||
startMs: 10000,
|
||||
});
|
||||
assert.ok(sfxTrack);
|
||||
assert.equal(sfxTrack!.type, "sfx");
|
||||
assert.equal(sfxTrack!.filePath, undefined, "filePath should be undefined when not set");
|
||||
});
|
||||
});
|
||||
+27
-18
@@ -109,12 +109,18 @@ flowchart TD
|
||||
|
||||
- [x] 35 music styles ACE-Step
|
||||
- [x] ComfyUI smart checkpoint selection (32 checkpoints + 24 LoRAs)
|
||||
- [ ] lot-178: ACE-Step API direct (duration fix)
|
||||
- [ ] lot-181: TTS voiceover mix into timeline
|
||||
- [ ] lot-182: Audio effects pipeline (reverb, delay, EQ, compression)
|
||||
- [ ] lot-183: DAW export (stems, markers, project file)
|
||||
- [ ] lot-187: Auto-mastering (loudness normalization, limiting)
|
||||
- [ ] lot-188: Stem separation (vocals, drums, bass, other)
|
||||
- [x] lot-184: Multi-track composition (/layer, composition-store)
|
||||
- [x] lot-185: Composition UI (track lanes, play/pause/seek)
|
||||
- [x] lot-186: Arrangement tools (/comp structure, section markers)
|
||||
- [x] lot-187: Auto-mastering (/mix master, loudness normalization, limiter)
|
||||
- [x] lot-188: /voice TTS voiceover injected into composition
|
||||
- [x] lot-189: /noise 5 types (white, pink, brown, rain, wind)
|
||||
- [x] lot-190: /fx 9 audio effects (reverb, delay, chorus, flanger, distortion, bitcrusher, EQ, compressor, tremolo)
|
||||
- [x] lot-191: /ambient scene generator (forest, ocean, city, space, cave)
|
||||
- [ ] lot-194: Waveform visualization (wavesurfer.js)
|
||||
- [ ] lot-195: /remix re-generate specific track
|
||||
- [ ] lot-199: Stem separation (Demucs v4 htdemucs, 6-stem, MIT)
|
||||
- [ ] lot-200: Full DAW export (WAV stems + JSON project)
|
||||
|
||||
### Personas
|
||||
|
||||
@@ -217,13 +223,14 @@ stateDiagram-v2
|
||||
- Privilegier TUI et scripts avec logs lisibles, puis purge des logs obsoletes.
|
||||
- Conserver la V1 comme reference comportementale, V2 comme cible active.
|
||||
|
||||
### Etat de cycle (2026-03-20 18:00)
|
||||
### Etat de cycle (2026-03-20 22:00)
|
||||
|
||||
- 130+ lots termines (lot-24 a lot-177).
|
||||
- 170+ lots termines (lot-24 a lot-191).
|
||||
- 425 tests, 0 failures.
|
||||
- 13 services en production.
|
||||
- 43 chat commands, 33 personas.
|
||||
- 35 music styles (ACE-Step), 5 CSS themes.
|
||||
- 53 chat commands, 33 personas.
|
||||
- 35 music styles (ACE-Step), 9 audio effects, 5 CSS themes.
|
||||
- Composition pipeline: multi-track, voice, noise, ambient, effects, mix.
|
||||
- 32 ComfyUI checkpoints + 24 LoRAs, smart selection NLP.
|
||||
- TTFC 284ms.
|
||||
- Guest mode, mobile responsive.
|
||||
@@ -231,12 +238,14 @@ stateDiagram-v2
|
||||
- Systemd services (TTS + LightRAG).
|
||||
- Frontend: lazy routes (-53%), React.memo, CRT boot, chat virtualization.
|
||||
|
||||
### Prochains lots (178-200) — Composition Pipeline
|
||||
### Prochains lots (192-200) — Composition Advanced
|
||||
|
||||
1. lot-178: Compose duration fix (ACE-Step API direct)
|
||||
2. lot-179: SPEC_COMPOSE_ADVANCED plan
|
||||
3. lot-180: Timeline data model (tracks, clips, markers)
|
||||
4. lot-181: TTS voiceover mix into timeline
|
||||
5. lot-182: Audio effects pipeline (reverb, delay, EQ)
|
||||
6. lot-183: DAW export (stems, markers, project)
|
||||
7. lot-184-200: Multi-track, arrangement, mastering, stem separation, MIDI, templates, collab, lyrics, FX rack, automation, samples, spectral view, history, render queue, sharing
|
||||
1. lot-192: ws-commands modular extraction
|
||||
2. lot-193: Composition tests (unit tests composition-store, /fx)
|
||||
3. lot-194: Waveform visualization (wavesurfer.js @wavesurfer/react)
|
||||
4. lot-195: /remix re-generate specific track
|
||||
5. lot-196: MIDI export from composition
|
||||
6. lot-197: Composition templates (preset multi-track arrangements)
|
||||
7. lot-198: Collaborative composition (multi-user, shared comp)
|
||||
8. lot-199: Stem separation (Demucs v4 htdemucs, MIT, 6-stem)
|
||||
9. lot-200: Full DAW export (WAV stems + JSON project file)
|
||||
|
||||
+10
-1
@@ -217,6 +217,15 @@ flowchart TD
|
||||
| Same-origin check | Verification origine sur les mutations |
|
||||
| RBAC (V2) | Roles admin, editor, operator, viewer |
|
||||
|
||||
## Composition Pipeline (lots 184-191)
|
||||
|
||||
| Fonctionnalite | Detail |
|
||||
| --- | --- |
|
||||
| **Phase 1: Multi-track** | `/compose` generates base track, `/layer` adds tracks, composition-store manages multi-track state |
|
||||
| **Phase 2: Voice & Noise** | `/voice` TTS voiceover injected as track, `/noise` 5 types (white/pink/brown/rain/wind), `/ambient` scene generator (forest/ocean/city/space/cave) |
|
||||
| **Phase 3: Effects & Mix** | `/fx` 9 audio effects (reverb, delay, chorus, flanger, distortion, bitcrusher, EQ, compressor, tremolo), `/mix` merge all tracks with mastering (loudness normalization, limiter) |
|
||||
| **Commands** | `/comp` (composition info/structure), `/layer` (add track), `/mix` (merge + master), `/voice` (TTS layer), `/noise` (noise layer), `/ambient` (scene layer), `/fx` (apply effect) |
|
||||
|
||||
## Fonctionnalites session 2026-03-20 (lots 174-177)
|
||||
|
||||
| Fonctionnalite | Detail |
|
||||
@@ -232,7 +241,7 @@ flowchart TD
|
||||
|
||||
| Fonctionnalite | Detail |
|
||||
| --- | --- |
|
||||
| **43 chat commands** | /help, /nick, /who, /personas, /web, /clear, /status, /model, /persona, /reload, /export, /compose, /imagine, /voice, /memory, /context, /rag, /stats, /uptime, /changelog, /version, /dice, /roll, /flip, /ban, /unban, /mute, /unmute, /whisper, /w, /history, /search, /react, /invite, /time, /date, /session, /speed, + more |
|
||||
| **53 chat commands** | /help, /nick, /who, /personas, /web, /clear, /status, /model, /persona, /reload, /export, /compose, /imagine, /voice, /memory, /context, /rag, /stats, /uptime, /changelog, /version, /dice, /roll, /flip, /ban, /unban, /mute, /unmute, /whisper, /w, /history, /search, /react, /invite, /time, /date, /session, /speed, + more |
|
||||
| **Markdown rendering** | marked + DOMPurify, bold, italic, code blocks, links, lists in chat messages |
|
||||
| **Smart routing** | 5 topic domains (music, philosophy, tech, arts, science), keyword + embedding scoring |
|
||||
| **Dynamic context window** | Adaptive 4k-32k tokens based on conversation length and complexity |
|
||||
|
||||
@@ -338,3 +338,15 @@ Pas de changement par rapport au 19 mars. Tester Qwen3-TTS pour les voix de pers
|
||||
- [react-window v2 Changes](https://github.com/bvaughn/react-window/issues/302)
|
||||
- [react-window Releases](https://github.com/bvaughn/react-window/releases)
|
||||
- [react-window CHANGELOG](https://github.com/bvaughn/react-window/blob/main/CHANGELOG.md)
|
||||
|
||||
### Audio / Composition (recherche 2026-03-20 22:00)
|
||||
- [wavesurfer.js](https://wavesurfer.xyz/) — Waveform visualization, Web Audio API + Canvas, MIT
|
||||
- [@wavesurfer/react](https://www.npmjs.com/package/@wavesurfer/react) — Official React hook + component, all wavesurfer options as props
|
||||
- Plugins: regions (clickable overlays), timeline, spectrogram, minimap, hover, envelope, microphone
|
||||
- Candidat ideal pour lot-194 (waveform visualization dans CompositionView)
|
||||
- [Demucs v4 (htdemucs)](https://github.com/facebookresearch/demucs) — Meta, MIT license, pip install demucs
|
||||
- Hybrid Transformer architecture, SDR 9.20 dB sur MUSDB HQ
|
||||
- 6-stem mode: vocals, drums, bass, other, piano, guitar (htdemucs_6s)
|
||||
- htdemucs_ft (fine-tuned) pour meilleure qualite, mdx_extra pour vitesse
|
||||
- GPU recommande, fonctionne aussi CPU (plus lent)
|
||||
- Candidat ideal pour lot-199 (stem separation)
|
||||
|
||||
Reference in New Issue
Block a user