multi-synth-execute
Execute multiple SynthDefs simultaneously in SuperCollider-MCP, allowing parallel synthesis with customizable duration and control over each synth's parameters.
Instructions
複数のSynthDefを同時に実行します。
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| duration | No | 再生時間(ミリ秒)。デフォルトは10000(10秒) | |
| synths | Yes | 再生するシンセのリスト |
Input Schema (JSON Schema)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration": {
"description": "再生時間(ミリ秒)。デフォルトは10000(10秒)",
"type": "number"
},
"synths": {
"description": "再生するシンセのリスト",
"items": {
"additionalProperties": false,
"properties": {
"code": {
"description": "シンセのコード",
"type": "string"
},
"name": {
"description": "シンセの名前",
"type": "string"
}
},
"required": [
"name",
"code"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"synths"
],
"type": "object"
}
Implementation Reference
- src/index.ts:143-207 (registration)Registration of the 'multi-synth-execute' tool using server.tool(), including inline schema and handler.server.tool( "multi-synth-execute", "複数のSynthDefを同時に実行します。", { synths: z.array( z.object({ name: z.string().describe("シンセの名前"), code: z.string().describe("シンセのコード") }) ).describe("再生するシンセのリスト"), duration: z.number().optional().describe("再生時間(ミリ秒)。デフォルトは10000(10秒)") }, async ( { synths, duration = 10000 }: { synths: { name: string, code: string }[], duration?: number } ) => { try { const scServer = await initServer(); const synthPromises = []; for (const synth of synths) { synthPromises.push(loadAndPlaySynth(scServer, synth.name, synth.code)); } const loadedSynths = await Promise.all(synthPromises); console.error(`${synths.length}個のシンセを${duration / 1000}秒間演奏中...`); await new Promise(resolve => setTimeout(resolve, duration)); await cleanupServer(); console.error('複数シンセの演奏完了'); return { content: [ { type: "text", text: `${synths.length}個のシンセを同時に再生しました。`, }, { type: "text", text: `再生したシンセ: ${synths.map(s => s.name).join(', ')}`, }, { type: "text", text: `合計再生時間: ${duration / 1000}秒`, } ], }; } catch (error) { console.error("複数シンセ実行エラー:", error); return { content: [ { type: "text", text: `エラーが発生しました: ${error instanceof Error ? error.message : JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, } ], }; } } );
- src/index.ts:155-206 (handler)The main handler function that orchestrates loading and playing multiple synths in parallel using Promise.all, waits for the specified duration, cleans up the server, and returns a response with details.async ( { synths, duration = 10000 }: { synths: { name: string, code: string }[], duration?: number } ) => { try { const scServer = await initServer(); const synthPromises = []; for (const synth of synths) { synthPromises.push(loadAndPlaySynth(scServer, synth.name, synth.code)); } const loadedSynths = await Promise.all(synthPromises); console.error(`${synths.length}個のシンセを${duration / 1000}秒間演奏中...`); await new Promise(resolve => setTimeout(resolve, duration)); await cleanupServer(); console.error('複数シンセの演奏完了'); return { content: [ { type: "text", text: `${synths.length}個のシンセを同時に再生しました。`, }, { type: "text", text: `再生したシンセ: ${synths.map(s => s.name).join(', ')}`, }, { type: "text", text: `合計再生時間: ${duration / 1000}秒`, } ], }; } catch (error) { console.error("複数シンセ実行エラー:", error); return { content: [ { type: "text", text: `エラーが発生しました: ${error instanceof Error ? error.message : JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, } ], }; } }
- src/index.ts:146-154 (schema)Zod schema defining the input parameters: an array of synth objects (name and code) and optional duration in ms.{ synths: z.array( z.object({ name: z.string().describe("シンセの名前"), code: z.string().describe("シンセのコード") }) ).describe("再生するシンセのリスト"), duration: z.number().optional().describe("再生時間(ミリ秒)。デフォルトは10000(10秒)") },
- src/index.ts:48-53 (helper)Helper function called for each synth to load the SynthDef and start playing it, tracking active synths.async function loadAndPlaySynth(scServer: SCServer, synthName: string, synthCode: string): Promise<any> { const def = await scServer.synthDef(synthName, synthCode); const synth = await scServer.synth(def); activeSynths.push(synth); return synth; }
- src/index.ts:21-46 (helper)Initializes and boots the SuperCollider server instance, with singleton-like caching.async function initServer(): Promise<SCServer> { if (serverInitPromise) { return serverInitPromise; } serverInitPromise = (async () => { try { console.error("SuperColliderサーバーを起動中..."); const server = await (sc as any).server.boot({ debug: false, echo: false, stderr: './supercollider-error.log' }) as SCServer; console.error("SuperColliderサーバー起動完了"); scServerInstance = server; return server; } catch (err) { console.error("SuperColliderサーバー起動エラー:", err); serverInitPromise = null; throw err; } })(); return serverInitPromise!; }