jmmariejulie/music-notation-editor

0

stars

9

commits

Python

primary language

Aug 1, 2026

updated

README

Music Notation Editor

A browser-based music notation editor built on Smoosic, with a modular architecture for future AI composing agent integration.

Stack

LayerTechnology
FrontendNext.js 14 (Pages router) + React 18 + TypeScript
Notation engineSmoosic (CDN, via window.Smo)
BackendPython 3.11 + FastAPI

Quick start

Frontend

cd frontend
cp .env.local.example .env.local   # adjust if backend runs elsewhere
npm install
npm run dev                         # http://localhost:3000

Backend

cd backend
python3 -m venv venv
source venv/bin/activate            # Windows: venv\Scripts\activate
pip install -r requirements.txt
uvicorn main:app --reload           # http://localhost:8000

To show Aria MLX model logs when running the API server, set ARIA_LOG_LEVEL:

cd backend
source venv/bin/activate
ARIA_LOG_LEVEL=INFO uvicorn main:app --reload
# or
ARIA_LOG_LEVEL=DEBUG uvicorn main:app --reload

MLX model setup (Aria continuation)

The MLX continuation path uses a locally downloaded model folder and does not download from Hugging Face during each inference call.

cd backend
source venv/bin/activate
python -m ai.download_mlx_model

Default local model directory:

backend/ai/mlx_model/napanto-jazz-piano-performance-modeling/aria-real-time/mlx-deployed

To use a different local model directory, set:

export ARIA_MLX_MODEL_DIR="/absolute/path/to/mlx-model-dir"

Generate continuation from MusicXML (CLI)

You can run continuation directly from a MusicXML file using the MLX Aria model:

cd backend
source venv/bin/activate
python -m ai.continue_from_musicxml_mlx \
    --input-xml tests/resources/input/prime_sample_1.musicxml \
    --output tests/resources/output/prime_sample_1_continued

The command writes three files based on --output:

  • <output>.midi
  • <output>.xml
  • <output>-one-staff.xml

Features (Phase 1)

FeatureStatus
New empty piano score (treble + bass grand staff)
Open existing SMO score (.json)
Import MusicXML
Import MIDI
Export MusicXML
Save score (SMO JSON)
Select parts of the score✅ (built-in Smoosic UI)
Right-click context menu on notes✅ (hook wired, placeholder items)
Play / pause score
Full score editing (notes, rhythms, dynamics, …)✅ (Smoosic built-in editor UI)
Backend score storage✅ (in-memory; swap for DB in production)

Architecture

frontend/
├── pages/
│   ├── _document.tsx        # Loads jQuery + Smoosic CSS/JS from CDN
│   ├── _app.tsx             # Context providers
│   └── index.tsx            # Main editor page
├── components/editor/
│   ├── SmoosicEditor.tsx    # No-SSR Smoosic container
│   ├── EditorToolbar.tsx    # File & playback operations bar
│   └── ContextMenu.tsx      # Right-click context menu
├── context/
│   ├── ScoreContext.tsx     # Score state + file operations
│   └── EditorContext.tsx    # Selection state
└── lib/smoosic/
    └── bridge.ts            # ← AI seam: SmoosicBridge wraps Smoosic API

backend/
├── main.py                  # FastAPI app
├── routers/scores.py        # Score CRUD
└── models/score.py          # Pydantic models

The AI seam — SmoosicBridge

lib/smoosic/bridge.ts is the single interface between the application and Smoosic. All public methods are async and return plain serializable data, making it straightforward to expose them over REST or WebSocket for Phase 2:

AI Agent (Python) ──→ FastAPI backend ──→ REST/WS ──→ SmoosicBridge ──→ Smoosic

Phase 2 roadmap

  • Python AI composing agent (calls bridge.getScoreJson(), sends mutations back)
  • WebSocket channel between backend and frontend for real-time AI suggestions
  • Right-click context menu populated with AI note suggestions
  • Score library view (saved scores from backend)

Contributors

jmmariejulie

9 commits

jmmariejulie/music-notation-editor

0

stars

9

commits

Python

primary language

Aug 1, 2026

updated

README

Music Notation Editor

A browser-based music notation editor built on Smoosic, with a modular architecture for future AI composing agent integration.

Stack

LayerTechnology
FrontendNext.js 14 (Pages router) + React 18 + TypeScript
Notation engineSmoosic (CDN, via window.Smo)
BackendPython 3.11 + FastAPI

Quick start

Frontend

cd frontend
cp .env.local.example .env.local   # adjust if backend runs elsewhere
npm install
npm run dev                         # http://localhost:3000

Backend

cd backend
python3 -m venv venv
source venv/bin/activate            # Windows: venv\Scripts\activate
pip install -r requirements.txt
uvicorn main:app --reload           # http://localhost:8000

To show Aria MLX model logs when running the API server, set ARIA_LOG_LEVEL:

cd backend
source venv/bin/activate
ARIA_LOG_LEVEL=INFO uvicorn main:app --reload
# or
ARIA_LOG_LEVEL=DEBUG uvicorn main:app --reload

MLX model setup (Aria continuation)

The MLX continuation path uses a locally downloaded model folder and does not download from Hugging Face during each inference call.

cd backend
source venv/bin/activate
python -m ai.download_mlx_model

Default local model directory:

backend/ai/mlx_model/napanto-jazz-piano-performance-modeling/aria-real-time/mlx-deployed

To use a different local model directory, set:

export ARIA_MLX_MODEL_DIR="/absolute/path/to/mlx-model-dir"

Generate continuation from MusicXML (CLI)

You can run continuation directly from a MusicXML file using the MLX Aria model:

cd backend
source venv/bin/activate
python -m ai.continue_from_musicxml_mlx \
    --input-xml tests/resources/input/prime_sample_1.musicxml \
    --output tests/resources/output/prime_sample_1_continued

The command writes three files based on --output:

  • <output>.midi
  • <output>.xml
  • <output>-one-staff.xml

Features (Phase 1)

FeatureStatus
New empty piano score (treble + bass grand staff)
Open existing SMO score (.json)
Import MusicXML
Import MIDI
Export MusicXML
Save score (SMO JSON)
Select parts of the score✅ (built-in Smoosic UI)
Right-click context menu on notes✅ (hook wired, placeholder items)
Play / pause score
Full score editing (notes, rhythms, dynamics, …)✅ (Smoosic built-in editor UI)
Backend score storage✅ (in-memory; swap for DB in production)

Architecture

frontend/
├── pages/
│   ├── _document.tsx        # Loads jQuery + Smoosic CSS/JS from CDN
│   ├── _app.tsx             # Context providers
│   └── index.tsx            # Main editor page
├── components/editor/
│   ├── SmoosicEditor.tsx    # No-SSR Smoosic container
│   ├── EditorToolbar.tsx    # File & playback operations bar
│   └── ContextMenu.tsx      # Right-click context menu
├── context/
│   ├── ScoreContext.tsx     # Score state + file operations
│   └── EditorContext.tsx    # Selection state
└── lib/smoosic/
    └── bridge.ts            # ← AI seam: SmoosicBridge wraps Smoosic API

backend/
├── main.py                  # FastAPI app
├── routers/scores.py        # Score CRUD
└── models/score.py          # Pydantic models

The AI seam — SmoosicBridge

lib/smoosic/bridge.ts is the single interface between the application and Smoosic. All public methods are async and return plain serializable data, making it straightforward to expose them over REST or WebSocket for Phase 2:

AI Agent (Python) ──→ FastAPI backend ──→ REST/WS ──→ SmoosicBridge ──→ Smoosic

Phase 2 roadmap

  • Python AI composing agent (calls bridge.getScoreJson(), sends mutations back)
  • WebSocket channel between backend and frontend for real-time AI suggestions
  • Right-click context menu populated with AI note suggestions
  • Score library view (saved scores from backend)

Contributors

jmmariejulie

9 commits

Languages

Python

72.5%

TypeScript

23.3%

CSS

4.1%