add_controlchanges_by_index
Add control change events to a specific track in a MIDI file using the track index. Specify the controller number, value, and timing (time or ticks).
Instructions
Add controlchanges to midi file by track index
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Absoulate File Path to midi file | |
| trackIndex | Yes | Track index number | |
| controlchanges | Yes |
Implementation Reference
- src/main.ts:256-277 (handler)The handler function that executes the 'add_controlchanges_by_index' tool logic: loads a MIDI file, finds the track by index, adds each control change via track.addCC(), then saves the modified file.
withErrorHandling(({ filePath, trackIndex, controlchanges }) => { // 读取文件 const midi = loadMidiFile(filePath) // 查找轨道 const track = getTrackByIndex(midi, trackIndex) // 添加控制器变化 controlchanges.forEach(controlchange => { track.addCC(controlchange) }) // 保存文件 saveMidiFile(midi, filePath) return { content: [ { type: 'text', text: 'add controlchange success', }, ] } }) ) - src/types/types.ts:41-51 (schema)The Zod schema for ControlChangeInterfaceSchema, defining the input validation for control changes: number, value, and either time or ticks.
export const ControlChangeInterfaceSchema = z.object({ number: z.number(), value: z.number(), }).and(z.union([ z.object({ time: z.number(), }), z.object({ ticks: z.number(), }) ])) - src/main.ts:248-277 (registration)The tool registration using server.tool() with name 'add_controlchanges_by_index', description, input schema (filePath, trackIndex, controlchanges array), and handler.
server.tool( 'add_controlchanges_by_index', 'Add controlchanges to midi file by track index', { filePath: z.string().describe('Absoulate File Path to midi file'), trackIndex: z.number().describe('Track index number'), controlchanges: z.array(ControlChangeInterfaceSchema) }, withErrorHandling(({ filePath, trackIndex, controlchanges }) => { // 读取文件 const midi = loadMidiFile(filePath) // 查找轨道 const track = getTrackByIndex(midi, trackIndex) // 添加控制器变化 controlchanges.forEach(controlchange => { track.addCC(controlchange) }) // 保存文件 saveMidiFile(midi, filePath) return { content: [ { type: 'text', text: 'add controlchange success', }, ] } }) ) - src/utils/file-util.ts:5-15 (helper)The loadMidiFile helper reads a MIDI file from disk and parses it using @tonejs/midi.
export function loadMidiFile(filePath: string) { const midiData = fs.readFileSync(filePath) const midi = new Midi(midiData) return midi } export function saveMidiFile(midi: any, filePath: string): void { const arrayBuffer = midi.toArray() // 将ArrayBuffer转换为Buffer并写入文件 fs.writeFileSync(filePath, Buffer.from(arrayBuffer)) } - src/utils/obj-utils.ts:1-6 (helper)The getTrackByIndex helper retrieves a track from the MIDI object by its numeric index with bounds checking.
export function getTrackByIndex(midi: any, trackIndex: number) { if (trackIndex < 0 || trackIndex >= midi.tracks.length) { throw new Error('Track index out of range') } return midi.tracks[trackIndex] }