Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion components/audio/DAW/Multitrack/ClipEffectsRack.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,18 @@ export default function ClipEffectsRack({ show, onHide, selectedClipId, logOpera
clips: selectedTrack.clips.map(c => c.id === selectedClipId ? updatedClip : c)
});

// Log for study protocol (Activity 3)
// Log for study protocol
if (logOperation) {
// eq_preset_applied unlocks Activity 3 Q5
logOperation('eq_preset_applied', {
clipId: selectedClipId,
presetName: presetName
});
// Applying a preset is also applying an effect (Activity 4 requirement)
logOperation('effect_applied', {
clipId: selectedClipId,
effectType: 'preset:' + presetName
});
}
}, [selectedClip, selectedClipId, selectedTrack, updateTrack, logOperation]);

Expand Down
41 changes: 32 additions & 9 deletions components/audio/DAW/Multitrack/TakesImportModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,49 @@ export default function TakesImportModal({ show, onHide, takes = [] }) {
useEffect(() => {
if (!show || takes.length === 0) return;

const audioElements = [];

takes.forEach((take) => {
if (take.duration > 0 || !take.audioURL || resolvedDurations[take.id] != null) return;

// For proxy / HTTP URLs, resolve duration via fetch + AudioContext decode
// since <audio> preload='metadata' needs range-request support
if (take.audioURL.startsWith('/api/') || take.audioURL.startsWith('http')) {
fetch(take.audioURL)
.then((r) => {
if (!r.ok) throw new Error(`${r.status}`);
return r.arrayBuffer();
})
.then((buf) => new AudioContext().decodeAudioData(buf))
.then((decoded) => {
if (decoded.duration && isFinite(decoded.duration)) {
setResolvedDurations((prev) => ({ ...prev, [take.id]: decoded.duration }));
}
})
.catch((err) =>
console.warn(`TakesImportModal: duration resolve failed for ${take.id}:`, err.message),
);
return;
}

// Blob URLs work fine with the Audio element approach
const audio = new Audio();
audio.preload = 'metadata';
audio.onloadedmetadata = () => {
if (audio.duration && isFinite(audio.duration)) {
setResolvedDurations((prev) => ({ ...prev, [take.id]: audio.duration }));
}
};
audio.onerror = () => {
console.warn(`TakesImportModal: Audio metadata load failed for ${take.id}`);
};
audio.src = take.audioURL;
audioElements.push(audio);
});

return () => {
audioElements.forEach((a) => { a.src = ''; });
};
}, [show, takes]);

// Update track name when take is selected
Expand Down Expand Up @@ -213,17 +245,8 @@ export default function TakesImportModal({ show, onHide, takes = [] }) {
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
};

// Mock data for testing if no takes provided
const displayTakes = takes.length > 0 ? takes : [];

console.log('🎹 TakesImportModal: Received takes:', takes);
console.log('🎹 TakesImportModal: Display takes:', displayTakes);

// Show helpful message if no takes
if (displayTakes.length === 0 && takes.length === 0) {
console.log('No takes available in TakesImportModal');
}

return (
<Modal show={show} onHide={onHide} size="lg" className="takes-import-modal">
<Modal.Header closeButton className="bg-dark text-white">
Expand Down
Loading