Un'app React per comporre e suonare una partitura musicale su endecalineo (i due pentagrammi di violino e basso uniti dal Do centrale).
Sotto-progetto web, indipendente dall'app macOS AudioLens che vive nella stessa repository.
-
Endecalineo — pentagramma di violino + pentagramma di basso, con graffa, chiavi, Do centrale su taglio addizionale e tagli addizionali sopra/sotto calcolati automaticamente.
-
Palette di inserimento
- Strumento: Note / Pause
- Durata: intero, metà, quarto, ottavo, sedicesimo, trentaduesimo
- Punti di valore (0, 1, 2)
- Alterazioni: naturale, diesis (♯), bemolle (♭)
-
Divisione della battuta — 2/4, 3/4, 4/4, 5/4, 6/8, 9/8, 12/8, 3/8, 2/2.
-
Inserimento a hover & click (prima modalità del requisito):
- Scegli una durata dalla palette.
- Muovendo il mouse sulla battuta appare l'anteprima della nota in grigio, con eventuali tagli addizionali.
- Click su uno spazio libero → nuova nota singola.
- Click dove c'è già una nota (altra altezza) → accordo (note contemporanee, stessa durata).
- Click su una nota già presente → la cancella.
- Stesso comportamento per le pause; con lo strumento pausa un click su una nota di pari valore la sostituisce con la pausa.
L'anteprima cambia colore per anticipare l'azione: grigio = inserisci, blu = accordo, rosso = cancella.
-
Freccia — lo strumento puntatore (icona della freccia del mouse) non crea note: trascinando una nota la si alza/abbassa di intonazione, un clic in un punto vuoto sposta l'indicatore di playback/inserimento.
-
Larghezza battute — slider 100–200% nella fascia «Brano»: allarga tutte le battute per i brani troppo densi di note; salvato con il brano (vale anche nella pagina di ascolto), si somma all'allargamento automatico delle battute più fitte. Nelle righe a doppio rigo le travature che invaderebbero l'altro rigo vengono accorciate o ribaltate.
-
Toolbar compatta e richiudibile — il toggle ▲/▼ a destra della riga del playback (o il tasto
H) nasconde fascia brano e palette lasciando solo il playback, con un riassunto dello strumento attivo (clic per riaprire). Il chip «▸ Brano» apre/chiude la fascia con tempo, armatura, vista, file e libreria (chiusa di default). Entrambe le scelte sono ricordate tra le sessioni. -
Due viste
- Orizzontale: la partitura è un unico rigo che scorre a sinistra/destra (anche automaticamente durante il playback).
- Pagina: le battute vanno a capo in più righe/sistemi; durante il playback lo scorrimento è verticale.
-
Playback (Web Audio) con BPM regolabile e un cursore verticale evidenziato che segue le note suonate, con auto-scroll.
-
Strumenti campionati — accanto al Play si sceglie lo strumento (piano, archi, fiati, chitarre, … con relativa icona). I campioni si scaricano lazy al primo uso e la scelta è ricordata tra le sessioni; il synth storico dell'app resta disponibile come "8 bit sound".
-
Mixer per rigo — lo strumento generale può anche essere «—» (nessuna scelta) e l'icona del mixer accanto apre un pannellino con, per ogni rigo, strumento (ha priorità su quello generale), volume, mute/solo (M ammutolisce il rigo; con uno o più S premuti suonano solo quelli), trasposizione in semitoni (es. +12 per un basso notato un'ottava sopra) e canale MIDI per l'uscita MIDI («—» usa quello generale del brano), più una trasposizione generale che si somma a quelle di rigo. I controlli agiscono in tempo reale anche durante il playback. Tutto viene salvato nel JSON del brano; al caricamento uno strumento generale «—» mantiene quello già impostato. Il mixer (solo la parte audio) è disponibile anche nella pagina di ascolto condivisa, per ribilanciare i volumi.
-
Pentagrammi aggiuntivi — dal pannellino del mixer si aggiungono righi singoli (con chiave di violino o basso a scelta) o interi endecalinei sopra e sotto quelli esistenti (es. una voce sopra il piano, o una partitura per due pianoforti). Ogni rigo ha il suo strumento, volume, trasposizione e anche una tonalità propria («= brano» segue quella del brano e i suoi cambi; una tonalità fissa serve agli strumenti traspositori). Ogni rigo si può mostrare/nascondere (nascosto continua a suonare) — si può quindi disattivare anche l'endecalineo, in tutto o in parte. Tutti i righi sono uniti dalla linea verticale iniziale; ogni endecalineo conserva la sua graffa. Nel mixer i pentagrammi si riordinano trascinandoli dalla maniglia ⋮⋮ (i due righi di un endecalineo sono legati e si spostano insieme). La configurazione dei righi è salvata nel JSON e viaggia in MusicXML (una parte per rigo/endecalineo).
-
Batteria — dal mixer «+ Batteria» aggiunge un rigo di percussione (chiave neutra, niente armatura). Un menu Batteria nella palette sceglie la voce (grancassa, rullante, rim shot, hi-hat chiuso/aperto/pedale, crash, ride, tom alto/medio/basso); cliccando sul rigo si inserisce la voce alla sua posizione standard, con le teste corrette (✕ per hi-hat e piatti, ⊗ per il rim shot). Più voci sullo stesso movimento (grancassa + rullante + hi-hat) si impilano su un gambo unico. Trascinando una nota di batteria non diventa una nota intonata: si sposta sulla voce di batteria più vicina. Nel mixer si sceglie il kit del rigo: Sintetico (Web Audio, offline, nessun download) o Acustico (campioni scaricati al primo uso; se non raggiungibili ripiega sul sintetico). In MIDI le voci vanno sul canale 10 con le note General-MIDI standard. Volume, mute/solo e trasposizione del rigo funzionano come per gli altri.
-
Accordi — con lo strumento Accordo (1 click: una volta · doppio: fisso) si scrive il nome dell'accordo sotto il pentagramma (o endecalineo) su cui si clicca: ogni rigo può avere la propria linea di accordi, che lo segue anche aggiungendo o riordinando altri righi. Agganciato a una griglia di ottavi nel punto cliccato; testo libero (nessun controllo); clic su un accordo esistente per modificarlo, testo vuoto per eliminarlo. I file salvati prima di questa funzione mettono le loro sigle sotto l'endecalineo classico, come erano.
-
Testo — con lo strumento Testo (1 click: una volta · doppio: fisso) si scrive testo libero sopra un rigo (didascalie, istruzioni: in corsivo) o sotto (testo della canzone): si clicca nel punto voluto e il testo parte da lì sviluppandosi verso destra (gli accordi invece sono centrati); gli spazi iniziali sono conservati, per l'allineamento fine delle sillabe. Ogni rigo può avere le sue righe di testo; quando sotto lo stesso rigo ci sono sia testo che accordi, gli accordi scendono sotto il testo. Clic su un testo esistente per modificarlo, testo vuoto per eliminarlo.
-
Staccato — con lo strumento Staccato si clicca su una nota o un accordo per il puntino (sul lato opposto al gambo); nel playback suona una frazione della durata scritta (regolabile nelle Opzioni).
-
Arpeggiato — con lo strumento Arpeggio si trascina in verticale sulle note da arpeggiare: la linea ondulata compare a sinistra e nel playback le note attaccano scaglionate dal grave all'acuto (velocità regolabile nelle Opzioni), tenendo tutte fino alla fine. Un trascinamento che copre entrambi i pentagrammi crea un arpeggio unico trans-rigo; ripetere il gesto toglie l'arpeggio.
-
Ritornelli — con lo strumento Ritornello: clic nella metà sinistra di una battuta per il segno di inizio
|:, nella metà destra per quello di fine:|. Trascinando in verticale sul segno di inizio si imposta il numero di esecuzioni (mostrato sopra il segno se ≠ 1); sotto l'1 diventa ∞ e la sezione va in loop nel playback. Doppio clic su un segno per eliminarlo. Il playback (audio e MIDI) espande i ritornelli.
cd score-composer
npm install
npm run dev # server di sviluppo (http://localhost:5173) — solo frontendAltri comandi:
npm run build # type-check + build di produzione in dist/
npm run preview # anteprima della build
npm run typecheck # solo controllo dei tipiI brani della lista condivisa vivono in Netlify Blobs, serviti dalla
funzione netlify/functions/api.mts (rotte /api/*). Per lo sviluppo con
il backend attivo:
npx netlify dev # frontend + funzioni + Blobs locali (richiede netlify-cli)Sul sito Netlify va impostata la variabile d'ambiente ADMIN_PASSWORD:
è la password della pagina di gestione (#/admin). Senza variabile le
scritture sono disabilitate (le letture restano pubbliche).
#/— l'editor. Il menu Libreria è calcolato dalla lista sul server (i brani con il flag "nel menu"). Chiunque può aprire un brano, modificarlo in locale ed esportarlo in JSON; la lista sul server non cambia. Alla prima lettura lo store viene seminato con i brani di esempio integrati. Il brano in lavorazione è autosalvato di continuo nel localStorage del browser: chiudendo o ricaricando la pagina per sbaglio si riparte da dove si era rimasti. Il pulsante ✚ Nuovo nell'intestazione chiude il brano corrente (con conferma) e ne inizia uno vuoto.#/admin— gestione della lista (con password, ricordata sul browser finché non si preme Logout): aggiungi il brano corrente, ⤴ Aggiorna sostituisce il contenuto di un brano in lista con quello corrente dell'editor mantenendo lo stesso link di condivisione, importa/esporta JSON, rinomina, riordina, elimina, scegli se un brano compare nel menu dell'editor, copia il link di ascolto. Il campo 🔍 Cerca filtra la lista per nome in tempo reale.#/play/:id— versione solo ascolto di un brano, pensata per essere condivisa: partitura e controlli di playback, nessuno strumento di modifica. La scheda del browser prende il titolo del brano.#/libreria— la libreria pubblica: una vetrina visibile a chiunque abbia il link, con i brani che in Gestione brani hanno il flag «Nella libreria pubblica» (checkbox accanto a «Nel menu»). Schede di sola consultazione — anteprima (clic = ascolta), titolo, data di aggiornamento, BPM, Prova e Condividi — più la ricerca per nome./p/:id— il link di condivisione che l'admin copia/mostra: una piccola pagina server (netlify/functions/play.mts) con<title>e tag Open Graph presi dal titolo del brano — così l'anteprima di WhatsApp/Telegram/social mostra il nome della canzone (i bot non eseguono JS e non vedono i frammenti#…) — che poi inoltra il visitatore a#/play/:id. I vecchi link#/play/…restano validi.
Il pulsante «?» accanto all'ingranaggio delle Opzioni (o il rimando nel
footer) apre il manuale completo dell'app: tutte le funzionalità, gli
strumenti della palette e le scorciatoie, organizzati in sezioni richiudibili.
Il manuale vive in src/components/ManualDialog.tsx e va aggiornato insieme a
ogni nuova funzionalità.
| Tasto | Azione |
|---|---|
1–6 |
durata (intero → trentaduesimo) |
. |
cicla i punti di valore |
R |
alterna Note / Pause |
Spazio |
play / stop |
H |
mostra/nasconde fascia brano e palette |
⌘/Ctrl+Z |
annulla |
⌘/Ctrl+⇧+Z (o Ctrl+Y) |
ripristina (redo) |
src/
music/
constants.ts geometria del rigo e risoluzione ritmica (tick)
types.ts modello dati (Pitch, Duration, Event, Measure, Score)
theory.ts altezza↔posizione diatonica, frequenze, durate in tick
layout.ts mappatura diatonica↔y, tagli addizionali, sistemi/battute
placement.ts regole crea/accordo/cancella/bloccato
smufl.ts code point SMuFL (Bravura) usati
audio.ts scheduler e player Web Audio + playhead
instruments.ts catalogo strumenti campionati e lazy loading dei sample
drums.ts voci di batteria (posizioni, teste, note General-MIDI)
drumkit.ts kit di batteria sintetizzato (Web Audio, offline)
playback.ts strumenti/volumi/trasposizioni per rigo (salvati nel brano)
staves.ts elenco righi del brano e layout verticale multi-rigo
state/
scoreReducer.ts stato della partitura e azioni
components/
Toolbar.tsx palette, battuta, vista, trasporto
Score.tsx contenitore, layout dei sistemi, auto-scroll del playhead
System.tsx un endecalineo: rigo, chiavi, battute, hover/click, playhead
Note.tsx testa/e, gambo, code (flag), tagli addizionali, alterazioni, punti
Rest.tsx pause
InstrumentIcon.tsx icone SVG degli strumenti del playback
MixerPanel.tsx pannellino con strumento/volume/trasposizione per rigo
App.tsx stato dell'interfaccia e collegamenti
Modello del tempo. Ogni battuta è lunga numeratore × (768 / denominatore)
tick (768 tick = semibreve). Gli eventi hanno startTick e durata in tick; la
posizione orizzontale è proporzionale al tick, quella verticale è la "posizione
diatonica" (ogni linea/spazio = 1 passo, Do centrale = 28).
Rendering. Linee del rigo, tagli addizionali, teste di nota, gambi, punti, stanghette e playhead sono disegnati come primitive SVG; chiavi, pause, alterazioni, code e cifre di tempo usano i glifi del font musicale Bravura (SMuFL), dove 1em = 4 spazi del rigo.
- Niente travature (le crome/semicrome hanno code singole), né gruppi irregolari (terzine).
- Niente armatura di chiave; le alterazioni sono per singola nota.
- Le note contemporanee sono modellate come accordi (stessa durata), non come voci indipendenti.
- Export PDF: nel menu del pulsante Salva (tieni premuto o clic destro), «PDF (stampa)» apre il dialogo di stampa del browser («Salva come PDF») su una vista dedicata: impaginazione A4 in modalità Pagina a densità da carta (impaginato largo e ridotto al 50%: pentagramma ~6mm, molte più battute per rigo e righi per pagina che a schermo), titolo in testa, niente cursore, sistemi mai spezzati tra le pagine, font musicale incorporato (output vettoriale).
- Export/import MusicXML (
.musicxml): i pulsanti di export (Salva nell'editor, JSON nella pagina admin) esportano in JSON al clic e aprono un menu JSON/MusicXML tenendoli premuti; Carica/Importa accettano anche.musicxml/.xml. L'export copre tutto il modello (ritornelli inclusi, ∞ =times="0"); l'import è pensato per i file esportati dall'app e ignora ciò che non riconosce. Export MIDI non ancora presente.
- Codice: vedi la licenza della repository (GPL-3.0-or-later).
- Font Bravura (
src/assets/Bravura.woff) — SIL Open Font License 1.1, © Steinberg Media Technologies GmbH. Testo insrc/assets/Bravura-OFL.txt. - Campioni degli strumenti da nbrosowsky/tonejs-instruments — Creative Commons Attribution 3.0 (CC-BY 3.0) — e Salamander Grand Piano di Alexander Holm (CC-BY 3.0), serviti via tonejs.github.io.
