talkback-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context-assembler.d.ts +7 -0
- package/dist/context-assembler.d.ts.map +1 -0
- package/dist/context-assembler.js +181 -0
- package/dist/context-assembler.js.map +1 -0
- package/dist/heuristics/dynamics.d.ts +3 -0
- package/dist/heuristics/dynamics.d.ts.map +1 -0
- package/dist/heuristics/dynamics.js +53 -0
- package/dist/heuristics/dynamics.js.map +1 -0
- package/dist/heuristics/frequency-buildup.d.ts +3 -0
- package/dist/heuristics/frequency-buildup.d.ts.map +1 -0
- package/dist/heuristics/frequency-buildup.js +69 -0
- package/dist/heuristics/frequency-buildup.js.map +1 -0
- package/dist/heuristics/headroom.d.ts +3 -0
- package/dist/heuristics/headroom.d.ts.map +1 -0
- package/dist/heuristics/headroom.js +54 -0
- package/dist/heuristics/headroom.js.map +1 -0
- package/dist/heuristics/index.d.ts +3 -0
- package/dist/heuristics/index.d.ts.map +1 -0
- package/dist/heuristics/index.js +22 -0
- package/dist/heuristics/index.js.map +1 -0
- package/dist/heuristics/routing.d.ts +3 -0
- package/dist/heuristics/routing.d.ts.map +1 -0
- package/dist/heuristics/routing.js +60 -0
- package/dist/heuristics/routing.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +4 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +437 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/param-maps/compressor.d.ts +3 -0
- package/dist/param-maps/compressor.d.ts.map +1 -0
- package/dist/param-maps/compressor.js +51 -0
- package/dist/param-maps/compressor.js.map +1 -0
- package/dist/param-maps/eq-eight.d.ts +3 -0
- package/dist/param-maps/eq-eight.d.ts.map +1 -0
- package/dist/param-maps/eq-eight.js +55 -0
- package/dist/param-maps/eq-eight.js.map +1 -0
- package/dist/param-maps/generic.d.ts +3 -0
- package/dist/param-maps/generic.d.ts.map +1 -0
- package/dist/param-maps/generic.js +11 -0
- package/dist/param-maps/generic.js.map +1 -0
- package/dist/param-maps/index.d.ts +14 -0
- package/dist/param-maps/index.d.ts.map +1 -0
- package/dist/param-maps/index.js +42 -0
- package/dist/param-maps/index.js.map +1 -0
- package/dist/plugin-library.d.ts +4 -0
- package/dist/plugin-library.d.ts.map +1 -0
- package/dist/plugin-library.js +63 -0
- package/dist/plugin-library.js.map +1 -0
- package/dist/spectral.d.ts +9 -0
- package/dist/spectral.d.ts.map +1 -0
- package/dist/spectral.js +63 -0
- package/dist/spectral.js.map +1 -0
- package/dist/stdio.d.ts +3 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +32 -0
- package/dist/stdio.js.map +1 -0
- package/dist/types.d.ts +171 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/ws-bridge.d.ts +15 -0
- package/dist/ws-bridge.d.ts.map +1 -0
- package/dist/ws-bridge.js +139 -0
- package/dist/ws-bridge.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { assembleContext } from "./context-assembler.js";
|
|
4
|
+
import { getPluginLibrary } from "./plugin-library.js";
|
|
5
|
+
import { runHeuristics } from "./heuristics/index.js";
|
|
6
|
+
import { formatSpectralSummary } from "./spectral.js";
|
|
7
|
+
import { humanToRaw } from "./param-maps/index.js";
|
|
8
|
+
// ============================================================
|
|
9
|
+
// System prompt — prepended to session context responses
|
|
10
|
+
// ============================================================
|
|
11
|
+
const SYSTEM_PROMPT = `You are an experienced mixing and mastering engineer working alongside a music producer in their Ableton Live session. You have real-time access to their session via Talkback MCP tools.
|
|
12
|
+
|
|
13
|
+
The Talkback Bridge is a Max for Live Audio Effect device already installed in the producer's session. It connects to this MCP server via WebSocket. You do NOT need to guide setup — if you can read session data, the bridge is working.
|
|
14
|
+
|
|
15
|
+
Guidelines:
|
|
16
|
+
|
|
17
|
+
SESSION AWARENESS
|
|
18
|
+
1. Call get_session_context once to orient yourself. Only call again if the user says the session has changed.
|
|
19
|
+
2. Do NOT call analyze_mix on every message. Only when the user explicitly asks for mix feedback or describes a problem.
|
|
20
|
+
|
|
21
|
+
EMPTY TRACKS & NORMAL VARIANCE
|
|
22
|
+
3. Empty tracks, unused sends, tracks at 0dB, hard-panned pairs — all normal production choices, never flag as issues. The only time an empty track matters is if it has active devices AND non-zero output meters (e.g., a vinyl emulation plugin generating noise on a track the producer thinks is silent). Never suggest cleaning up or deleting empty tracks.
|
|
23
|
+
4. Sessions vary wildly between producers. Do not assume any track layout, gain structure, or routing pattern is wrong.
|
|
24
|
+
|
|
25
|
+
NO OBJECTIVE "GOOD MIX"
|
|
26
|
+
5. A mix is not objectively good or bad. There is no benchmark to optimize toward. When a user says "make it better" or "improve the mix," ask what they mean — louder? cleaner? drums hit harder while vocals stay present? more space? more aggression? The goal is to help the producer overcome technical limitations to achieve THEIR artistic vision, not a textbook standard.
|
|
27
|
+
6. A "technically rough" mix may be exactly right for the song's emotional intent. Respect that. Never assume a non-standard setting is a mistake.
|
|
28
|
+
|
|
29
|
+
PARAMETER CHANGES REQUIRE CONSENT
|
|
30
|
+
7. NEVER change a parameter without explicit user approval. Before any write operation, present the full plan: track name, device name, parameter name, current value → proposed value, and why. Wait for a clear "yes." If the user modifies the plan, re-present the updated changes and confirm again before executing. Never batch-execute changes without per-change approval.
|
|
31
|
+
|
|
32
|
+
FREQUENCY ANALYSIS
|
|
33
|
+
8. Your primary frequency insight comes from reading device parameters — EQ curves, filter cutoffs, compressor settings, device chains. Use get_track_details to read these. This works without playback and covers most mixing advice.
|
|
34
|
+
9. Spectral analysis (get_spectral_snapshot) is a secondary verification tool. It captures ~2 seconds of live audio from the master bus at the moment of capture. Transport must be playing. Use it only to confirm suspicions or detect issues invisible in device parameters (masking between tracks, phase cancellation, unexpected resonances). It is a microscope on a moment, not a full-song analyzer.
|
|
35
|
+
|
|
36
|
+
COMMUNICATION
|
|
37
|
+
10. Be specific — reference exact track names, device names, parameter values, and suggested values.
|
|
38
|
+
11. When suggesting devices, prefer plugins already in the session, then plugins the producer owns (use get_plugin_library). Don't suggest plugins without checking availability.
|
|
39
|
+
12. Speak like a knowledgeable colleague, not a textbook. Be direct and conversational. Prioritize by impact — lead with the highest-leverage suggestion.
|
|
40
|
+
13. When the producer describes a subjective problem ("muddy", "harsh", "thin"), use get_track_details to read device parameters on the relevant tracks BEFORE reaching for analyze_mix or spectral.
|
|
41
|
+
14. If session data is unavailable, simply say the bridge isn't connected. Do NOT fabricate setup instructions, GitHub URLs, or troubleshooting steps.`;
|
|
42
|
+
// ============================================================
|
|
43
|
+
// MCP server setup
|
|
44
|
+
// ============================================================
|
|
45
|
+
export function createMcpServer(bridge) {
|
|
46
|
+
const server = new McpServer({
|
|
47
|
+
name: "talkback-mcp",
|
|
48
|
+
version: "0.1.0",
|
|
49
|
+
});
|
|
50
|
+
// ----------------------------------------------------------
|
|
51
|
+
// Tool: get_session_context
|
|
52
|
+
// ----------------------------------------------------------
|
|
53
|
+
server.tool("get_session_context", "Returns a snapshot of the current Ableton session: all tracks (names, volumes, panning, mutes, sends, device chains), return tracks, master track, and routing. Call once at the start of a conversation to orient yourself. No need to call again unless the user says the session has changed.", {}, async () => {
|
|
54
|
+
const context = assembleContext(bridge.cache);
|
|
55
|
+
if (!context) {
|
|
56
|
+
return {
|
|
57
|
+
content: [
|
|
58
|
+
{
|
|
59
|
+
type: "text",
|
|
60
|
+
text: "No session data available. Is the Talkback Bridge device loaded in Ableton and is the WebSocket connection active?",
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{ type: "text", text: SYSTEM_PROMPT },
|
|
68
|
+
{ type: "text", text: JSON.stringify(context, null, 2) },
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
// ----------------------------------------------------------
|
|
73
|
+
// Tool: get_track_details
|
|
74
|
+
// ----------------------------------------------------------
|
|
75
|
+
server.tool("get_track_details", "Returns full detail for a specific track including all devices, every parameter in human-readable units, and per-device observations.", { track_name: z.string().describe("Track name (case-insensitive match)") }, async ({ track_name }) => {
|
|
76
|
+
const context = assembleContext(bridge.cache);
|
|
77
|
+
if (!context) {
|
|
78
|
+
return {
|
|
79
|
+
content: [{ type: "text", text: "No session data available." }],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const lower = track_name.toLowerCase();
|
|
83
|
+
const allTracks = [
|
|
84
|
+
...context.tracks,
|
|
85
|
+
...context.returnTracks,
|
|
86
|
+
context.masterTrack,
|
|
87
|
+
];
|
|
88
|
+
const track = allTracks.find((t) => t.name.toLowerCase() === lower);
|
|
89
|
+
if (!track) {
|
|
90
|
+
const names = allTracks.map((t) => t.name).join(", ");
|
|
91
|
+
return {
|
|
92
|
+
content: [
|
|
93
|
+
{
|
|
94
|
+
type: "text",
|
|
95
|
+
text: `Track "${track_name}" not found. Available tracks: ${names}`,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
content: [
|
|
102
|
+
{ type: "text", text: JSON.stringify(track, null, 2) },
|
|
103
|
+
],
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
// ----------------------------------------------------------
|
|
107
|
+
// Tool: get_spectral_snapshot
|
|
108
|
+
// ----------------------------------------------------------
|
|
109
|
+
server.tool("get_spectral_snapshot", "Captures ~2 seconds of live audio from the master bus and returns peak/RMS levels across frequency bands. Transport MUST be playing — coordinate with the user on which section to analyze (e.g., 'play the chorus'). This is a point-in-time microscope, not a full-song analyzer. Use as a secondary check to verify what device parameter analysis suggests, or to detect issues invisible in the device chain (masking, phase, resonances). For most frequency questions, reading EQ and filter parameters via get_track_details is more informative.", {
|
|
110
|
+
source: z
|
|
111
|
+
.string()
|
|
112
|
+
.default("master")
|
|
113
|
+
.describe("'master' for master bus, or a track name"),
|
|
114
|
+
}, async ({ source }) => {
|
|
115
|
+
try {
|
|
116
|
+
const snapshot = await bridge.requestSpectral(source);
|
|
117
|
+
const summary = formatSpectralSummary(snapshot);
|
|
118
|
+
return {
|
|
119
|
+
content: [
|
|
120
|
+
{ type: "text", text: summary },
|
|
121
|
+
{ type: "text", text: JSON.stringify(snapshot, null, 2) },
|
|
122
|
+
],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
127
|
+
return {
|
|
128
|
+
content: [
|
|
129
|
+
{
|
|
130
|
+
type: "text",
|
|
131
|
+
text: `Spectral analysis unavailable: ${message}`,
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
// ----------------------------------------------------------
|
|
138
|
+
// Tool: get_plugin_library
|
|
139
|
+
// ----------------------------------------------------------
|
|
140
|
+
server.tool("get_plugin_library", "Returns all audio plugins (AU, VST3) installed on this system. Use to know what tools the producer has available.", {
|
|
141
|
+
filter: z
|
|
142
|
+
.string()
|
|
143
|
+
.optional()
|
|
144
|
+
.describe("Optional search string to filter by plugin name"),
|
|
145
|
+
}, async ({ filter }) => {
|
|
146
|
+
const plugins = await getPluginLibrary(filter);
|
|
147
|
+
return {
|
|
148
|
+
content: [
|
|
149
|
+
{
|
|
150
|
+
type: "text",
|
|
151
|
+
text: `${plugins.length} plugins found${filter ? ` matching "${filter}"` : ""}:\n${JSON.stringify(plugins, null, 2)}`,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
// ----------------------------------------------------------
|
|
157
|
+
// Tool: analyze_mix
|
|
158
|
+
// ----------------------------------------------------------
|
|
159
|
+
server.tool("analyze_mix", "Runs rule-based heuristic analysis for potential mix issues: frequency buildup, dynamics problems, routing inefficiencies, headroom. Only call when the user explicitly asks for mix feedback or describes a specific problem — do NOT call proactively. Findings are suggestions to consider, not problems to fix. Mix quality is subjective — frame results in context of what the user is trying to achieve. A technically 'imperfect' setting may be an intentional artistic choice.", {}, async () => {
|
|
160
|
+
const context = assembleContext(bridge.cache);
|
|
161
|
+
if (!context) {
|
|
162
|
+
return {
|
|
163
|
+
content: [{ type: "text", text: "No session data available." }],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const findings = runHeuristics(context);
|
|
167
|
+
if (findings.length === 0) {
|
|
168
|
+
return {
|
|
169
|
+
content: [
|
|
170
|
+
{
|
|
171
|
+
type: "text",
|
|
172
|
+
text: "No issues detected by automated analysis. This doesn't mean the mix is perfect — it means no common problems were flagged. Describe what you're hearing and I can dig deeper.",
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
content: [
|
|
179
|
+
{
|
|
180
|
+
type: "text",
|
|
181
|
+
text: JSON.stringify(findings, null, 2),
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
};
|
|
185
|
+
});
|
|
186
|
+
// ----------------------------------------------------------
|
|
187
|
+
// Tool: set_device_parameter
|
|
188
|
+
// ----------------------------------------------------------
|
|
189
|
+
server.tool("set_device_parameter", "Sets a device parameter to a new value. Pass values in human-readable units (dB, ms, Hz, ratio, percent). NEVER call without explicit user approval. Present the planned change with current → proposed values first, wait for a clear 'yes', then execute. If the user modifies the plan, re-present and re-confirm before executing.", {
|
|
190
|
+
track_name: z.string(),
|
|
191
|
+
device_name: z.string(),
|
|
192
|
+
parameter_name: z.string(),
|
|
193
|
+
value: z.number(),
|
|
194
|
+
unit: z.enum(["dB", "ms", "Hz", "ratio", "percent"]),
|
|
195
|
+
}, async ({ track_name, device_name, parameter_name, value, unit }) => {
|
|
196
|
+
if (!bridge.cache.raw) {
|
|
197
|
+
return {
|
|
198
|
+
content: [{ type: "text", text: "No session data available." }],
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
// Find the track and device in raw cache to get device className
|
|
202
|
+
const allTracks = [
|
|
203
|
+
...bridge.cache.raw.tracks,
|
|
204
|
+
...bridge.cache.raw.returnTracks,
|
|
205
|
+
bridge.cache.raw.masterTrack,
|
|
206
|
+
];
|
|
207
|
+
const lower = track_name.toLowerCase();
|
|
208
|
+
const track = allTracks.find((t) => t.name.toLowerCase() === lower);
|
|
209
|
+
if (!track) {
|
|
210
|
+
return {
|
|
211
|
+
content: [
|
|
212
|
+
{ type: "text", text: `Track "${track_name}" not found.` },
|
|
213
|
+
],
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
const device = track.devices.find((d) => d.name.toLowerCase() === device_name.toLowerCase());
|
|
217
|
+
if (!device) {
|
|
218
|
+
return {
|
|
219
|
+
content: [
|
|
220
|
+
{
|
|
221
|
+
type: "text",
|
|
222
|
+
text: `Device "${device_name}" not found on track "${track_name}".`,
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// Convert human value to raw
|
|
228
|
+
let rawValue = humanToRaw(device.className, parameter_name, value, unit);
|
|
229
|
+
if (rawValue === null) {
|
|
230
|
+
// Fallback: assume 0-100 percent mapping
|
|
231
|
+
rawValue = unit === "percent" ? value / 100 : value;
|
|
232
|
+
}
|
|
233
|
+
// Clamp to 0-1
|
|
234
|
+
rawValue = Math.max(0, Math.min(1, rawValue));
|
|
235
|
+
const sent = bridge.sendCommand({
|
|
236
|
+
type: "set_parameter",
|
|
237
|
+
trackId: track.id,
|
|
238
|
+
deviceId: device.id,
|
|
239
|
+
parameterName: parameter_name,
|
|
240
|
+
value: rawValue,
|
|
241
|
+
});
|
|
242
|
+
if (!sent) {
|
|
243
|
+
return {
|
|
244
|
+
content: [
|
|
245
|
+
{ type: "text", text: "Failed to send command — M4L bridge not connected." },
|
|
246
|
+
],
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
content: [
|
|
251
|
+
{
|
|
252
|
+
type: "text",
|
|
253
|
+
text: `Set ${track_name} → ${device_name} → ${parameter_name} to ${value}${unit} (raw: ${rawValue.toFixed(4)})`,
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
};
|
|
257
|
+
});
|
|
258
|
+
// ----------------------------------------------------------
|
|
259
|
+
// Tool: toggle_device_bypass
|
|
260
|
+
// ----------------------------------------------------------
|
|
261
|
+
server.tool("toggle_device_bypass", "Enables or bypasses a device on a track. Useful for A/B comparison. Always confirm with the user before toggling.", {
|
|
262
|
+
track_name: z.string(),
|
|
263
|
+
device_name: z.string(),
|
|
264
|
+
active: z.boolean().describe("true = device on, false = bypassed"),
|
|
265
|
+
}, async ({ track_name, device_name, active }) => {
|
|
266
|
+
if (!bridge.cache.raw) {
|
|
267
|
+
return {
|
|
268
|
+
content: [{ type: "text", text: "No session data available." }],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
const allTracks = [
|
|
272
|
+
...bridge.cache.raw.tracks,
|
|
273
|
+
...bridge.cache.raw.returnTracks,
|
|
274
|
+
bridge.cache.raw.masterTrack,
|
|
275
|
+
];
|
|
276
|
+
const track = allTracks.find((t) => t.name.toLowerCase() === track_name.toLowerCase());
|
|
277
|
+
if (!track) {
|
|
278
|
+
return {
|
|
279
|
+
content: [{ type: "text", text: `Track "${track_name}" not found.` }],
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
const device = track.devices.find((d) => d.name.toLowerCase() === device_name.toLowerCase());
|
|
283
|
+
if (!device) {
|
|
284
|
+
return {
|
|
285
|
+
content: [
|
|
286
|
+
{
|
|
287
|
+
type: "text",
|
|
288
|
+
text: `Device "${device_name}" not found on track "${track_name}".`,
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const sent = bridge.sendCommand({
|
|
294
|
+
type: "set_device_active",
|
|
295
|
+
trackId: track.id,
|
|
296
|
+
deviceId: device.id,
|
|
297
|
+
isActive: active,
|
|
298
|
+
});
|
|
299
|
+
if (!sent) {
|
|
300
|
+
return {
|
|
301
|
+
content: [
|
|
302
|
+
{ type: "text", text: "Failed — M4L bridge not connected." },
|
|
303
|
+
],
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
content: [
|
|
308
|
+
{
|
|
309
|
+
type: "text",
|
|
310
|
+
text: `${device_name} on ${track_name} is now ${active ? "enabled" : "bypassed"}.`,
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
// ----------------------------------------------------------
|
|
316
|
+
// Tool: create_group_track
|
|
317
|
+
// ----------------------------------------------------------
|
|
318
|
+
server.tool("create_group_track", "Creates a new group track containing the specified tracks. Always confirm with the producer first.", {
|
|
319
|
+
track_names: z.array(z.string()).describe("Names of tracks to group"),
|
|
320
|
+
group_name: z.string().describe("Name for the new group track"),
|
|
321
|
+
}, async ({ track_names, group_name }) => {
|
|
322
|
+
if (!bridge.cache.raw) {
|
|
323
|
+
return {
|
|
324
|
+
content: [{ type: "text", text: "No session data available." }],
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
const trackIds = [];
|
|
328
|
+
const notFound = [];
|
|
329
|
+
for (const name of track_names) {
|
|
330
|
+
const track = bridge.cache.raw.tracks.find((t) => t.name.toLowerCase() === name.toLowerCase());
|
|
331
|
+
if (track) {
|
|
332
|
+
trackIds.push(track.id);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
notFound.push(name);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (notFound.length > 0) {
|
|
339
|
+
return {
|
|
340
|
+
content: [
|
|
341
|
+
{
|
|
342
|
+
type: "text",
|
|
343
|
+
text: `Could not find tracks: ${notFound.join(", ")}`,
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
const sent = bridge.sendCommand({
|
|
349
|
+
type: "create_group",
|
|
350
|
+
trackIds,
|
|
351
|
+
groupName: group_name,
|
|
352
|
+
});
|
|
353
|
+
if (!sent) {
|
|
354
|
+
return {
|
|
355
|
+
content: [
|
|
356
|
+
{ type: "text", text: "Failed — M4L bridge not connected." },
|
|
357
|
+
],
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
content: [
|
|
362
|
+
{
|
|
363
|
+
type: "text",
|
|
364
|
+
text: `Creating group "${group_name}" with tracks: ${track_names.join(", ")}`,
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
};
|
|
368
|
+
});
|
|
369
|
+
// ----------------------------------------------------------
|
|
370
|
+
// Tool: set_track_routing
|
|
371
|
+
// ----------------------------------------------------------
|
|
372
|
+
server.tool("set_track_routing", "Changes a track's output routing. Always confirm with the producer first.", {
|
|
373
|
+
track_name: z.string(),
|
|
374
|
+
output_target: z.string().describe("Name of the target track/group/bus"),
|
|
375
|
+
}, async ({ track_name, output_target }) => {
|
|
376
|
+
if (!bridge.cache.raw) {
|
|
377
|
+
return {
|
|
378
|
+
content: [{ type: "text", text: "No session data available." }],
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
const track = bridge.cache.raw.tracks.find((t) => t.name.toLowerCase() === track_name.toLowerCase());
|
|
382
|
+
if (!track) {
|
|
383
|
+
return {
|
|
384
|
+
content: [{ type: "text", text: `Track "${track_name}" not found.` }],
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
const sent = bridge.sendCommand({
|
|
388
|
+
type: "set_routing",
|
|
389
|
+
trackId: track.id,
|
|
390
|
+
outputTarget: output_target,
|
|
391
|
+
});
|
|
392
|
+
if (!sent) {
|
|
393
|
+
return {
|
|
394
|
+
content: [
|
|
395
|
+
{ type: "text", text: "Failed — M4L bridge not connected." },
|
|
396
|
+
],
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
content: [
|
|
401
|
+
{
|
|
402
|
+
type: "text",
|
|
403
|
+
text: `Routing ${track_name} output to ${output_target}.`,
|
|
404
|
+
},
|
|
405
|
+
],
|
|
406
|
+
};
|
|
407
|
+
});
|
|
408
|
+
// ----------------------------------------------------------
|
|
409
|
+
// Tool: get_bridge_health
|
|
410
|
+
// ----------------------------------------------------------
|
|
411
|
+
server.tool("get_bridge_health", "Returns performance metrics from the M4L bridge device: poll execution time (avg/max), WebSocket message size, LiveAPI cache size, and track count. Use to diagnose performance issues or confirm the device is running efficiently.", {}, async () => {
|
|
412
|
+
if (!bridge.cache.isConnected) {
|
|
413
|
+
return {
|
|
414
|
+
content: [{ type: "text", text: "M4L bridge not connected." }],
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
const p = bridge.perf;
|
|
418
|
+
const snapshotKb = (p.snapshotBytes / 1024).toFixed(1);
|
|
419
|
+
const lines = [
|
|
420
|
+
`Poll time: ${p.lastPollMs}ms (avg ${p.avgPollMs}ms, max ${p.maxPollMs}ms over ${p.pollCount} polls)`,
|
|
421
|
+
`Snapshot size: ${snapshotKb}KB (${p.snapshotBytes} bytes)`,
|
|
422
|
+
`Tracks in snapshot: ${p.trackCount}`,
|
|
423
|
+
`LiveAPI cache: ${p.apiCacheSize} objects`,
|
|
424
|
+
`Last poll was structure refresh: ${p.lastStructureRefresh}`,
|
|
425
|
+
``,
|
|
426
|
+
`Benchmarks:`,
|
|
427
|
+
` Poll time < 50ms = excellent, 50-200ms = acceptable, >200ms = needs work`,
|
|
428
|
+
` Snapshot < 30KB = good, 30-100KB = fine at 10s intervals, >100KB = large`,
|
|
429
|
+
` Cache should stabilize after first few polls — growth = potential leak`,
|
|
430
|
+
];
|
|
431
|
+
return {
|
|
432
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
433
|
+
};
|
|
434
|
+
});
|
|
435
|
+
return server;
|
|
436
|
+
}
|
|
437
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,+DAA+D;AAC/D,yDAAyD;AACzD,+DAA+D;AAE/D,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uJA8BiI,CAAC;AAExJ,+DAA+D;AAC/D,mBAAmB;AACnB,+DAA+D;AAE/D,MAAM,UAAU,eAAe,CAAC,MAAgB;IAC9C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,6DAA6D;IAC7D,4BAA4B;IAC5B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,kSAAkS,EAClS,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,oHAAoH;qBAC3H;iBACF;aACF,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,aAAa,EAAE;gBAC9C,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aAClE;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,0BAA0B;IAC1B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,uIAAuI,EACvI,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC,EAAE,EAC1E,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACvB,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC;aACzE,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG;YAChB,GAAG,OAAO,CAAC,MAAM;YACjB,GAAG,OAAO,CAAC,YAAY;YACvB,OAAO,CAAC,WAAW;SACpB,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;QAEpE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,UAAU,UAAU,kCAAkC,KAAK,EAAE;qBACpE;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aAChE;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,8BAA8B;IAC9B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,2hBAA2hB,EAC3hB;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,OAAO,CAAC,QAAQ,CAAC;aACjB,QAAQ,CAAC,0CAA0C,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;YAChD,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE;oBACxC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACnE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,kCAAkC,OAAO,EAAE;qBAClD;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,2BAA2B;IAC3B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,mHAAmH,EACnH;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,iDAAiD,CAAC;KAC/D,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,iBAAiB,MAAM,CAAC,CAAC,CAAC,cAAc,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACtH;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,oBAAoB;IACpB,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,aAAa,EACb,0dAA0d,EAC1d,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC;aACzE,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QAExC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,+KAA+K;qBACtL;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,6BAA6B;IAC7B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,wUAAwU,EACxU;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;QACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;QACvB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;QAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;KACrD,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;QACjE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC;aACzE,CAAC;QACJ,CAAC;QAED,iEAAiE;QACjE,MAAM,SAAS,GAAG;YAChB,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;YAC1B,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY;YAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW;SAC7B,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,UAAU,cAAc,EAAE;iBACpE;aACF,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAC/B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC,WAAW,EAAE,CAC1D,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,WAAW,WAAW,yBAAyB,UAAU,IAAI;qBACpE;iBACF;aACF,CAAC;QACJ,CAAC;QAED,6BAA6B;QAC7B,IAAI,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACzE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,yCAAyC;YACzC,QAAQ,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,eAAe;QACf,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAE9C,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;YAC9B,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,aAAa,EAAE,cAAc;YAC7B,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oDAAoD,EAAE;iBACtF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,OAAO,UAAU,MAAM,WAAW,MAAM,cAAc,OAAO,KAAK,GAAG,IAAI,UAAU,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;iBAChH;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,6BAA6B;IAC7B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,mHAAmH,EACnH;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;QACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;QACvB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;KACnE,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC;aACzE,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG;YAChB,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;YAC1B,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY;YAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW;SAC7B,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAC1B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,WAAW,EAAE,CACzD,CAAC;QACF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,UAAU,cAAc,EAAE,CAAC;aAC/E,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAC/B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC,WAAW,EAAE,CAC1D,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,WAAW,WAAW,yBAAyB,UAAU,IAAI;qBACpE;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;YAC9B,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oCAAoC,EAAE;iBACtE;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,GAAG,WAAW,OAAO,UAAU,WAAW,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,GAAG;iBACnF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,2BAA2B;IAC3B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,oGAAoG,EACpG;QACE,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QACrE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;KAChE,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE;QACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC;aACzE,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CACnD,CAAC;YACF,IAAI,KAAK,EAAE,CAAC;gBACV,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,0BAA0B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;qBACtD;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;YAC9B,IAAI,EAAE,cAAc;YACpB,QAAQ;YACR,SAAS,EAAE,UAAU;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oCAAoC,EAAE;iBACtE;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,mBAAmB,UAAU,kBAAkB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBAC9E;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,0BAA0B;IAC1B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,2EAA2E,EAC3E;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;QACtB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;KACzE,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,EAAE,EAAE;QACtC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC;aACzE,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,WAAW,EAAE,CACzD,CAAC;QACF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,UAAU,cAAc,EAAE,CAAC;aAC/E,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;YAC9B,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,YAAY,EAAE,aAAa;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oCAAoC,EAAE;iBACtE;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,WAAW,UAAU,cAAc,aAAa,GAAG;iBAC1D;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,0BAA0B;IAC1B,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,sOAAsO,EACtO,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9B,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,2BAA2B,EAAE,CAAC;aACxE,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;QACtB,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEvD,MAAM,KAAK,GAAG;YACZ,cAAc,CAAC,CAAC,UAAU,WAAW,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,SAAS,SAAS;YACrG,kBAAkB,UAAU,OAAO,CAAC,CAAC,aAAa,SAAS;YAC3D,uBAAuB,CAAC,CAAC,UAAU,EAAE;YACrC,kBAAkB,CAAC,CAAC,YAAY,UAAU;YAC1C,oCAAoC,CAAC,CAAC,oBAAoB,EAAE;YAC5D,EAAE;YACF,aAAa;YACb,4EAA4E;YAC5E,4EAA4E;YAC5E,0EAA0E;SAC3E,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;SAC7D,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressor.d.ts","sourceRoot":"","sources":["../../src/param-maps/compressor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,aAAa,EAAE,QA+C3B,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const compressorMap = {
|
|
2
|
+
deviceClassName: "Compressor",
|
|
3
|
+
parameters: {
|
|
4
|
+
Threshold: {
|
|
5
|
+
unit: "dB",
|
|
6
|
+
toHuman: (raw) => `${Math.round(-36 + raw * 36)}dB`,
|
|
7
|
+
fromHuman: (value) => (value + 36) / 36,
|
|
8
|
+
observe: (raw, human) => {
|
|
9
|
+
if (raw > 0.83)
|
|
10
|
+
return `High threshold (${human}) — compressor rarely triggering`;
|
|
11
|
+
return null;
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
Ratio: {
|
|
15
|
+
unit: ":1",
|
|
16
|
+
toHuman: (raw) => raw >= 0.99 ? "inf:1 (limiting)" : `${(1 + raw * 63).toFixed(1)}:1`,
|
|
17
|
+
fromHuman: (value) => (value - 1) / 63,
|
|
18
|
+
observe: (raw, human) => {
|
|
19
|
+
if (raw > 0.14)
|
|
20
|
+
return `High ratio (${human}) — behaving more like a limiter`;
|
|
21
|
+
return null;
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
Attack: {
|
|
25
|
+
unit: "ms",
|
|
26
|
+
toHuman: (raw) => `${(raw * 200).toFixed(1)}ms`,
|
|
27
|
+
fromHuman: (value) => value / 200,
|
|
28
|
+
observe: (raw, human) => {
|
|
29
|
+
if (raw > 0.25)
|
|
30
|
+
return `Slow attack (${human}) — transients passing through uncompressed`;
|
|
31
|
+
return null;
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
Release: {
|
|
35
|
+
unit: "ms",
|
|
36
|
+
toHuman: (raw) => `${(raw * 1190 + 10).toFixed(0)}ms`,
|
|
37
|
+
fromHuman: (value) => (value - 10) / 1190,
|
|
38
|
+
},
|
|
39
|
+
Makeup: {
|
|
40
|
+
unit: "dB",
|
|
41
|
+
toHuman: (raw) => `+${(raw * 24).toFixed(1)}dB`,
|
|
42
|
+
fromHuman: (value) => value / 24,
|
|
43
|
+
},
|
|
44
|
+
"Dry/Wet": {
|
|
45
|
+
unit: "%",
|
|
46
|
+
toHuman: (raw) => `${Math.round(raw * 100)}%`,
|
|
47
|
+
fromHuman: (value) => value / 100,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=compressor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressor.js","sourceRoot":"","sources":["../../src/param-maps/compressor.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAa;IACrC,eAAe,EAAE,YAAY;IAC7B,UAAU,EAAE;QACV,SAAS,EAAE;YACT,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,IAAI;YACnD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE;YACvC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBACtB,IAAI,GAAG,GAAG,IAAI;oBAAE,OAAO,mBAAmB,KAAK,kCAAkC,CAAC;gBAClF,OAAO,IAAI,CAAC;YACd,CAAC;SACF;QACD,KAAK,EAAE;YACL,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CACf,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YACrE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE;YACtC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBACtB,IAAI,GAAG,GAAG,IAAI;oBAAE,OAAO,eAAe,KAAK,kCAAkC,CAAC;gBAC9E,OAAO,IAAI,CAAC;YACd,CAAC;SACF;QACD,MAAM,EAAE;YACN,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YAC/C,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG;YACjC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBACtB,IAAI,GAAG,GAAG,IAAI;oBAAE,OAAO,gBAAgB,KAAK,6CAA6C,CAAC;gBAC1F,OAAO,IAAI,CAAC;YACd,CAAC;SACF;QACD,OAAO,EAAE;YACP,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YACrD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,IAAI;SAC1C;QACD,MAAM,EAAE;YACN,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YAC/C,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,EAAE;SACjC;QACD,SAAS,EAAE;YACT,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG;YAC7C,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG;SAClC;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eq-eight.d.ts","sourceRoot":"","sources":["../../src/param-maps/eq-eight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAyD3C,eAAO,MAAM,UAAU,EAAE,QAGxB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// EQ Eight has 8 bands, each with: Frequency, Gain, Q, Filter Type, Band On/Off
|
|
2
|
+
// Parameter names in LOM follow the pattern: "1 Frequency A", "1 Gain A", etc.
|
|
3
|
+
// This map covers the common parameters.
|
|
4
|
+
function freqToHuman(raw) {
|
|
5
|
+
// EQ Eight frequency range: ~20Hz to ~20kHz, logarithmic
|
|
6
|
+
const hz = 20 * Math.pow(1000, raw);
|
|
7
|
+
if (hz >= 1000)
|
|
8
|
+
return `${(hz / 1000).toFixed(1)}kHz`;
|
|
9
|
+
return `${Math.round(hz)}Hz`;
|
|
10
|
+
}
|
|
11
|
+
function freqFromHuman(hz) {
|
|
12
|
+
return Math.log(hz / 20) / Math.log(1000);
|
|
13
|
+
}
|
|
14
|
+
function gainToHuman(raw) {
|
|
15
|
+
// Gain range: -15dB to +15dB, centered at 0.5
|
|
16
|
+
const db = (raw - 0.5) * 30;
|
|
17
|
+
const sign = db > 0 ? "+" : "";
|
|
18
|
+
return `${sign}${db.toFixed(1)}dB`;
|
|
19
|
+
}
|
|
20
|
+
function gainFromHuman(db) {
|
|
21
|
+
return db / 30 + 0.5;
|
|
22
|
+
}
|
|
23
|
+
function observeGain(raw, human) {
|
|
24
|
+
const db = (raw - 0.5) * 30;
|
|
25
|
+
if (db > 4)
|
|
26
|
+
return `Notable boost (${human})`;
|
|
27
|
+
if (db < -6)
|
|
28
|
+
return `Significant cut (${human})`;
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
// Build parameters for all 8 bands
|
|
32
|
+
const parameters = {};
|
|
33
|
+
for (let band = 1; band <= 8; band++) {
|
|
34
|
+
parameters[`${band} Frequency A`] = {
|
|
35
|
+
unit: "Hz",
|
|
36
|
+
toHuman: freqToHuman,
|
|
37
|
+
fromHuman: freqFromHuman,
|
|
38
|
+
};
|
|
39
|
+
parameters[`${band} Gain A`] = {
|
|
40
|
+
unit: "dB",
|
|
41
|
+
toHuman: gainToHuman,
|
|
42
|
+
fromHuman: gainFromHuman,
|
|
43
|
+
observe: observeGain,
|
|
44
|
+
};
|
|
45
|
+
parameters[`${band} Resonance A`] = {
|
|
46
|
+
unit: "Q",
|
|
47
|
+
toHuman: (raw) => `Q ${(0.1 + raw * 17.9).toFixed(1)}`,
|
|
48
|
+
fromHuman: (value) => (value - 0.1) / 17.9,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export const eqEightMap = {
|
|
52
|
+
deviceClassName: "Eq8",
|
|
53
|
+
parameters,
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=eq-eight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eq-eight.js","sourceRoot":"","sources":["../../src/param-maps/eq-eight.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,+EAA+E;AAC/E,yCAAyC;AAEzC,SAAS,WAAW,CAAC,GAAW;IAC9B,yDAAyD;IACzD,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACpC,IAAI,EAAE,IAAI,IAAI;QAAE,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IACtD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED,SAAS,aAAa,CAAC,EAAU;IAC/B,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,8CAA8C;IAC9C,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,SAAS,aAAa,CAAC,EAAU;IAC/B,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;AACvB,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAE,KAAa;IAC7C,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC5B,IAAI,EAAE,GAAG,CAAC;QAAE,OAAO,kBAAkB,KAAK,GAAG,CAAC;IAC9C,IAAI,EAAE,GAAG,CAAC,CAAC;QAAE,OAAO,oBAAoB,KAAK,GAAG,CAAC;IACjD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,GAAuD,EAAE,CAAC;AAE1E,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;IACrC,UAAU,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG;QAClC,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,WAAW;QACpB,SAAS,EAAE,aAAa;KACzB,CAAC;IACF,UAAU,CAAC,GAAG,IAAI,SAAS,CAAC,GAAG;QAC7B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,WAAW;QACpB,SAAS,EAAE,aAAa;QACxB,OAAO,EAAE,WAAW;KACrB,CAAC;IACF,UAAU,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG;QAClC,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACtD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI;KAC3C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAa;IAClC,eAAe,EAAE,KAAK;IACtB,UAAU;CACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/param-maps/generic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,UAAU,EAAE,QASxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/param-maps/generic.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAa;IAClC,eAAe,EAAE,UAAU;IAC3B,UAAU,EAAE;QACV,QAAQ,EAAE;YACR,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG;YAC7C,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG;SAClC;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ParamMapEntry {
|
|
2
|
+
unit: string;
|
|
3
|
+
toHuman: (raw: number) => string;
|
|
4
|
+
fromHuman?: (value: number, unit: string) => number;
|
|
5
|
+
observe?: (raw: number, human: string) => string | null;
|
|
6
|
+
}
|
|
7
|
+
export interface ParamMap {
|
|
8
|
+
deviceClassName: string;
|
|
9
|
+
parameters: Record<string, ParamMapEntry>;
|
|
10
|
+
}
|
|
11
|
+
export declare function lookupParamMap(deviceClassName: string): ParamMap | null;
|
|
12
|
+
export declare function translateParameter(deviceClassName: string, paramName: string, rawValue: number, paramMap: ParamMap | null): string;
|
|
13
|
+
export declare function humanToRaw(deviceClassName: string, paramName: string, value: number, unit: string): number | null;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/param-maps/index.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACzD;AAED,MAAM,WAAW,QAAQ;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC3C;AAwBD,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAEvE;AAED,wBAAgB,kBAAkB,CAChC,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,GAAG,IAAI,GACxB,MAAM,CAOR;AAED,wBAAgB,UAAU,CACxB,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAQf"}
|