Skip to main content
Glama

Ableton Copilot MCP

by xiaolaa2
clip-utils.ts2.99 kB
import { Clip } from 'ableton-js/ns/clip.js' import { ableton } from '../ableton.js' import { SnapshotType, Snapshot, NoteSnapshotData } from '../entities/Snapshot.js' import { createSnapshot } from './snapshot-utils.js' import { Note, NoteExtended } from 'ableton-js/util/note.js' import { NoteExtendedToNote } from './obj-utils.js' import { ErrorTypes } from '../mcp/error-handler.js' export async function removeNotesExtended( clip: Clip, fromPitch: number, pitchSpan: number, fromTime: number, timeSpan: number ) { const abltonMajorVersion = await ableton.application.get('major_version', true) if (abltonMajorVersion < 11) { return clip.removeNotes(fromTime, fromPitch, timeSpan, pitchSpan) } return clip.removeNotesExtended(fromTime, fromPitch, timeSpan, pitchSpan) } export async function removeAllNotes(clip: Clip) { return removeNotesExtended(clip, 0, 127, 0, 9999) } export async function getAllNotes(clip: Clip) { const liveVersion = await ableton.application.get('major_version', true) if (liveVersion >= 11) { return clip.getNotesExtended(0, 0, 9999, 127) } return clip.getNotes(0, 0, 9999, 127) } export async function getNotes(clip: Clip, fromPitch: number, pitchSpan: number, fromTime: number, timeSpan: number) { const liveVersion = await ableton.application.get('major_version', true) if (liveVersion >= 11) { return clip.getNotesExtended(fromTime, fromPitch, timeSpan, pitchSpan) } return clip.getNotes(fromTime, fromPitch, timeSpan, pitchSpan) } export async function createNoteSnapshot(clip: Clip, historyId: number): Promise<number> { const data: NoteSnapshotData = { clip_id: clip.raw.id, notes: await getAllNotes(clip), } const snapshot = { history_id: historyId, snapshot_data: JSON.stringify(data), snapshot_type: SnapshotType.NOTE, } as Omit<Snapshot, 'id' | 'createdAt' | 'updatedAt'> return createSnapshot(snapshot) } // only use for replace_clip_notes and rollback_by_history_id export async function setNotesExtended(clip: Clip, notes: NoteExtended[]) { const noteToSet = notes.map(note => NoteExtendedToNote(note)) // throw new Error(`note: ${noteToSet.map(note => JSON.stringify(note))}`) await clip.setNotes(noteToSet) const getNotes = await getAllNotes(clip) if (getNotes.length !== notes.length) { throw ErrorTypes.INTERNAL_ERROR('setNotesExtended failed') } notes.forEach((note, index) => { note.note_id = (getNotes[index] as NoteExtended).note_id }) await clip.applyNoteModifications(notes) } export async function replaceClipNotes(clip: Clip, notes: Note[]) { await removeAllNotes(clip) await clip.setNotes(notes) } // only apply note modifications if live version is 11 export async function replaceClipNotesExtended(clip: Clip, notes: NoteExtended[]) { await removeAllNotes(clip) await setNotesExtended(clip, notes) }

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/xiaolaa2/ableton-copilot-mcp'

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