Skip to content

Repository files navigation

SV Harmony API

A file-based bridge API that extends Synthesizer V Studio's Lua scripting interface, enabling bidirectional communication between SV and external programs through a pseudo-bus (local JSON files).

Disclaimer

Project Scope: This API is a wrapper for the Synthesizer V Lua scripting interface. It does not modify the Synthesizer V binary.

"SV" in this project refers to Synthesizer V, a product of Dreamtonics Co., Ltd. This project is an independent tool and is not affiliated with, sponsored by, or endorsed by Dreamtonics.

Overview

SV_Harmony_API provides a JSON Loop IO Bridge that runs inside Synthesizer V Studio as a Lua script. It continuously exports the live project state to a JSON file and monitors a second JSON file for incoming changes from external programs. This pseudo-bus architecture allows any external tool -- written in Python, C#, Node.js, or any language -- to read, manipulate, and write back project data (notes, parameters, tracks, tempo, etc.) while SV is running.

The system is split into two scripts:

Script Purpose
Harmony Bridge (HarmonyBridge.lua) Runtime: starts the bridge loop on click. No UI dialogs.
Harmony Settings (HarmonySettings.lua) Configuration UI: update interval, work mode, end detection silence, working directory, session cleanup. Saves to Harmony_Config.json.

Why a Pseudo-Bus?

Synthesizer V's Lua scripting sandbox does not expose sockets, named pipes, or any network/IPC primitives. The only available I/O is io.open() for local files and SV:setTimeout() for scheduling. SV_Harmony_API leverages these two primitives to build a poll-based, dual-file IPC channel using the local filesystem as the communication medium.

Architecture

+----------------------------+          +----------------------------+
|   Synthesizer V Studio     |          |   External Program         |
|                            |          |   (Python, C#, etc.)       |
|  +----------------------+  |          |  +----------------------+  |
|  | Harmony Bridge       |  |          |  | Reads/writes JSON    |  |
|  | (HarmonyBridge.lua)  |  |          |  |                      |  |
|  +------+----------+----+  |          |  +----+-----------+-----+  |
|         |          ^        |          |       ^           |        |
+---------+----------|-------+          +-------|-----------|-------+
          |          |                          |           |
          v          |                          |           v
   {uuid}_out.json   |                          |    {uuid}_in.json
   (SV --> External)  |                          |    (External --> SV)
                      +--------------------------+

                    Harmony/ working directory
                    (default: ~/Documents/Dreamtonics/Synthesizer V Studio/Harmony/)

Session-based file naming: Each loop session generates a unique UUID. Bridge files are named {uuid}_out.json and {uuid}_in.json in the Harmony working directory. Session metadata is tracked in Harmony_Session.json.

Two bridge files prevent read/write collisions:

File Direction Writer Reader
{uuid}_out.json SV --> External SV (every tick) External program
{uuid}_in.json External --> SV External program SV (every tick)
{uuid}_cmd_in.json External --> SV External program SV (cmd poll tick)
{uuid}_cmd_out.json SV --> External SV (after exec) External program
Harmony_Lock.json Toggle signal Bridge (on start) Bridge (on click)

The bridge uses asynchronous phased export: each export cycle is split into multiple phases (metadata → one track per tick → JSON encoding → file write), spreading work across several timer ticks to avoid blocking the SV main thread. In Full mode, an import is performed after each export cycle completes.

Toggle mechanism: Harmony_Lock.json records the active session ID. Clicking Harmony Bridge a second time detects this file and deletes it, which the running loop interprets as a stop signal at the next tick.

Features

  • Bidirectional sync -- export project state and import external modifications in real-time
  • Async phased export -- export is split across multiple timer ticks (meta → track → encode → write) to avoid blocking the SV main thread
  • Segment-based parameter fetching -- parameter curves are fetched in segments, supporting arbitrarily long songs without a fixed time limit
  • Configurable end detection -- export range ends after a configurable silence gap (15s/30s/60s/120s with no notes), eliminating the old ~10-minute hard limit
  • Pretty-printed JSON -- output uses indented formatting for git-friendliness and human readability
  • Resilient import -- tolerates transient _in.json file absence (e.g., during atomic file replacement by external tools) for up to 60 seconds before reporting an error
  • Work modes -- Full (alternating export/import), Export Only, or Import Only (configurable in Settings)
  • Session cleanup -- stale sessions auto-detected and removable via Settings checkbox
  • SVP-compatible JSON format -- output matches the official .svp file structure
  • Full project coverage -- notes, 8 parameter curves (pitchDelta, vibratoEnv, loudness, tension, breathiness, voicing, gender, toneShift), tempo, time signatures, mixer settings, render config
  • Zero dependencies -- includes a built-in pure-Lua JSON encoder/decoder
  • Session management -- UUID-based sessions with auto-expiry, tracked in Harmony_Session.json
  • Field-level diff import -- only modifies notes/parameters that actually changed
  • Change detection -- only applies imports when file content actually changes
  • CMD execution channel (opt-in, disabled by default) -- external programs can request arbitrary shell commands to be run inside SV Studio and retrieve stdout; independent poll interval, hard limits on command/output size, full error reporting
  • Configurable -- update interval, work mode, end detection silence, working directory, and CMD settings via the Settings script
  • Localization -- UI supports English and Simplified Chinese

MCP entry

A local stdio MCP server exposes the bridge to any MCP-capable agent. It binds no model and runs no agent loop — those belong to whatever client connects.

Tool Description
harmony_read Return the latest project snapshot exported by HarmonyBridge
harmony_cmd Execute one Lua chunk inside SV Studio via the CMD channel
harmony_capabilities Report running sessions, enabled channels, and which writes this bridge supports

This bridge covers the scripting API layer: same-version reads and writes against the live project. It cannot render audio or save the project — the SV scripting API has neither, and bounce is a frozen-state flag rather than an export. Carrying a render across SV versions and driving an export are separate layers.

Build and register

npm install
npm run build

Register the built entry point with your MCP client as a local stdio server:

node <repo>/dist/src/cli.js

The server resolves the Harmony working directory from HARMONY_DIR, falling back to %USERPROFILE%\Documents\Dreamtonics\Synthesizer V Studio\Harmony. Set HARMONY_DIR when Node and SV Studio do not resolve the same path.

Note: HarmonyBridge must be running in SV Studio for either tool to return data, and harmony_cmd additionally requires the CMD channel to be enabled in Harmony Settings.

External programs that are not MCP clients can keep talking to the bridge files directly — see JSON Data Format and docs/CmdExecution.md.

Requirements

  • Synthesizer V Studio v1.0.1+ (some features like getMixer() require v2.1.1+)
  • Operating System: Windows (path handling supports both / and \)
  • No external Lua installation or libraries required
  • MCP entry: Node.js 20.10+

Installation

Quick install (Windows)

Run install.bat. It will:

  1. Auto-detect (or prompt for) your SV Studio scripts folder and copy both Lua scripts.
  2. Scan for installed AI clients — Claude Code, GitHub Copilot, Cursor, Open Interpreter, OpenAI Codex CLI, Continue.dev — and ask whether to install the Harmony skill into each one's config.

After running: in SV Studio go to Scripts > Rescan.

Manual install

Copy both scripts into your SV Studio scripts directory (find it via Scripts > Open Scripts Folder):

HarmonyBridge.lua
HarmonySettings.lua

To give your AI assistant context about the bridge, copy skill\HarmonyBridge-skill\SKILL.md into your AI client's instruction/rules config (see the table below). Clients that support skill folders can load skill\HarmonyBridge-skill\ directly, which also brings in the bundled SV scripting API reference.

AI Client Where to add the skill
Claude Code ~/.claude/skills/sv-harmony/ (copy the whole folder — this is what install.bat does)
Cursor ~/.cursor/rules/sv-harmony.mdc
OpenAI Codex CLI ~/.codex/instructions.md
GitHub Copilot Repo: .github/copilot-instructions.md · Global: VS Code settings github.copilot.chat.codeGeneration.instructions
Open Interpreter Append to ~/.openinterpreter under custom_instructions:
Continue.dev ~/.continue/rules/sv-harmony.md, then reference in config.json

Usage

  1. Save your project (Ctrl+S) before running the bridge. The script reads the .svp file on disk to extract voice library (database) and systemPitchDelta data that are not accessible through the scripting API.

  2. (Optional) Configure settings: From the Scripts menu, select Harmony Settings to set the update interval, work mode, end detection silence, and working directory. Settings are saved to Harmony_Config.json.

    Work modes:

    Mode Behavior Use case
    Full (default) Async phased export, then import after each export cycle completes Normal bidirectional workflow
    Export Only Async phased export every cycle, no import Read-only external tools (monitoring, analysis)
    Import Only Import every tick, no export One-way external control

    End Detection Silence:

    Setting Behavior
    15s Export range stops 15 seconds after last note
    30s (default) Export range stops 30 seconds after last note
    60s Export range stops 60 seconds after last note
    120s Export range stops 120 seconds after last note

    Note: Export Only / Import Only should only be used if the external script requires it or you know what you are doing. The default Full mode is recommended for most use cases.

  3. Start the bridge: From the Scripts menu, select Harmony Bridge. The loop starts immediately (no dialog). The Harmony working directory will be created automatically if needed.

  4. Stop the bridge: Click Harmony Bridge again. The script detects the running instance via a lock file (Harmony_Lock.json) and sends a stop signal. The running loop stops at the next tick and cleans up automatically. Only one bridge instance can run per SV editor at a time.

  5. For external program integration, write your tool to:

    • Read Harmony_Session.json to discover the active session UUID and file paths
    • Read {uuid}_out.json to get the current SV project state
    • Write {uuid}_in.json to push changes back into SV

WARNING: Switching .svp projects while a session is running

You must stop the bridge before opening or switching to a different .svp project. The session is bound to the project that was active when it started. If you switch projects without stopping first, the bridge will continue exporting/importing against the wrong project context. The resulting behavior is undefined -- you have been warned.

Session Cleanup

Over time, stale sessions and orphan bridge files can accumulate in the Harmony working directory. To clean them up, open Harmony Settings and check the Clean Sessions checkbox before clicking OK.

Cleanup rules:

  • Sessions with state == "stopped" are removed immediately, along with their bridge files.
  • Sessions with state == "running" that have not updated their heartbeat in >60 seconds are considered dead and removed, along with their bridge files.
  • After session cleanup, all *_out.json / *_in.json files in the working directory are scanned. Any files whose UUID does not belong to a surviving session are deleted as orphans.

Bridge File Location

Bridge files are created in the Harmony working directory:

~/Documents/Dreamtonics/Synthesizer V Studio/Harmony/

This can be overridden in Harmony Settings. The directory is created automatically on first run.

JSON Data Format

The bridge produces JSON structurally identical to the official .svp format. Time values use blicks (1 quarter note = 705,600,000 blicks).

{
  "version": 153,
  "time": {
    "meter": [{ "index": 0, "numerator": 4, "denominator": 4 }],
    "tempo": [{ "position": 0, "bpm": 120.0 }]
  },
  "tracks": [{
    "name": "Track 1",
    "mixer": { "gainDecibel": 0.0, "pan": 0.0, "mute": false, "solo": false },
    "mainGroup": {
      "notes": [{
        "onset": 0,
        "duration": 705600000,
        "pitch": 60,
        "lyrics": "la",
        "phonemes": ""
      }],
      "parameters": {
        "pitchDelta":   { "mode": "cubic", "points": [] },
        "vibratoEnv":   { "mode": "cubic", "points": [] },
        "loudness":     { "mode": "cubic", "points": [] },
        "tension":      { "mode": "cubic", "points": [] },
        "breathiness":  { "mode": "cubic", "points": [] },
        "voicing":      { "mode": "cubic", "points": [] },
        "gender":       { "mode": "cubic", "points": [] },
        "toneShift":    { "mode": "cubic", "points": [] }
      }
    }
  }],
  "renderConfig": { "sampleRate": 44100, "bitDepth": 16 }
}

Known Limitations

  • Latency: Configurable polling interval (default 1s); in Full mode, one complete export-then-import cycle spans multiple ticks due to phased export
  • No file locking: An external program could theoretically read a partially-written file
  • Voice library: Database info is read from the saved .svp file, not from the live editor. Changing the voice library requires saving the project first
  • Project switching: You must stop the session before switching .svp projects. Behavior is undefined otherwise

Project Structure

HarmonyBridge.lua          # Runtime bridge (starts loop on click, no UI)
HarmonySettings.lua        # Settings UI (interval, work mode, working dir, session cleanup)
install.bat                # One-click installer: copies scripts + installs AI skill to detected clients
uninstall.bat              # Removes installed scripts, skill entries, and optionally session data
LICENSE.txt                # ALE 1.1 + GPL v3.0 dual license
src/
  cli.ts                   # MCP stdio entry point
  config.ts                # Harmony working directory resolution
  session.ts               # Harmony_Session.json reading and session selection
  harmony-ipc.ts           # Snapshot read and CMD request/poll
  server.ts                # Two-tool MCP surface: harmony_read, harmony_cmd
skill/
  HarmonyBridge-skill/
    SKILL.md               # AI assistant skill: MCP tools, file protocol, data schema, examples
    references/sv-api.md   # Synthesizer V scripting API reference
docs/
  CmdExecution.md          # CMD execution channel: protocol, error handling, Python example, API ref

License

This project is dual-licensed under the Anti-Labor Exploitation License 1.1 and GNU General Public License v3.0. The permissions granted under GPL v3.0 are conditional upon full compliance with ALE 1.1. See LICENSE.txt for details.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages