Skip to main content
Glama
juce_bridge.py3.5 kB
""" juce_bridge.py This file provides a clean, simple OSC-based bridge between the MCP server (Python) and your JUCE synthesizer application or plugin host. The MCP server calls functions here to send instructions to the synth, such as: set_parameter("cutoff", 0.8) The JUCE synth listens on an OSC port (default 9001) and receives messages like: /setParameter cutoff 0.8 You can change the port or OSC address patterns in config.py. """ from pythonosc.udp_client import SimpleUDPClient from typing import List, Optional from .config import JUCE_OSC_HOST, JUCE_OSC_PORT # ------------------------------------------------------------ # OSC client initialization # ------------------------------------------------------------ # SimpleUDPClient(host, port) creates a reusable OSC sender osc_client = SimpleUDPClient(JUCE_OSC_HOST, JUCE_OSC_PORT) # ------------------------------------------------------------ # Core parameter control functions # ------------------------------------------------------------ def set_parameter(param: str, value: float) -> None: """ Send an OSC message to set a parameter in the JUCE synth. The OSC address scheme: /setParameter <paramName> <value> JUCE side: if (msg.getAddressPattern() == "/setParameter") { ... } """ # The OSC protocol is simple: address + arguments osc_client.send_message("/setParameter", [param, float(value)]) def get_parameter(param: str) -> float: """ For now, we do not implement bidirectional OSC (synth → Python). So this function either: A) returns a cached/stored value (if you add a cache), or B) raises NotImplemented, or C) returns a placeholder. For now we return a placeholder so the LLM has something to use. Later, you can add TCP/OSC reply support. """ # TODO: implement bidirectional communication if needed # For now, pretend all parameters default to 0.0 return 0.0 def list_parameters() -> List[str]: """ Return a list of all known parameters. You can hard-code this list, load it from a config file, or eventually query JUCE for a dynamic list. For now, we return a starter set that you will expand. """ return [ "cutoff", "resonance", "attack", "release", "mix", "gain", "osc1Detune", "osc2Detune", ] # ------------------------------------------------------------ # Optional utility (rate-limited ramps, smoothing, etc.) # ------------------------------------------------------------ def ramp_parameter(param: str, start: float, end: float, steps: int = 20) -> None: """ Utility: ramp a parameter smoothly from start → end in N steps. The MCP server can call this via a dedicated tool if you want “smooth sweeps” controlled by the LLM. NOTE: Do NOT call this in a tight loop inside the audio thread — this is Python and therefore control-rate only (fine for UI-level modulation). """ import time if steps <= 1: set_parameter(param, end) return delta = (end - start) / steps current = start for _ in range(steps): current += delta set_parameter(param, current) time.sleep(0.01) # 10 ms step = 100 Hz control rate # ------------------------------------------------------------ # Done — the MCP server now has clean access to your synth! # ------------------------------------------------------------

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TYLERSFOSTER/MCPSynthController'

If you have feedback or need assistance with the MCP directory API, please join our Discord server