Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

31 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

STUDIO MUSICAL — Phase 0

Moteur de rendu musical deterministe. Entree : une partition (.mid / .musicxml). Sortie : un orchestre INSTRUMENTAL execute exactement comme ecrit, reproductible au hash SHA256.

RENDU MECANIQUE — FIDELITE NOTATIONNELLE — TIMBRE SOUNDFONT GM — NON HUMANISE — INSTRUMENTAL

Aucune voix, aucun chant. Aucune donnee fabriquee : un rendu qui echoue est declare, jamais simule en "vert".

Principe

Le rendu offline de FluidSynth est bit-a-bit deterministe pour un triplet (binaire, soundfont, MIDI) donne. Le studio s'appuie sur cette propriete : deux rendus de la meme partition produisent un master.wav au SHA256 identique.

Installation

./install.sh            # idempotent, non-root

install.sh :

  • cree le venv ./venv et installe requirements.txt (+ pytest) ;
  • assure fluidsynth : binaire systeme si present, sinon vendorisation locale non-root (apt-get download + dpkg -x dans vendor/, en s'appuyant sur la libfluidsynth.so deja presente). Si rien n'est possible, declare le BLOCAGE avec la commande exacte a lancer en root ;
  • detecte la soundfont : FluidR3_GM.sf2 prioritaire, sinon TimGM6mb.sf2 (fallback) ;
  • ecrit config.json (chemins sf2 + fluidsynth retenus) ;
  • affiche l'etat reel de chaque dependance.

Sur cette machine : fluidsynth est vendorise localement (pas de sudo), soundfont retenue = TimGM6mb.sf2.

Utilisation

from studio import studio
result = studio.render("partition.mid", basename="ma_piece", out_dir="output")
print(result["master_path"], result["master_sha256"])

render() retourne un dict honnete : chemins, master_sha256, duree, nombre de stems, methode de loudness, etat des dependances. Il leve une exception en cas de blocage reel.

Demo K155 (Mozart, corpus music21)

./venv/bin/python demo_k155.py

Parse mozart/k155/movement1.mxl -> export MIDI -> studio.render() -> output/k155_master.wav + un stem par voix. Rend deux fois et prouve l'egalite SHA256.

Tests

./venv/bin/pytest -q          # 13 tests
  • test_technicien.py — etat reel des dependances (pas de mock "ok").
  • test_regisseur.py — parse OK ; source vide/corrompue/inconnue -> ValueError.
  • test_determinisme.py — rend K155 deux fois, asserte SHA256 master identique.
  • test_pipeline.py — render() -> master.wav non vide + N stems distincts.

Interface web — « Atelier Nocturne » (127.0.0.1:8200)

Une interface web premium pour voir le catalogue réel et piloter la chaîne complète (intention -> composer -> écouter + partition). Design « salle de concert avant le lever de rideau » : nuit bleutée, or/cuivre, frise d'accords, accordage en 4 étapes, visualiseur (vrai spectre WebAudio). Back-end 100 % honnête : il ne reflète que des faits vérifiés sur les fichiers réels et délègue toute la logique à tools/maestro.executer(...).

./tools/serve_web.sh        # idempotent ; affiche URL + mot de passe
  • Accès : http://127.0.0.1:8200, HTTP Basic — utilisateur studio, mot de passe aléatoire généré dans web/.studio_auth (affiché au démarrage).
  • Endpoints : GET / (page), GET /api/pieces (catalogue réel depuis output/*_master.wav), POST /api/composer {intention, nom} (chaîne complète), POST /api/importer (import de partition, voir ci-dessous), GET /api/audio/{nom}, GET /api/pdf/{nom}. Noms validés par regex ([A-Za-z0-9_-]+) : aucune traversée ..//.
  • Isolation : écoute UNIQUEMENT 127.0.0.1:8200, sous l'utilisateur studio, jamais root — aucun rapport avec la prod AutoScan. Accès distant par tunnel SSH : ssh -L 8200:127.0.0.1:8200 <hôte>. Pare-feu non modifié.
  • Tests : tests/test_web.py (auth 401/200, thème + champ d'intention, /api/pieces reflète le disque, POST crée wav+pdf vérifiés, .. rejeté).

Importer une partition manuscrite — pont MuseScore

Écrivez vos notes dans MuseScore (logiciel PC), exportez en .mxl (ou .mid), puis déposez le fichier directement dans l'interface web — sans terminal, sans scp. La section « votre partition » offre une zone de dépôt dorée (drag & drop ou clic), un champ nom optionnel et un champ grille d'accords optionnel (ex. Em C C — vide = déduction automatique), plus un lien « Composer à la main » vers https://musescore.org/fr. L'éditeur MuseScore reste un logiciel PC ; ici on importe le fichier exporté, on ne l'édite pas dans le navigateur.

À l'import, le studio produit TOUJOURS 3 versions et les expose (écoute + PDF) en 3 cartes : BRUTE (telle quelle), CORRIGÉE (notes hors-accord déplacées vers la plus proche — rapport : grille utilisée + nb notes corrigées), INTERPRÉTÉE (nuances liées à la tension, articulation, respiration — 0 hauteur changée, vérifié). La pièce est enregistrée au catalogue avec l'intention « partition importée (MuseScore) ».

  • Skill : studio/skills/importateur.py — importer(chemin_source, nom, grille=None). Opt-in et isolé (rien dans le socle ne l'importe). Le .mxl est converti en MIDI via music21 (même chemin que regisseur) pour le correcteur/chef ; le fichier source d'origine n'est JAMAIS modifié (vérifié par SHA256).
  • API : POST /api/importer (multipart : fichier + nom optionnel + grille optionnelle). Sécurité : extensions limitées à .mxl/.musicxml/.mid/.midi, taille max 5 Mo, nom assaini (regex sûre, pas de ..). Échec d'étape -> erreur réelle déclarée (jamais un faux succès).
  • Tests : tests/test_importateur.py (3 versions wav+pdf vérifiées, 0 hauteur changée, source intacte, format .txt rejeté, grille fournie respectée, API multipart 200/4xx, .. rejeté).

Architecture (studio/)

Role Module Fonction
Technicien technicien.py check_dependencies() reel ; detecte sf2 ; RuntimeError explicite
Regisseur regisseur.py parse .mid/.musicxml -> Partition ; refus net si malforme
Dispatcher dispatcher.py separe en pistes mono-instrument ; mappe programme MIDI -> pupitre
Pupitre pupitre.py rend UNE piste : MIDI mono -> fluidsynth -ni -F (offline)
Chef chef.py somme numpy des stems, gain/pan, alignement duree max
Ingenieur ingenieur.py normalise -14 LUFS (ou peak -1 dBFS si lib absente) ; export 44100/16bit + stems + metadata
Studio studio.py orchestrateur : technicien.check AVANT tout rendu ; render(path) -> dict

studio/skills/ : dossier de contrat des futurs skills perfectionneurs (graveur, interprete, mixeur, bibliothecaire). Non implementes en phase 0 — voir skills/README.md.

Garanties d'honnetete

  • Tout export porte le LABEL ci-dessus. Termes interdits : enregistrement, live, joue par un orchestre, voix, chant.
  • Aucun statut "vert" par defaut : chaque dependance est verifiee effectivement.
  • Determinisme verifie par test (SHA256) et par la demo.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages