fix: copilot Multi-tool Calling)
This commit is contained in:
@@ -8099,6 +8099,177 @@ const App = () => {
|
||||
trackId,
|
||||
time
|
||||
};
|
||||
},
|
||||
fadeIn: args => {
|
||||
const trackIdRaw = args.track_id || selectedTrackId;
|
||||
const track = tracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw);
|
||||
if (!track) return {
|
||||
success: false,
|
||||
error: `Track ${trackIdRaw} not found`
|
||||
};
|
||||
const clips = track.clips && track.clips.length > 0 ? track.clips : track.buffer ? [{
|
||||
id: 'default_' + track.id,
|
||||
buffer: track.buffer,
|
||||
startTime: track.startTime || 0,
|
||||
name: track.name
|
||||
}] : [];
|
||||
if (clips.length === 0) return {
|
||||
success: false,
|
||||
error: 'No clips on track'
|
||||
};
|
||||
let clip = null;
|
||||
if (args.clip_id) {
|
||||
clip = clips.find(c => c.id === args.clip_id);
|
||||
} else if (args.clip_index !== undefined) {
|
||||
const idx = parseInt(args.clip_index);
|
||||
const realIdx = idx > 0 ? idx - 1 : 0;
|
||||
clip = clips[realIdx] || clips[0];
|
||||
} else {
|
||||
clip = clips[0];
|
||||
}
|
||||
if (!clip || !clip.buffer) return {
|
||||
success: false,
|
||||
error: 'Clip has no audio buffer'
|
||||
};
|
||||
const duration = parseFloat(args.duration_seconds || 3);
|
||||
const buffer = clip.buffer;
|
||||
const sr = buffer.sampleRate;
|
||||
const numChannels = buffer.numberOfChannels;
|
||||
const length = buffer.length;
|
||||
const ctx = getAudioContext();
|
||||
const newBuffer = ctx.createBuffer(numChannels, length, sr);
|
||||
for (let c = 0; c < numChannels; c++) {
|
||||
newBuffer.getChannelData(c).set(buffer.getChannelData(c));
|
||||
}
|
||||
const fadeSamples = Math.min(length, Math.floor(duration * sr));
|
||||
for (let c = 0; c < numChannels; c++) {
|
||||
const data = newBuffer.getChannelData(c);
|
||||
for (let i = 0; i < fadeSamples; i++) {
|
||||
const factor = (1 - Math.cos(Math.PI * i / fadeSamples)) / 2;
|
||||
data[i] *= factor;
|
||||
}
|
||||
}
|
||||
const beforeSnap = captureTrackSnapshot(track.id);
|
||||
setTracks(prev => prev.map(t => {
|
||||
if (t.id !== track.id) return t;
|
||||
const existingClips = t.clips && t.clips.length > 0 ? t.clips : t.buffer ? [{
|
||||
id: 'default_' + t.id,
|
||||
buffer: t.buffer,
|
||||
startTime: t.startTime || 0,
|
||||
name: t.name
|
||||
}] : [];
|
||||
const updatedClips = existingClips.map(c => {
|
||||
if (c.id === clip.id || clip.id.startsWith('default_') && c.id === 'default') {
|
||||
return {
|
||||
...c,
|
||||
buffer: newBuffer
|
||||
};
|
||||
}
|
||||
return c;
|
||||
});
|
||||
const mainBuffer = updatedClips[0]?.buffer || t.buffer;
|
||||
return {
|
||||
...t,
|
||||
clips: updatedClips,
|
||||
buffer: mainBuffer
|
||||
};
|
||||
}));
|
||||
setTimeout(() => {
|
||||
const afterSnap = captureTrackSnapshot(track.id);
|
||||
pushAction('AI_FADE_IN', track.id, beforeSnap, afterSnap);
|
||||
}, 50);
|
||||
return {
|
||||
success: true,
|
||||
trackId: track.id,
|
||||
clipId: clip.id,
|
||||
duration_seconds: duration
|
||||
};
|
||||
},
|
||||
fadeOut: args => {
|
||||
const trackIdRaw = args.track_id || selectedTrackId;
|
||||
const track = tracks.find(t => t.id === String(trackIdRaw) || t.id === 'track_' + trackIdRaw);
|
||||
if (!track) return {
|
||||
success: false,
|
||||
error: `Track ${trackIdRaw} not found`
|
||||
};
|
||||
const clips = track.clips && track.clips.length > 0 ? track.clips : track.buffer ? [{
|
||||
id: 'default_' + track.id,
|
||||
buffer: track.buffer,
|
||||
startTime: track.startTime || 0,
|
||||
name: track.name
|
||||
}] : [];
|
||||
if (clips.length === 0) return {
|
||||
success: false,
|
||||
error: 'No clips on track'
|
||||
};
|
||||
let clip = null;
|
||||
if (args.clip_id) {
|
||||
clip = clips.find(c => c.id === args.clip_id);
|
||||
} else if (args.clip_index !== undefined) {
|
||||
const idx = parseInt(args.clip_index);
|
||||
const realIdx = idx > 0 ? idx - 1 : 0;
|
||||
clip = clips[realIdx] || clips[0];
|
||||
} else {
|
||||
clip = clips[0];
|
||||
}
|
||||
if (!clip || !clip.buffer) return {
|
||||
success: false,
|
||||
error: 'Clip has no audio buffer'
|
||||
};
|
||||
const duration = parseFloat(args.duration_seconds || 3);
|
||||
const buffer = clip.buffer;
|
||||
const sr = buffer.sampleRate;
|
||||
const numChannels = buffer.numberOfChannels;
|
||||
const length = buffer.length;
|
||||
const ctx = getAudioContext();
|
||||
const newBuffer = ctx.createBuffer(numChannels, length, sr);
|
||||
for (let c = 0; c < numChannels; c++) {
|
||||
newBuffer.getChannelData(c).set(buffer.getChannelData(c));
|
||||
}
|
||||
const fadeSamples = Math.min(length, Math.floor(duration * sr));
|
||||
for (let c = 0; c < numChannels; c++) {
|
||||
const data = newBuffer.getChannelData(c);
|
||||
for (let i = 0; i < fadeSamples; i++) {
|
||||
const idx = length - fadeSamples + i;
|
||||
const factor = (1 + Math.cos(Math.PI * i / fadeSamples)) / 2;
|
||||
data[idx] *= factor;
|
||||
}
|
||||
}
|
||||
const beforeSnap = captureTrackSnapshot(track.id);
|
||||
setTracks(prev => prev.map(t => {
|
||||
if (t.id !== track.id) return t;
|
||||
const existingClips = t.clips && t.clips.length > 0 ? t.clips : t.buffer ? [{
|
||||
id: 'default_' + t.id,
|
||||
buffer: t.buffer,
|
||||
startTime: t.startTime || 0,
|
||||
name: t.name
|
||||
}] : [];
|
||||
const updatedClips = existingClips.map(c => {
|
||||
if (c.id === clip.id || clip.id.startsWith('default_') && c.id === 'default') {
|
||||
return {
|
||||
...c,
|
||||
buffer: newBuffer
|
||||
};
|
||||
}
|
||||
return c;
|
||||
});
|
||||
const mainBuffer = updatedClips[0]?.buffer || t.buffer;
|
||||
return {
|
||||
...t,
|
||||
clips: updatedClips,
|
||||
buffer: mainBuffer
|
||||
};
|
||||
}));
|
||||
setTimeout(() => {
|
||||
const afterSnap = captureTrackSnapshot(track.id);
|
||||
pushAction('AI_FADE_OUT', track.id, beforeSnap, afterSnap);
|
||||
}, 50);
|
||||
return {
|
||||
success: true,
|
||||
trackId: track.id,
|
||||
clipId: clip.id,
|
||||
duration_seconds: duration
|
||||
};
|
||||
}
|
||||
};
|
||||
window.DAWCommandDispatcher.registerDAWCommands(api);
|
||||
|
||||
Reference in New Issue
Block a user