fix: copilot Multi-tool Calling)
This commit is contained in:
@@ -7729,6 +7729,115 @@ const App = () => {
|
||||
return { ...t, markers: [...(t.markers || []), { id: 'ai_marker_' + Date.now(), time, label: args.label || 'AI Marker' }] };
|
||||
}));
|
||||
return { success: true, 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