Skip to content

Fix Activity 3 multitrack DAW not rendering with bassline track#154

Merged
hcientist merged 2 commits intoLab-Lab-Lab:mainfrom
espadonne:fix/activity3-daw-bassline-loading
Mar 27, 2026
Merged

Fix Activity 3 multitrack DAW not rendering with bassline track#154
hcientist merged 2 commits intoLab-Lab-Lab:mainfrom
espadonne:fix/activity3-daw-bassline-loading

Conversation

@mfwolffe
Copy link
Copy Markdown
Collaborator

Problem

When navigating from Activity 2 to Activity 3 in the guided DAW study, the multitrack editor was not appearing and no bassline track was loaded. Three independent bugs prevented this:

What was happening (old approach)

  1. showDAW was never set to trueUIContext defaults showDAW to false, and the only call sites that set it to true were in recorder.js (when a user clicks "Edit" on a take) and standalone pages like /studio and /audio-utils/daw. Nothing in the Activity 3/4 flow ever enabled it. The DAW component's first line is if (!showDAW) return null;, so the entire editor was invisible.

  2. dawMode defaulted to 'single' — Even if the DAW had rendered, AudioContext initializes dawMode as 'single', and nothing in the activity flow switched it to 'multi'. The single-track waveform editor would have rendered instead of the multitrack editor.

  3. Bassline audio file did not exist — The initialTracks config hardcoded a path to /media/sample_audio/Air_for_Band_Bass_Line.mp3. This file doesn't exist in the frontend's public/ directory. The /media/ URL pattern is served by the Django backend, but the specific file path was incorrect and not sourced from any actual backend data.

What the new approach delivers

  1. DAWInitializer component — A small render-null component placed inside DAWProvider for Activities 3-4 that calls setShowDAW(true) and setDawMode('multi') on mount. It must live inside the provider tree because useUI() and useAudio() require their respective contexts.

  2. Bassline sourced from assignment data — Instead of a hardcoded path, the bassline track URL now comes from preferredSample, which is already resolved from the assignment's part.sample_audio or instrument-specific part.instrument_samples data (the same URL used for the <audio> player in Activities 1-2). The track name is derived from the actual piece name (e.g. "Freedom 2040 - Bassline").

  3. Loading gate for useState timingMultitrackProvider initializes tracks via useState(initialTracks), which only reads the value on first mount. Since preferredSample is set asynchronously in an effect, the provider could mount before the URL was available, resulting in empty tracks that never update. The fix adds a loading gate that keeps the spinner visible for Activity 3 until preferredSample is resolved, ensuring initialTracks is populated before the provider mounts.

  4. Removed unused initialTracks prop from <DAW> — The prop was accepted but never forwarded to child components. The tracks reach MultitrackContext correctly through DAWProviderMultitrackProvider, not through the DAW component itself.

Expected prod behavior

On navigating to Activity 3, students should see: spinner while assignment loads → multitrack editor appears with the piece's bassline pre-loaded as an audio track → student can add tracks, record, apply effects, etc.

⚠️ Needs prod testing

These changes fix the rendering pipeline and data sourcing, but need to be verified in a production environment where:

  • The Django backend serves the actual sample_audio files via /media/
  • A real assignment with a populated part.sample_audio or part.instrument_samples field is used
  • The full Activity 1 → 2 → 3 navigation flow is exercised end-to-end

Files changed

  • pages/courses/[slug]/[piece]/[actCategory]/[partType]/activity/[step].js — DAWInitializer, dynamic bassline URL, loading gate
  • components/audio/DAW/index.js — removed unused initialTracks prop

…ent data

- Add DAWInitializer component to set showDAW=true and dawMode='multi' for steps 3-4
  (showDAW defaulted to false and was never set in the activity flow, causing the
  entire DAW to render null; dawMode defaulted to 'single')
- Replace hardcoded nonexistent /media/sample_audio/Air_for_Band_Bass_Line.mp3 with
  preferredSample from the assignment's part data (backend-served URL)
- Gate DAWProvider mount on preferredSample being ready for step 3 to avoid
  useState(initialTracks) ignoring late-arriving track data
- Remove redundant initialTracks prop from <DAW> (already in context via provider)
@hcientist hcientist merged commit e054435 into Lab-Lab-Lab:main Mar 27, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants