Skip to content

31 days · 327 commits

March 2026

The last month before the public beta push. A lot of these commits are polish — the shape was already there.

  1. Day 335 · 9 commits
    Progress on 2026-03-01
    • Audio engine
      • f66d845Added sample browser metadata editor with genre field, manual key/BPM overrides, and inline editing panel
      • a282c30Fixed MP3 export Failed to set input media type on sink writer error in WmfAudioEncoder. The WMF MP3 encoder MFT only accepts 16-bit integer PCM input, but the encoder was feeding it 32-bit float PCM which works for AAC but not MP3. Changed the input media type to use MFAudioFormat_PCM with 16-bit samples for MP3 encoding while keeping MFAudioFormat_Float for AAC. Added float-to-int16 conversion with clamping in the sample writing loop, computed buffer sizes from the correct bytes-per-sample, removed MF_MT_AUDIO_BITS_PER_SAMPLE from the MP3 output type not valid for compressed formats, and added HRESULT codes to the SetInputMediaType error message for better diagnostics.
      • 024c9e0Drum Map visual polish and bug fixes (MIDI-014). Fixed CategoryComboCell missing Clap and Rim categories and corrected enum ordering to match DrumNoteCategory. Added category-colored drum notes on the piano roll grid using DrumCategoryColors instead of uniform time-of-day color. Added short instrument name labels on drum note bars with text shadow for readability. Polished DrumMapEditorDialog with category-tinted row backgrounds, MIDI note name display (e.g. '36 (C2)'), Group by Category/Sort by MIDI Note/Duplicate button factory map indicator, drop shadow, and larger dialog sizing. Removed all DRUM-DBG debug logging from PianoRollPaintManager.
      • 258f387PFL/AFL (Pre-Fader Listen / After-Fader Listen) end-to-end implementation. Registered PFL and AFL boolean APVTS parameters for all 16 mixer tracks and master channel in ParameterHelpersMixer.cpp. Fixed ParamIDs.h getPFLParamID/getAFLParamID to use MIXER_TRACK_X_PFL/AFL format matching the registered parameters, which also fixes BusWindowComponent's existing attachment code. Added listen bus audio routing in MixerTrackManager with a pre-allocated stereo buffer, cached PFL/AFL param pointers, and restructured the mute/solo skip logic so PFL can hear muted tracks — PFL taps the signal before the fader, AFL taps after post-fader inserts, and when any listen is active the main output is replaced with the listen bus sum (bypassed during offline rendering). Added AFL toggle button to MixerChannelStrip alongside PFL with cyan coloring, mutual exclusivity onClick callbacks, APVTS attachment, and stacked 15px layout. Added green LISTEN overlay indicator on the master fader area driven by MixerPanel's timer callback querying isListenBusActive
      • 859424dPhase Invert: Return panel layout refinements — unified Return Effects header matching main track typography 12px font, 25px height, baseline-aligned), replaced effect type combo boxes with radio-style toggle button stacks (Reverb/Delay/Chorus/None) in vertical mode, and trimmed aux return container bottom by scrollbar thickness so return faders align with main mixer faders without overlapping the horizontal scrollbar.
    • Timeline
      • b9069d2Fixed progress bar fill rendering artifact at low percentages in ExportStatusOverlay by clipping fill to track bounds and enforcing minimum width matching corner diameter.
    • UI / UX
      • 182c4b0Update Meta button to follow time-of-day theme colors
      • 5b001bbUI polish pass replacing native system dialogs and default progress bars with themed equivalents. Created ThemedProgressBar (h/cpp) as drop-in juce::ProgressBar replacement with time-of-day adaptive coloring, clip-masked rounded-rect fill, and centered percentage text. Created ThemedMessageOverlay (h/cpp) as self-managing modal overlay for notifications and confirmations with frosted-glass card, painted icons (info/warning/error/question), and async callback support. Rewired ConfirmationDialogs.h to route all 10 inline dialog helpers through ThemedMessageOverlay instead of native AlertWindow. Replaced bare juce::ProgressBar in BatchConversionDialog, PitchShiftSettingsPanelComponent, PluginScanProgressDialog, ProjectConsolidationDialog, and StemSeparationPanelComponent, removing hardcoded blue/lightblue colors. Removed dead ProgressBar pointer from MissingSampleRelinkDialog. Replaced ~35 NativeMessageBox::showMessageBoxAsync and AlertWindow::showMessageBoxAsync notification calls across 18 source files with ThemedMessageOverlay equivalents. Fixed ThemedProgressBar fallback constructor to use EphemeraLookAndFeel::getTimeOfDayBaseColour instead of static blue, with timer-driven updates so bars without an explicit theme color ref adapt dynamically.
      • c3c31b1Replaced native AlertWindow dialogs and buried ProgressBar with themed ExportStatusOverlay component. Created ExportStatusOverlay h/cpp as a modal overlay covering the ExportManagerWindow viewport area with semi-transparent backdrop and centered frosted-glass card matching time-of-day theming. Progress state shows animated custom-painted progress bar with percentage text, status message, and cancel button at 30Hz refresh. Success state shows checkmark icon, file path, 'Show in Explorer' and 'OK' buttons. Error state shows warning triangle with red-tinted title and message. Removed ProgressBar member and replaced 12 AlertWindow::showMessageBoxAsync calls across validateExportSettings, performExport, performSingleExport, and performBatchExport with statusOverlay showProgress/showSuccess/showError calls. Added setStatusMessage method for batch export 'Exporting X of Y' updates. Kept the interactive track selector AlertWindow dialog unchanged.
  2. Day 336 · 14 commits
    Progress on 2026-03-02
    • Audio engine
      • 8218b74Fixed duplicate gesture start crash by guarding against re-entrant beginChangeGesture calls on mixer mute/solo buttons during JUCE button state flash transitions.
      • 6771e4eImplemented VCA (Virtual Control Amplifier) fader groups for the mixer. Added VCAGroupManager backend with atomic arrays for real-time-safe audio thread reads, single-VCA-per-track assignment, per-condition volume/mute/solo state, and ValueTree persistence. Integrated VCA gain offsets into TrackChannel and MixerEngine frozen track paths with volume clamping to prevent extreme gain stacking. Created MixerVCAStrip UI components positioned after group strips in the mixer panel with fader, mute, solo, member count badge, and context menu. Added VCA offset visualization on member track faders showing ghost thumb position and colored assignment badges on channel strips. Wired track assignment through right-click context menus on channel strip names and 16-track membership toggles in the bus routing window. Connected listener interfaces so MixerPanel and BusWindowComponent auto-sync when VCA state changes.
      • b8d4d1fClamped chord note output to valid MIDI range 0-127 to prevent crash when chord intervals push notes beyond bounds.
      • f20a71aAdd MIDI drag export from piano roll control bar
      • bf1e9c4Sample browser polish pass addressing 6 items. Fixed favorites column star icon showing identical asterisks for both states by switching to filled ★ and empty ☆ Unicode characters. Extended duration filter slider range from 60s to 600s with skew factor giving finer control in the 0-60s range and added seconds/minutes text formatting. Added BPM min/max range sliders to the filter panel wired into the existing FilterState BPM fields. Replaced 6 full table rebuild calls in the metadata panel with targeted in-place row updates and repaint for tags, genre, key, BPM, note, and color edits. Added clear search × button next to the search bar in both horizontal and vertical layouts with time-of-day theming. Cached time-of-day color values in the table model with a 1-second refresh interval to eliminate hundreds of redundant getConditionMonitor and color interpolation calls
    • Modulation
      • df3dc90Replaced hardcoded key highlight colors with time-of-day tinted white and added themed hover highlights to white keys, black keys, and drum rows.
    • UI / UX
      • 5ca3b0dImplemented Render In Place for timeline clips. Added RenderInPlaceRenderer static class that offline-renders individual clips to 32-bit float stereo WAV files with trim, reverse, fades, and optional per-cell effects chain baked in. Created RenderInPlaceAction undoable action that stores full original clip state for each rendered clip, restores originals on undo, and deletes rendered WAV files when no longer referenced. Added four menu IDs (7650-7653) to TimelineGridMenuIDs and integrated into TimelineContextMenuHandler with Processing submenu items for single clips and multi-selection context menu items for batch rendering. Background thread renders clips without blocking the UI, then performs clip replacements and registers the undo action on the message thread.
      • d77455aExtended time-of-day theming to all piano roll components. Added pianoRollToggle/pianoRollBarButton properties and time propagation to sidebar selectors (Scale, Lanes, Arp, Insp), fixed ruler to use consistent base colour function, and triggered repaints of all themed components from viewport timer when time override changed.
      • d8dd6fdPolish piano roll toolbar: widen truncated GRID/SW labels, increase divider gap and brightness for clearer group separation, style swing value as a visible input box. Unify active toggle color to match tool button primary accent blue.
      • c625ab8Polish piano roll toolbar: convert toggles to themed TextButtons, add group dividers and segmented tool control
      • 588d702Fix chord draw mode placing single notes instead of chords by propagating tool type to the interaction handler. Fix chord shape transposition to root at the clicked note and add nearest-chord fallback for non-scale-degree notes. Add step interval combo and independent cursor to ChordStripComponent for controlled chord button placement spacing.
      • 6b93b5fUpdate bottom bar combo boxes to follow time-of-day theme colors. Added gridSelectComboBox property to cycleRecordModeCombo and timeSigDenominatorCombo in BottomBarComponent so the ComboBoxStyleRenderer applies the same time-aware styling used by combo boxes elsewhere in the UI. Wired currentHour and currentMinute property updates and repaint calls into updateBottomButtonColors so both combo boxes refresh dynamically with the rest of the transport bar controls.
      • 07abacbUpdate bottom bar combo boxes to follow time-of-day theme colors. Added gridSelectComboBox property to cycleRecordModeCombo and timeSigDenominatorCombo in BottomBarComponent so the ComboBoxStyleRenderer applies the same time-aware styling used by combo boxes elsewhere in the UI. Wired currentHour and currentMinute property updates and repaint calls into updateBottomButtonColors so both combo boxes refresh dynamically with the rest of the transport bar controls.
      • cf91193Added chord strip and chord draw feature to piano roll. Created DiatonicChordEngine utility class that computes diatonic triads by stacking thirds within any scale type, and ChordStripComponent UI strip with key/scale/octave selectors and clickable chord buttons that sync bidirectionally with ScaleSnapManager. Added Chords toggle to PianoRollControlBar and wired the collapsible strip into PianoRollViewport between the minimap and time ruler. Implemented ChordDraw tool type in PianoRollInteractionHandler that places full chords instead of single notes when clicking the grid. Added hover chord name labels to PianoKeyboardComponent that display diatonic chord names as pill overlays on white and black keys when the chord strip is visible.
  3. Day 337 · 9 commits
    Progress on 2026-03-03
    • Audio engine
      • 62397e2Implemented MIDI clock output for syncing external hardware. Added MidiClockGenerator for RT-safe 24 PPQN clock pulse generation with Start/Stop/Continue transport messages and Song Position Pointer on seek. Added MidiOutputManager with lock-free SPSC FIFO and HighResolutionTimer for sending MIDI to a selected output port without blocking the audio thread. Wired both into PluginProcessor's processBlock via a dedicated midiClockTemp buffer to keep clock messages separate from internal MIDI routing. Added PID_MIDI_CLOCK_ENABLED APVTS parameter with state persistence of the selected output device through ProcessorState's ValueTree serialization. Extended PluginMidiTabComponent with a MIDI Clock Output section containing an APVTS-bound toggle, device selection combo, and timer-driven status label showing running/stopped/disabled state.
      • 1ccfaa8Implemented 7 quick-win features from the backlog. Added DC offset removal to the timeline Processing context menu with background thread processing and per-file deduplication. Extended parameter copy/paste support to EQ, Bus, Aux, Master Volume, and Mixer Effect Slot components by wiring ModulatableSlider clipboard callbacks and adding the required setParameterID calls. Completed zero-crossing snap for waveform editor markers with a 20ms search radius algorithm that activates via the existing toolbar toggle. Created PianoRollQuantizeDialog with grid resolution and strength selection that applies partial quantization through MidiQuantizeHelper with full undo support. Added MIDI click output option to the metronome that sends note-on/note-off events on channel 10 with accent-aware velocity. Added a session notes TextEditor to ProjectInfoWindow wired to ProjectMetadataManager for persistent project annotations. Implemented metronome sound selection with five presets (Classic, Soft, Bright, Wooden, Electronic) each using distinct waveform generation, exposed via a Click Sound submenu in the metronome right-click menu with safe message-thread buffer regeneration.
      • a8a7a6bBottom bar polish: active nav states, zone separators, monospace fonts, BPM drag, punch theming, nav grouping
      • fd455f9Apply themed popup menu styling to metronome right-click menu and tag metronome button as bottomBarButton with time properties so it uses time-of-day accent colors instead of static orange. Brighten the bottom bar button lit state for better visibility.
      • 714f883Implemented count-in before all playback with visual countdown. Added MetronomePreCountMode parameter with Record Only and All Playback options to metronome settings menu in BottomBarButtonHandler. Extended RecordingViewModel with startPlaybackPreCount and cancelPlaybackPreCount methods that enter PreCounting from Idle state and modified transitionFromPreCountToRecording to return to Idle instead of Recording for playback pre-counts. Added buffer muting in PluginProcessor processBlock between global volume and metronome rendering so only clicks are heard during count-in. Integrated pre-count triggering into EditorPlaybackController for both Stopped-to-Playing and Paused-to-Playing transitions with cancellation on Stop and Pause. Added visual beat countdown in BottomBarComponent update that replaces the time label with beat and bar context, theme-colored for playback and red for recording, plus a transport area flash effect in paint that pulses on each beat boundary.
    • UI / UX
      • 5915a63Move the time display label from the Clock Zone (after time signature controls) to the Transport Zone, positioned directly between the Record and Punch buttons. Increase font size dynamically (controlHeight * 0.6f, clamped 14-28px) for better readability, widen the label from 100px to 130px, and center-justify the text. Update the Timing/Navigation zone separator to reference timeSigDenominatorCombo instead of the relocated timeLabel.
      • b5fcf2cFix waveform editor loop marker dragging and tool switching bugs. Rewrote hitTestMarker() in WaveformMarkerOverlay with tool-aware priority ordering so the active editor tool's markers are checked first, resolving the overlap ambiguity where loop markers at default positions (0.0, 1.0) were unreachable because trim markers always won the hit test. Added auto-disable logic in WaveformDisplayComponent's onToolChanged handler that removes the blue loop overlay when switching away from the Loop tool if loop points are still at their default positions, while preserving intentionally-set custom loop regions.
      • 8587a43Add time-tinted hover highlight to bottom bar toggle buttons. When unticked, hovering now shows a subtle theme-aware background instead of the near-invisible generic white overlay.
    • Other
      • 7d79405Moved Clock to right of Rec
  4. Day 338 · 6 commits
    Progress on 2026-03-04
    • Audio engine
      • d01283aImplemented per-track MIDI output routing to external hardware synthesizers. Added TrackMidiOutputManager with reference-counted device pool, atomic RT-safe snapshot for audio thread access, and ValueTree persistence. Extended PianoRollPlaybackEngine with processBlockPerTrack(), onTransportStartPerTrack(), and onTransportStopPerTrack() methods that generate MIDI into per-track buffers wrapping the existing processTrackMidi(). Modified PluginProcessor processBlock to route externally-assigned tracks through MidiOutputManager's lock-free FIFO with channel remapping while merging unassigned tracks into the internal buffer, with zero overhead when no external outputs are configured. Added ProcessorState save/load delegation following the TrackRecordArmManager pattern. Built a Track MIDI Outputs UI section in PluginMidiTabComponent with 16-row scrollable table containing device combo, channel selector, and enable toggle per track.
    • UI / UX
      • a816599Fixed accidental underline on grid title headers by passing Font::plain instead of weight value as JUCE style flags in FontFamily::createFont. Replaced hardcoded purple waveform gradient in TimelineGridPainter with time-of-day aware createTimelineWaveformGradient.
      • 290cf3fLocationGridComponent performance caching, MVVM listener, and preload flash animation. Cached header gradient (16 color stops) and breathing multiplier (10Hz polling) to eliminate per-frame recalculation. Added BaseViewModel::Listener inheritance with onViewModelPropertyChanged callback handling gridLayout, headerViewMode, selection, interaction state, hover, display mode, and cell dimensions. Connected ViewModel listener registration in constructor/destructor and added headerViewMode write-through. Implemented CellFlash struct with triggerCellFlash, updateCellFlashes (cosine ease-out over 1s), and paintCellFlash (cyan glow border + inner fill) matching WeatherGridComponent's pattern.
      • a12c69dCached header gradient, breathing multiplier, and icon rendering to reduce per-frame work in SeasonGridComponent. Added BaseViewModel Listener for MVVM property notifications. Breathing now polls at 10Hz, gradient rebuilds only on resize or view mode change, and icons pre-render in resized instead of during paint.
      • 4eb5746Season grid: pre-render icon cache to eliminate per-frame opacity changes
    • Other
      • 37fcbedSeasons Batch Optimizations
  5. Day 339 · 5 commits
    Progress on 2026-03-05
    • Audio engine
      • fcfeeb0Eliminated per-frame vector allocations in drawAtmosphericParticles, drawSplashEffect, and GPU rain rendering by switching to single-pass inline loops and a persistent particle buffer. Replaced expensive atan() calls in snow pile physics with direct height ratio comparison against a precomputed tan threshold.
    • Modulation
      • 24da7a1Corrected render optimizer background clipping caused by using parent-coordinate getBounds() instead of local-coordinate getLocalBounds() in GridPaintManager's batched rendering path. Fixed inverted phase terminator shadow in MoonPhaseGridComponent that was darkening the lit side of waxing moon phases.
    • UI / UX
      • 8fc8b94MOON-001 to MOON-009: Added performance caching and MVVM integration to MoonPhaseGridComponent matching LocationGridComponent patterns. Implemented icon pre-rendering, 10Hz breathing cache, header gradient cache with dirty invalidation, BaseViewModel::Listener with property change callbacks and ViewModel write-through, and preload flash animation with cosine ease-out cyan glow. --- Hero moon background: Added procedural hero moon background to MoonPhaseGridComponent rendered per-pixel to a cached ARGB image with spherical limb darkening, deterministic maria and craters with bright rims, and spherical terminator projection for distinct phase shadows. Implemented multi-octave hash-based surface noise at three block sizes for rough regolith texture, time-of-day visibility scaling, exponential outer glow, and zero per-frame cost through dirty-flag cache invalidation on resize, phase, or hour change.
      • 5b9f2f0Fixed UI lag when activating Snow/HeavySnow weather states by capping the snow pile ARGB image allocation to 800x600 instead of full window size, batching snow landing ellipse draws into a single Graphics session per frame instead of one per particle, throttling snow physics (stability checks and settling) to every other frame, and eliminating per-frame vector allocations in the snow renderer by replacing the two-pass pointer-sorting approach with a single inline loop.
      • e19ffcaReplaced blobby radial-gradient fog ellipses in drawFogHazeEffect with thin horizontal streaks using linear gradients for a streakier, more atmospheric look. Fixed the fog animation loop cut caused by linear windPhase accumulation by switching all drift calculations to sin()/cos() oscillations that wrap seamlessly. Fixed the InfoChironComponent location controls (Lat/Lon editors and Update button) being clipped by increasing the allocated width from 180px to 280px, shortening labels to 'Lat:'/'Lon:', and rebalancing the layout so all elements including the weather update button are visible.
  6. Day 340 · 9 commits
    Progress on 2026-03-06
    • Audio engine
      • 276f2feFixed use-after-free crash when stopping playback with pitch/time shift active. Changed releaseEffectProcessors to reset processor state instead of destroying objects, since the audio thread accesses them lock-free without holding poolMutex
      • 767161aAdded smooth phase crossfade to the hero moon behind MoonPhaseGridComponent by replacing the discrete phase index lookup with continuous illumination interpolation. Changed renderHeroMoon to accept a float illumination and bool isWaning instead of an integer phase index, added 180-frame smoothstep transition state that interpolates both the terminator shadow position and the horizontal column position when the moon phase changes, quantized the illumination to 0.005 steps during transitions to limit per-pixel re-renders, and added a timer-driven repaint to keep the animation running until the transition settles.
      • f261cccAdded smooth moon phase crossfade system to the environment visualizer so phase transitions appear as the moon turning to its new position rather than snapping instantly. Modeled the lunar cycle as a continuous angle from 0.0 to 1.0 and derived illumination and light direction mathematically using a triangle wave, replacing the discrete eight-case switch statement in the renderer. Added shortest-path circular interpolation in the particle updater that always takes the short way around the cycle with ease-out deceleration near the target. Snapped the phase angle to the current moon phase on startup and reset to prevent an unwanted transition on load.
      • 179cfa5Added 5th header view mode (GlassCards) to MoonPhaseHeaderViewMode enum and set it as the default for both sample and effect grids. Implemented dark glass card rendering with inset gaps between cells, rounded corners, breathing-modulated brightness on the active phase, white borders at variable alpha, and a 5px top accent glow that interpolates from dark blue to cyan based on illumination percentage. Replaced 3D PNG moon icons with cached 20x20 procedural flat icons using semicircle arcs and elliptical terminator curves for correct phase shapes. Added 'Glass Cards' entry to the header view context menu in both grids, updated ViewModel range checks to accept the new mode value, and suppressed the yellow pulsating overlay on the effect grid when in GlassCards mode since it has its own active-card highlighting.
    • UI / UX
      • 0dc2ebdAdded luminance-based text color flipping so labels switch to dark text on bright phase backgrounds like Full Moon and Gibbous. Applied 1px dark text shadows on light-on-dark labels, boosted subtitle font size and opacity for the '% lit' indicators.
      • 0d44668This adds a glow effect to both vertical edges of the active column for moon phase grid
      • acd762d Added opaque backing disc in moon grid background to occlude stars from the environment visualizer. Fixed render priority ordering so background (0) paints before headers (1), content (2), and overlay grid lines (3) instead of last.
    • Infrastructure
      • c0e74d6Moved TimeOfDayColorSystem inline functions to .cpp files to reduce build time. Extracted ~2,053 lines of inline function bodies from four DesignTokens headers (TimeOfDayColorSystem, ContrastUtilities, PatternColors, ColorHarmony) into corresponding .cpp files so the compiler processes them once instead of 237 times. Headers now contain only declarations, type definitions, and the inline global TimeTransitionState instance. Fixed five function signatures (createTimelinePlayheadBloom, createTimelineDragTrailGradient, createTimelineClipGlassGradient, createTimelineWaveformLilacGradient, createSequencerButtonGlow) that had diverged from their call sites during the initial extraction.
      • 228a1afDisabled unused JUCE modules juce_box2d, juce_analytics, juce_animation, juce_midi_ci, juce_javascript to reduce build time
  7. Day 341 · 1 commit
    Progress on 2026-03-07
    • UI / UX
      • 2488020Added LunarCalculator helper with continuous moon cycle position, illumination percentage, and moonrise/moonset estimation. Refactored TimingModule to delegate moon math to LunarCalculator, exposed cycle position through ConditionMonitor, and enhanced Moon Phase grid tooltips to show illumination % and rise/set times — MOON-011, MOON-012, MOON-013
  8. Day 342 · 5 commits
    Progress on 2026-03-08
    • Modulation
      • 8c099d7Added unique sky palettes for all 11 weather conditions in the Summer column — clear blue, overcast gray, dark slate rain, bruised purple storms, green-gray hail, milky fog, and graduated snow skies. Fixed opacity stacking bug where bokeh draw's setOpacity persisted into the sky gradient, making non-clear weather skies invisible. Heavier weather conditions push cloud coverage further down the column.
      • 2bfca5aAdded weather-dependent sky rendering to the Summer column. Blue sky now appears in the top region during clear weather, with unique sky palettes for all 11 weather conditions — overcast gray-blue for cloudy, dark slate for heavy rain, bruised purple-gray for thunderstorms, sickly green-gray for hail, milky white for fog, and graduated white-grays for snow conditions. Heavier weather pushes cloud coverage further down the column. Sky is painted over the bokeh layer to ensure visibility, respects season/weather overrides, and is suppressed at night.
    • Visualizer
      • 878effaReplaced the 5-pass multi-stroke wire rendering with a filled-outline approach using Catmull-Rom to cubic bezier conversion for smooth tapered vine stems. Vines now cascade from top to bottom with 3 vines per side, gnarled branches that droop with gravity, and leaf density that increases toward the hanging tips. Added vine flowers as radial gradient blossoms along stems, a dense flower bed garden at the column base with blossoms, buds, leaf clusters, and sprays, plus three leaf types including standard, double, and tendril curls.
    • UI / UX
      • ab5d60dAdded full living-world weather and time-of-day system to the Summer column. Enhanced sunset sky with rich magenta-to-fiery-orange-to-deep-purple multi-stop gradient and golden rim-light highlights on front canopy leaf edges during evening. Added deep indigo/navy night sky overlay with weather-specific variants, pushed leaves to near-silhouette darkness at night, and boosted firefly brightness 1.8x so they become the star of the show after dark. Added pale lavender-pink dawn sky and breathing morning mist at column base with secondary wisps, also active during fog weather. Implemented slanted rain particle system with intensity tiers for drizzle, heavy rain, and thunderstorms, plus random white-blue lightning flashes with fast decay and double-flash probability during storms. Added heat haze shimmer with wavy horizontal distortion lines in the bottom 30% during hot clear daytime. Made all leaves, fronds, vines, and dappled shadows respond to weather-driven wind with amplified sway up to 3.5x during storms, smoothly interpolating between wind states. Fixed fillRect ambiguity from mixed float/int arguments in the morning mist renderer.
      • 2995fc1Moved Latitude and Longitude controls out of the InfoChiron scrolling text row into their own dedicated row below it. Added a two-row layout mode to InfoChironComponent that activates when the Weather grid is visible, with the top row for scrolling text and time display at full width and the bottom row for Latitude/Longitude input fields, Update button, and 'weather by Open-Meteo' attribution. Updated EditorLayoutManager to use dynamic height from InfoChironComponent so the info area expands to 40px in Weather view and collapses back to 20px for all other grids.
  9. Day 343 · 14 commits
    Progress on 2026-03-09
    • Modulation
      • b1d18f1 Added next major moon phase countdown to the title row right side, showing days until the nearest New Moon, First Quarter, Full Moon, or Third Quarter. Implemented getNextMajorPhase() in LunarCalculator using cycle position boundaries and synodic month duration, cached the formatted string in timerLogic(), and rendered it right-aligned at 11pt with 0.75 alpha to complement the left-aligned title and center-positioned rise/set text.
      • af8a956Improved lunar phase calculation accuracy by replacing the mean synodic month division approach in getCyclePosition with angular elongation between Moon and Sun ecliptic longitudes, reducing drift from ~14 hours to ~1-2 hours. Extracted getMoonEclipticLongitude from getMoonPosition to eliminate code duplication, added getSunEclipticLongitude using simplified Meeus ch.25, and added verification tests against known USNO new/full moon dates.
      • 0bdf83aAutumn column visual system: amber bokeh, falling leaves, gnarled branches, frost & harvest moon. Winter column visual treatment: Enchanted Frozen Forest with 13 layered effects
    • Visualizer
      • d092536Add smooth-looping firefly animation by using integer frequency multipliers so sine waves complete whole cycles within the breathing phase period, eliminating the visible jump at the 2π wrap point.
    • UI / UX
      • 536ba48Added severe weather alert visualization to the weather grid header. Forecast data now classifies WMO codes for heavy rain, heavy snow, thunderstorms, and hail as severe, tracked via a new isSevere flag on ForecastData. When severe conditions appear in the 24-hour forecast, affected column headers display a pulsing red/orange border with an inner glow and a small red exclamation badge in the top-left corner, animated at a ~2 second cycle driven by the existing timer. Tooltips for severe conditions are prefixed with a warning indicator for additional context.
      • 6d2ecfaWeather forecast badge: Fixed the active weather condition's forecast badge not appearing in the header after refreshing. The paint code only checked timeRemaining which was never set for the current condition it used continuingDuration instead. Added a branch to render the current condition's badge using its continuing duration text, a smart prefix that skips 'In' for duration strings starting with '~', and a '~now' fallback so the badge always displays for the active condition.
      • dc1f6baWeather Grid: Spinner always spins
      • 98d8c24Added loading spinner animation to weather forecast refresh button. When clicked, the button text changes to 'Fetching...' and disables to prevent duplicate requests, while a small spinning indicator appears to its left. Both reset automatically when the forecast service responds, whether successful or not.
      • 682accbAdded dedicated weather icons for Flurries, Heavy Snow, and Blizzard conditions, replacing reused snow and fog placeholders. Generated three 20x20 PNGs matching the existing pastel icon style and updated BinaryData references in WeatherGridComponent and WeatherEffectGridComponent.
      • 3b4cc37Added blue moon detection and visual indicator for months containing two full moons. Implemented isBlueMoonMonth() in LunarCalculator which steps through the month in 12-hour increments counting full moon crossings at the 0.5 cycle position boundary, cached the result in MoonPhaseGridComponent::timerLogic() with monthly recalculation to avoid redundant computation, rendered a 'Blue Moon' pill badge in the title row between the zodiac sign and next phase countdown, and added a subtle blue tint overlay with blue border highlight on the Full Moon column header across all view modes.
      • 405f392Add zodiac sign display to moon phase grid title row, showing which zodiac sign the moon is currently transiting such as Moon in Gemini positioned after the title text. Added getZodiacSign() to LunarCalculator using existing ecliptic longitude calculation mapped to 12 zodiac segments, cached the result in timerLogic, and rendered it alongside the next phase countdown at 13pt for readability.
      • 1b47b20Add moon rise/set time display to title row above active phase column with dark backing pill, replacing the previous unreadable two-line layout crammed into SplitView and GlassCards column headers.
      • 01269fdReplaced hardcoded moon illumination percentages with LunarCalculator cosine model values and added real-time illumination display for the active phase column in SplitView and GlassCards header modes. The active column now shows the actual current illumination percentage from the elongation-based cycle position, while inactive columns show representative midpoint values computed via LunarCalculator::getIlluminationFraction.
      • 3cd1ab8Brought the Spring column renderer to feature parity with Summer, Autumn, and Winter by adding weather-responsive effects that were previously missing entirely. Spring now has gentle rain showers with warm blue-lavender streaks, thunderstorm lightning flashes, wind-responsive vegetation sway (up to 3x in storms), lavender-tinted morning mist during dawn and fog, weather-dependent sky gradients for all 11 weather conditions, a Spring-unique morning dew sparkle effect with independently pulsing gold-white dots, and a dramatically upgraded night showcase with 14 wandering fireflies featuring sinusoidal drift paths, varied sizes for depth, independent pulse timing, and faint glow trails.
  10. Day 344 · 5 commits
    Progress on 2026-03-10
    • Modulation
      • cd97642Rewrote environment visualizer moon rendering from path-based crescent clipping to full-disc per-pixel rendering matching the hero moon approach. The old implementation only drew the lit portion as a clipped path, making the dark side completely invisible and causing phases to cut in and out unnaturally. The new renderer always shows the complete spherical disc with limb darkening, procedural surface texture (maria, craters with rims, multi-level noise grain), spherical terminator shadow that smoothly sweeps across the surface, earthshine on the dark side, and an always-visible rim glow. Also fixed the terminator direction bug where crescent and gibbous phases were swapped, and removed the early return that hid the moon entirely at new moon phase.
    • UI / UX
      • bc89238Extended active column highlight vertical glow lines through the segment bar row by starting them from y=0 instead of the hour header row. Reverted the separator color changes in GridDisplayComponent and EndlessScrollGridComponent since those were painted under the grid lines and never visible.
      • dba7cbdReduced environment visualizer moon brightness so it doesn't overpower the grid. Lowered surface brightness base, luminosity scaling factor, glow halo alpha, and rim glow intensity.
      • 6c6ffa5Hid the environment visualizer sky moon when the moon phase grid is active since the hero moon already represents the current phase. Added a moonGridActive flag to EnvironmentVisualizerComponent with a public setter, wired it from PluginEditor's view switch handler, and added an early return in the renderer's drawSunMoonEffect to skip moon rendering when the flag is set.
      • 417db0fAdded forecast-aware parameter scheduling as a new modulation source that bridges 24-hour weather forecast data into the existing modulation engine. Users can now define transition rules that gradually modulate parameters before predicted weather arrives, such as increasing reverb 30 minutes before rain. Created ForecastScheduleManager to own transition rules with atomic progress values, curve shaping, 30-second cancellation fades, and override/freeze suppression. Created ForecastTransitionSource as the EnvironmentalModSource adapter and ForecastSchedulePanel with inline rule editing and a real-time curve preview. Wired the new ForecastTransition source into ModSourceID, isEnvironmentalSource, ModulationSourceManager, PluginProcessor, and ProcessorState persistence. Added a Transitions button in the WeatherGridComponent header and a Forecast option in the modulation routing source dropdown.
  11. Day 345 · 2 commits
    • UI / UX
      • 52e8d6bGrid buttons navigate out of Timeline/Sequencer mode to target grid. Season grid: increase header text sizes
    • Other
      • c7e3ecaDev Tools: Screenshot Capture Tools
  12. Day 346 · 0 commits
    • Day 347 · 9 commits
      • UI / UX
        • 74f5a3fDayOfWeekGridComponent: Connect config settings to grid rendering via GridRegistry
        • 2291747Add dayOfWeekGridComponent member to PluginEditor with full integration across 13 files: visibility management, layout bounds, drag-drop handling, theme color blending, navigation, zoom controller, toolbar jump-to-condition, grid registry mappings, screenshot automation, waveform tooltips, and ProcessorState persistence. TopRowComponent button already existed — this connects it to an actual grid instance.
        • 4b2d0e8Location grid: add coordinate tooltips on header hover and persistent coords display in title row
        • aadfa27Location grid: maximize title label font size and remove padding
        • f02c77dAdd Detection Settings section with four combo boxes for future geofencing runtime: location source (Manual/GPS/IP), update interval (1-60 min), fallback location (Last Known or any built-in type), and multi-match behavior (Nearest/Priority/Blend). All settings persist to grid properties and are included in preset save/load. UI-only for now.
        • 939018fExpand LocationConfigComponent from 6 hardcoded locations to all 16 from LocationType constants. Use stable semantic IDs (forest, beach, city_busy, etc.) instead of index-based IDs to prevent breaking saved settings. Add category subheaders (Natural, Urban, Social, Indoor, Industrial, Personal) for visual grouping. Remove redundant label column — name editor now serves as both display and edit field, freeing horizontal space for wider coordinate inputs.
        • f700fc4Location Grid: Added All locations
        • ec1ed96Add lat/lon coordinate editors to built-in and custom location rows in LocationConfigComponent. Add activation radius slider (0.1-50km). Improve custom location creation with text input dialog, inline editable names, and color pickers. Persist coordinates and radius in grid properties and presets. Add coordinate validation with visual feedback. Add 'Configure' button to LocationGridComponent title row that opens config in a callout.
      • Other
        • 7d12e7dConditionMonitor: Added getCurrentDayOfWeek() method and day change detection
    • Day 348 · 20 commits
      • Audio engine
        • e2f2e7dCreated OmniAnimationController with timer-driven easeOutSpring layout interpolation for panel bounds, splitter positions, and alpha values at 60fps. Added entry animation to enterOmniMode that slides panels in from off-screen edges and fades them in over 300ms with interactions disabled during playback. Added 200ms collapse and maximize animations that capture before and after layout snapshots and interpolate between them. Wired animation callbacks in OmniGridComponent to apply interpolated snapshots each frame and restore full alpha and interactions on completion
        • be9a82dFixed top-left Omni panel not receiving mouse input by returning false from MixerUIManager hitTest when Omni mode is active, preventing the always-on-top mixer overlay from intercepting events meant for the panels beneath it.
        • 0485464Embedded the MixerPanel into the Omni Grid TopRight panel and added grid selection persistence across mode switches. Added OmniDocked DisplayState to MixerPanel and getMixerPanel accessor plus setOmniModeActive flag to MixerUIManager, suppressing mixer toggle shortcuts while in Omni mode. Stored the pre-Omni mixer DisplayState for restoration on exit. Added lastSelectedGridType to OmniLayoutManager so re-entering Omni mode restores the previously selected sample grid instead of defaulting to the active view.
        • de6e35fWired the grid selector ComboBox onChange callback to swap the embedded sample grid in the Omni view. Added getGridComponentForType to resolve GridType enum values to editor grid components and switchSampleGrid to perform the restore-then-embed swap pattern, updating the panel header title from GridRegistry after each switch.
        • 71cc5bcAdded keyboard navigation and grid selector ComboBox for the Omni Grid view. Implemented Escape to exit Omni mode and return to the previous grid view, with pre-Omni mode stored on entry. Registered Ctrl+Shift+O as a global toggle shortcut for Omni view in the ShortcutRegistry and EditorKeyboardShortcutHandler. Added OmniGridComponent as a friend of PluginEditor for access to handleGridModeChange. Created an optional grid selector ComboBox in OmniPanelHeader for the Sample Grid panel, populated from GridRegistry enabled grids with ComboBox IDs offset by one to satisfy the greater-than-zero requirement, and synced to the activ grid type on Omni entry.
        • 14391bfEmbedded sequencer and sample grid components into the Omni Grid view. Added getSequencerGridComponent accessor to PluginEditor and embedded SequencerGridComponent into the Sequencer panel during enterOmniMode. Created getActiveSampleGridComponent helper that resolves the correct environmental grid based on the current active view, falling back to TimeOfDay when in Timeline or Sequencer mode, and embeds it into the Sample Grid panel with a dynamic header title reflecting the active grid type.
      • UI / UX
        • 8701adbAdded tiered rendering performance optimization for the Omni Grid view using buffered-to-image caching on unfocused panels. Added onFocusChanged callback to OmniFocusManager and wired it in OmniGridComponent to toggle setBufferedToImage, caching unfocused panels to avoid redundant repaints from timer-driven playhead animations while the focused panel renders live at full framerate. Buffering is set on Omni entry, updated on each focus change, and cleared on exit.
        • 7063a19Added panel focus visual polish with time-of-day accent colored borders drawn via paintOverChildren on OmniPanelContainer. Focused panels show a 2px accent border with subtle drop shadow, unfocused panels show a 1px muted border for delineation. Updated setPanelFocused to trigger repaint and added updateTimeOfDayAccentColor using DesignTokens getCurrentTimeHighlightColor called on Omni mode entry. Verified context menus and component state preservation work correctly with reparented components requiring no code changes.
        • a023018Fixed shutdown crash in OmniEmbeddingManager destructor by clearing embed records instead of restoring to already-destroyed parent components during editor teardown.
        • 5ef8531Added per-panel keyboard routing and cross-session layout persistence for the Omni Grid view. Unhandled key events in OmniGridComponent are now forwarded to the focused panel content component so timeline, sequencer, and grid shortcuts work based on which panel has focus. Added saveToValueTree and loadFromValueTree to OmniLayoutManager serializing split ratios, collapse states, panel assignments, and last selected grid type. Wired persistence through ProcessorState so Omni layout survives plugin close and reopen, loading on OmniGridComponent construction and saving on exit from Omni mode.
        • 7d1e695Fixed OmniPanelHeader z-order so collapse, maximize buttons, and grid selector ComboBox render above embedded content components by calling header toFront after content is added and on each resized.
        • ad6aab9Fixed infinite recursion crash in OmniPanelContainer mouseWheelMove by consuming the event without forwarding to content component, which already receives wheel events directly from JUCE dispatch.
        • 890292cAdded scroll isolation, focus management, and splitter snap polish for the Omni Grid view. Overrode mouseWheelMove in OmniPanelContainer to forward scroll events to content components and consume them, preventing propagation to adjacent panels. Created OmniFocusManager with focus-follows-click via panel mouseDown callbacks, Tab and Shift-Tab cycling that skips collapsed panels, and visual focus ring updates. Added snap-to-grid behavior to OmniSplitterBar at five common ratios with 15px pixel tolerance, Shift-held bypass for free positioning, a bright snap indicator line when locked, and grip line spread animation on hover
        • 4dae26aWired Omni mode into the PluginEditor visibility and layout pipeline. Updated EditorViewManager updateViewVisibility to detect Omni mode entry and exit, calling enterOmniMode to embed components and exitOmniMode to restore them when switching away. Hides all individual grid components, timeline-specific elements, sequencer UI, and mainContentComponent when Omni is active. Updated EditorLayoutManager to position OmniGridComponent in the main content area and hide the environmental grid toolbar in Omni mode. Added early return in repaintActiveGrid for Omni mode and excluded Omni from view transition and active view resolution paths.
        • 6a32f71Implemented panel maximize functionality and timeline panel embedding for the Omni Grid view. Added maximize callbacks wired from each panel header to the layout manager, with pre-maximize state snapshot storing all three split ratios and four collapse states for perfect restoration. When maximized, all other panel containers and splitters are hidden and the maximized panel fills the full area. Added Escape key handling via KeyListener to restore from maximize. Created enterOmniMode and exitOmniMode methods on OmniGridComponent that use the OmniEmbeddingManager to safely reparent TimelineGridComponent from PluginEditor into the Timeline panel container and restore it on exit.
        • 0cd117dImplemented panel collapse functionality and created the OmniEmbeddingManager for safe component reparenting. Updated OmniLayoutManager getEffectiveBounds to give collapsed panels a 28px header-only rectangle while the adjacent column neighbor expands to fill the freed space, removing the vertical splitter gap. Wired each panel header collapse button callback through OmniGridComponent to the layout manager, with content component visibility toggling and vertical splitter hiding when either panel in a column is collapsed. Created OmniEmbeddingManager to record original parent, bounds, and visibility state before embedding components into OmniPanelContainers, using MessageManager callAsync for deferred reparenting to avoid Timer and AsyncUpdater re-entrancy, with synchronous restoreAll for clean mode exit.
        • 58ceeacWired all three OmniSplitterBars into OmniGridComponent with OmniLayoutManager integration for the full 2x2 draggable layout. OmniGridComponent now owns a horizontal splitter dividing left and right columns and two vertical splitters dividing top and bottom within each column, with drag callbacks updating normalized split ratios and triggering layout recalculation. Created OmniPanelHeader as a 28px header bar with FlexBox layout containing title label, collapse chevron button, and maximize button, supporting double-click to toggle maximize and focus indicator rendering. Integrated OmniPanelHeader into OmniPanelContainer replacing the inline paint header. Added Omni View option with separator to the TopRowComponent grid mode selector ComboBox and updated both comboBoxChanged and setMode to hide view buttons and controls top row when Omni is active. Extracted OmniPanelID and OmniQuadrant enums into OmniTypes.h to resolve circular include dependencies between Omni headers.
        • 109d3ebAdded OmniSplitterBar, OmniPanelContainer, and OmniModeID constant as foundational components for the Omni Grid view. Created OmniSplitterBar with horizontal and vertical orientations, MixerDragHandle-style grip lines, hover state with cursor changes, and std::function drag callbacks that emit normalized positions. Created OmniPanelContainer as a quadrant wrapper with a 28px header zone, non-owning content component management, and focus indicator support. Added OmniModeID to the GridModeIDs enum in Constants.h, OmniView to NavigationManager ViewType, and OmniModeID cases to all three WaveformTooltipProvider switch statements.
        • 43af471Added OmniLayoutManager as a pure layout math utility for the Omni Grid 2x2 view. Stores normalized split ratios for horizontal and vertical column divisions, panel-to-quadrant assignments via OmniPanelID, and per-panel collapse and maximize state. Implements calculatePanelBounds to compute four quadrant rectangles accounting for 6px splitter thickness and minimum size constraints, and getEffectiveBounds to handle maximized panels taking full area and collapsed panels redistributing space to their column neighbor.
      • Other
        • 1ce6407Fixed Omni mode embed and restore cycle that caused grids to disappear when switching back from Omni view. Moved the exit-Omni check in updateViewVisibility to before the transition block so previousGridMode is read before being overwritten. Made embedding synchronous and fixed viewport detach to use setViewedComponent nullptr so the restore call is not treated as a no-op.
    • Day 349 · 5 commits
      • Effects
        • 29b7be1Plugin Sandboxing: Out-of-process VST plugin hosting with crash recovery
      • UI / UX
        • a3ebc071. Double-click splitter to reset — resets to 50/50, gated by layout lock 2. Middle-click header to collapse — toggles collapse via middle button 3. Header drag handle icon — 2x3 muted dot grid at left edge of header 4. Content dimensions in title — shows '(WxH)' suffix, only updates on change 5. Drag cursor feedback — DraggingHandCursor during drag, reset on mouseUp 6. Persist panel arrangement — enterOmniMode reads panelAssignment, swaps update it 7. Lock layout toggle — padlock button at splitter intersection, gates splitters + drags + double-click reset 8. Right-click header context menu — Swap with submenu, Collapse All Others, Reset Layout (swap/reset disabled when locked) 9. Panel swap animation — 150ms dim-to-full flash on both swapped panels
        • 5e5804aAdded drag-and-drop panel reordering to the Omni Grid view by making OmniGridComponent a DragAndDropContainer, OmniPanelContainer a DragAndDropTarget, and OmniPanelHeader the drag source initiated on mouseDrag after a 5px threshold with a semi-transparent header snapshot as the drag image. Implemented swapPanelContents in OmniGridComponent that detaches content from both panels, re-embeds them in swapped positions, swaps titles, transfers the grid selector ComboBox and its callback between headers, swaps collapse states, and updates embedding manager target records. Added accent-colored highlight overlay on the drop target panel during hover, and added updateTarget to OmniEmbeddingManager so restore-on-exit correctly tracks which panel each component was last embedded in
      • Other
        • 8bfbb90Fix AudioMidiSettingsWindow shutdown crash when settings open on exit
        • 9e16e72Added ASIO Support
    • Day 350 · 13 commits
      • Audio engine
        • 047af05Added window management batch (WIN-501 through WIN-504). Created WindowStateRegistry as a lightweight coordination layer on PluginEditor that tracks all detached/floating windows via register/deregister calls without rewriting existing managers. Implemented cascade, tile, hide-all, show-all arrangement operations with keyboard shortcuts (Ctrl+Alt+C/T/H/S) handled through EditorKeyboardShortcutHandler. Wired registry into MixerUIManager, PluginEditorWindowManager, and BottomBarWindowManager so mixer pop-out, plugin editor, and all seven synthesizer/shader windows are tracked automatically. Added WindowStatePersistence for per-project window state saving through ProcessorState and default layout storage via ApplicationProperties. Created MixerDetachManager wrapping MixerUIManager with multi-monitor display targeting, independent zoom (0.5x-2.0x), and factory/user mixer view presets following the ChannelStripPresetManager pattern. Added EditorWindowFactory with type configurations and created AutomationEditorWindow and SampleEditorWindow following the PianoRollWindow ContentComponent + CustomTitleBarComponent pattern, ready for context menu wiring.
        • 967566eAdded export enhancement batch (EXP-501 through EXP-504). Implemented LUFS-based loudness normalization with EBU R128 measurement via new ExportLoudnessProcessor that performs two-pass analysis using the existing LoudnessMeter, applying gain with true-peak ceiling protection and safety caps. Replaced the single normalize toggle with a three-mode combo (Off/Peak/LUFS) and added platform target quick-sets for Spotify, Apple Music, YouTube, Broadcast, and CD Master with their respective LUFS and true-peak values. Created ExportPresetManager following the ChannelStripPresetManager pattern with seven factory presets and user preset CRUD, persisted through ProcessorState ValueTree serialization. Added multi-format export that renders audio once then writes to additional formats simultaneously via a new writeBufferToFormat dispatch method. Enhanced stem export with configurable naming templates supporting {project}, {track_num}, {track_name}, {date}, and {time} tokens, replacing the previously hardcoded stem filenames.
        • 6e78e37Add unified MIDI FX selector UI to piano roll replacing standalone Arp button. New PianoRollMidiFXSelector provides a single button with left-click CallOutBox chain panel and right-click quick menu for managing all 6 MIDI effects (Arpeggiator, ChordTrigger, ScaleSnap, NoteEcho, VelocityShaper, Randomizer). Each effect has parameter submenus, power toggle, and summary text display. MidiFXChainPopupContent shows the chain with per-effect rows. Ported all existing arpeggiator functionality (Pattern/Rate/Gate/Octave submenus, Print to Notes, Customize dialog). Fixed use-after-free crash when toggling effect power by separating row rebuild from repaint refresh.
        • 96b029dMidiEffects: Implement 5 MIDI effects (Batch C: MIDI-504 through MIDI-508). Added ChordTrigger (chord generation with strum delay), ScaleSnap (scale-constrained note correction via ScaleDefinitions), NoteEcho (tempo-synced MIDI delay with cross-block ring buffer scheduling), VelocityShaper (compress/expand/limit/fix/randomize modes), and Randomizer (pitch/velocity/timing humanization with probability control). All effects use atomic parameters, real-time-safe processing, and ValueTree persistence following the ArpeggiatorProcessor pattern.
        • 3d20d5aMarked PIANO-501 (MIDI Humanize), PIANO-503 (Swing/Shuffle), PIANO-504 (Quantize Strength), PIANO-505 (Note Folding), PIANO-508 (Scale Snap), PIANO-509 (Chord Detection) as completed in features.yaml. Added detected chord label and diatonic button highlighting to ChordStripComponent with MIDI input chord detection in PianoRollViewport. Added velocity ramp draw mode with L key toggle and curve shape preview, curve shape submenu with header badge, and quick velocity preset buttons (pp/p/mp/mf/f/ff) to PianoRollParameterLane. Moved VelocityCurveApplicator::interpolate to public for ramp preview use. Marked PIANO-507 and PIANO-509 as completed.
        • 9b54ca5Moved clip cache rebuilding and audio file I/O inside the condition activation branch so it only runs once when a condition first becomes active instead of every timer tick. Consolidated AudioFormatManager creation to one instance per condition activation instead of per-clip. Protected clip players from being stolen by grid auto-play assignment by checking assignedClipID.isEmpty before treating players as idle. Added assignedClipID.clear on all player release and reassignment paths to prevent stale clip overrides from bleeding into grid cells. Added auto-loop for condition timelines so clips repeat as long as the condition is active rather than playing once and going silent.
        • f7c4d8aEditor Mode: transport stop means full stop, no condition-driven playback when stopped Restricted processConditionClipPlayback to Living Mode only in the audio process path. Editor Mode relies solely on TimelineBlockProcessor via the transport playhead, ensuring stop silences all clips immediately.
        • 22fc1c1Unify condition clip playback across Living and Editor modes with continuous position tracking Renamed processLivingModeTimelinePlayback to processConditionClipPlayback and updateConditionTimelineStates to updateConditionClipStates to reflect mode-agnostic design. Removed Living Mode gates so condition-driven clip playback activates in both modes, with Editor Mode deferring to TimelineBlockProcessor when transport is active to prevent double-driving. Enhanced processConditionClipPlayback with continuous per-block position tracking mirroring TimelineBlockProcessor behavior including normalized position computation, fade-in and fade-out gain calculation using FadeCurves, and proper clip-end detection. Extended CachedClipInfo with durationSec and fade parameters computed from audio file metadata on the message thread. Anti-double-triggering now suppresses grid auto-play for cells with clips in both modes rather than only Living Mode.
        • 99681bdGrid-Timeline Unification: Living Mode plays arranged clips instead of raw cell samples Re-enabled Living Mode clip-driven playback where timeline clips are the playback source when conditions activate. Added anti-double-triggering logic that suppresses grid auto-play for cells with timeline clips, allowing cells without clips to fall back to normal auto-play. Fixed two RT-safety violations in processLivingModeTimelinePlayback by removing the CriticalSection lock and replacing getAllClips allocation with pre-cached clip data populated on the message thread, using the existing lock-free FIFO via controlTimelinePlayer. Created CellClipSyncManager for bidirectional sync between clip overrides and grid cells when a clip is the primary and only clip for its cell. Extended ClipSettingsResolver and ClipTabOverrides with PitchTabData and PlaybackTabData structs for per-clip pitch shift and playback mode overrides. Wired the extended resolver into setupClipForPlayback to apply pitch and playback mode properties to the player pool. Editor Mode behavior is completely untouched.
        • 4ae93dcQuick Punch Mode: toggle recording on/off during playback with per-segment WAV capture
        • d0066faLow Latency Recording Mode: bypass pitch shifter and compressor on armed tracks
      • UI / UX
        • e520cdbAdded AutomationWriteManager that records parameter gestures to automation curves via timer-based sampling at 50Hz on the message thread. Touch mode records while a control is held and inserts a return-to-curve point on release. Latch mode records from first touch and holds the last value until transport stops. Write mode records continuously from play to stop. Trim mode applies relative offset to existing curves preserving their shape. Added configurable fill modes (to start, to end, to punch) that extend recorded values beyond the active region. Integrated gesture detection via AudioProcessorParameter::Listener to automatically capture SliderAttachment touch events. Wired transport state notifications from setEditorPlayStateAtomically into the write manager. Added context menu submenus on automation tracks for mode and fill selection with radio-checked items. Added color-coded write mode badges on automation track headers (R green, T orange, L red, W pink, Tr purple) that pulse brighter during active recording. Stored pre-recording curve snapshots per parameter for future undo support.
        • 78eef02Fixed Editor Mode silence caused by anti-double-triggering suppressing grid auto-play for cells with clips. Restored Living Mode gate on both updateConditionClipStates and the anti-double-triggering check since Editor Mode relies on TimelineBlockProcessor driving the same grid players rather than dedicated clip players. Grid auto-play now works correctly in Editor Mode regardless of whether cells have timeline clips.
    • Day 351 · 11 commits
      • Audio engine
        • c542d95Removed 30Hz debug timer cap and promoted LFO visualizer to Critical priority so the phase ball animates at full 60fps in all builds. Added time-based phase interpolation between audio block updates so the ball glides smoothly along the waveform instead of jumping between discrete positions.
        • 7ff4997Added Morph, Phase Reset, and Tempo Sync controls to LFOControlPanel UI. Extended the panel with three new rows for the Batch J LFO enhancements: a Morph slider showing 0-100% blend between adjacent waveform shapes, a Phase Reset combo box selecting Free Run or On Play reset behavior, and a Tempo Sync toggle with a 24-division sync rate combo box covering normal, dotted, and triplet subdivisions from 4 bars through 1/32. Updated getTotalRequiredHeight from 5 to 8 control rows so the expanded panel renders without clipping, wired all new controls with APVTS attachments and gesture tracking for undo support, and registered tooltips for each new control.
        • f1989c4Added Batch J modulation sources expanding the modulation system with 3 new source types and enhancements to existing sources. Created RandomSHModSource with rate, smoothing, and bipolar parameters for stepped random modulation. Created FollowerModSource as an audio envelope follower with separate attack/release coefficients fed by buffer RMS from processBlock. Created MSEGModSource as a multi-segment envelope generator supporting up to 32 breakpoints with OneShot, Loop, and PingPong modes and ValueTree persistence following the StepSequencerModSource pattern. Enhanced LFO with shape morphing between adjacent waveforms, phase reset on host play start, and tempo sync with 24 beat divisions across normal, dotted, and triplet subdivisions. Added PingPong loop mode to ADSREnvelope that reverses direction at loop boundaries and replaced the hardcoded exponential curve with a selectable curve type parameter supporting Exponential, Linear, Logarithmic, and S-Curve shapes. Added swing and glide parameters to StepSequencerModSource where swing shifts even-step timing for shuffle feel and glide applies a one-pole slew limiter for smooth transitions. Registered all 22 new APVTS parameters in ParameterHelpersEffects, added MSEG/Follower/RandomSH to ModSourceID enum, instantiated all three sources in ModulationSourceManager, added PPQ position caching to PlayheadInfoCache, wired MSEG breakpoint persistence through ProcessorState, and added the three new sources to the modulation routing combo box.
        • 5648ab0Add scrollable viewport to audio settings tab to fix overlapping UI elements. Wrapped all child components in a juce::Viewport with a content component so the recording latency, device information, and audio testing sections no longer overlap when the JUCE AudioDeviceSelectorComponent needs more vertical space than the panel provides.
        • 61c852cAdded MIDI sync batch (SYNC-501 through SYNC-504). Created MidiSyncManager as central coordinator with MidiClockReceiver for PLL-based external clock tempo tracking, MidiTimecodeManager for MTC quarter-frame generation and parsing across four frame rates including drop-frame, MidiMachineControl for SysEx transport command send and receive, and MidiSyncOutputManager as a variable-length lock-free ring buffer for SysEx-capable MIDI output. Integrated into PluginProcessor processBlock with incoming sync extraction before MIDI recording and outgoing sync generation replacing the previous processMidiClockBlock method. Added five APVTS parameters for sync mode, MTC frame rate, and MMC configuration with cached atomic pointers for RT-safe access. Added MIDI Sync UI section to PluginMidiTabComponent with mode selection, frame rate, MMC toggles, and sync output port. Wired ValueTree persistence through ProcessorState for sync settings and output device. Marked SYNC-501 as already complete via existing MidiClockGenerator.
      • Modulation
        • c9e29b4Added moon and environmental conditions chain batch (MOON-501, SEASON-502, DOW-501, SEASON-504, DOW-502, MOON-503). Extended the modulation system with 6 new environmental sources by adding LunarCycle, WorkdayWeekend, CustomDayType, SeasonalTransition, SupermoonProximity, and EclipseProximity to the ModSourceID enum with corresponding EnvironmentalModSource subclasses registered in ModulationSourceManager. Implemented continuous lunar cycle modulation reading the existing ConditionMonitor moon cycle position, bitmask-based workday/weekend detection supporting Western, Middle East, and custom regional patterns, seasonal transition morphing using smoothstep proximity to season boundaries with a configurable 7-28 day window, and supermoon/eclipse detection via new LunarCalculator methods for moon distance, perigee-fullness correlation, and simplified ascending node eclipse geometry. Created CustomDayScheduleManager following the ForecastScheduleManager pattern with day type CRUD, date scheduling, built-in holiday detection, atomic cached value for real-time reads, and ValueTree persistence wired through ProcessorState. Added hemisphere auto-detection from weather service latitude as a third 'Auto (from Location)' option in both SeasonsConfigComponent and MoonPhaseConfigComponent. All 6 sources are recognized as environmental in ModulationEngine for per-slot smoothing and appear in the modulation routing ComboBox.
      • Timeline
        • df51e06Fixed LFO visualizer waveform/ball desync and clipping by unifying all shape drawing through getWaveformValueAtPhase so the drawn line and phase indicator use identical coordinate math in both bipolar and unipolar modes. Increased vertical padding to accommodate the ball glow radius, added a subtle filled area under the waveform, and set the animation timer to 60Hz with a finer phase threshold for smoother motion.
      • Visualizer
        • d055e95LFO Visual upgrade
      • UI / UX
        • 917951bNow the morph slider will visually blend the waveform. At Morph=0 you see the selected shape, at Morph=1 you see the next shape (Sine→Triangle→SawUp→SawDown→Square→Sine), and in between you see the blend — both the drawn waveform line and the ball follow the morphed curve.
        • 5b36e4cUpdated bottom bar button styling to match grid manager button gradient colors and reduced corner radius from 6px to 4px to match punch and new take comboboxes. Moved isBottomBarButton detection earlier in ButtonStyleRenderer to support conditional corner sizing.
        • d8d9837Added configure buttons to Season Samples and Moon Phase Samples grid headers matching the existing Location Grid pattern. Both launch their respective config panels in viewport-wrapped CallOutBox popups on click. Wired the Season button's hemisphere callback to update both TimingModule and SeasonalTransitionSource.
    • Day 352 · 20 commits
      • Audio engine
        • 0d9694cPhase 1b: Made currentAudioState, smoothers, and needsStopAfterFade audio-thread-exclusive. Added forceIdleRequested atomic flag to PoolPlayerInfo that the message thread sets to request immediate Idle transitions, consumed by the audio thread via exchange(false) at the top of each per-player iteration in process(). Replaced direct non-atomic state writes in eight message-thread functions (processTimelineCommands, forceReleaseClipPlayer, pauseChannelPlayback, hardResetAllPlayersInPool, forceReadyStateForPlayback, stopConditionClipPlayback, and updateConditionClipStates deactivation) with atomic flag stores, eliminating data races where the message thread wrote to fields the audio thread reads every block without synchronization. The audio thread's existing state machine already handles all play/stop transitions based on playerShouldBePlaying, making the message thread's previous state writes redundant. Simplified pauseChannelPlayback to only set the programmaticallyPausedByEditor atomic and call player->pause(), relying on the audio thread to detect the flag and transition to FadingOut.
        • efc27f1Both Living Mode and Editor Mode now write clipFadeGain and playerShouldBePlaying directly from the audio thread using cached pool indices, bypassing the FIFO round-trip that added ~12ms of latency. The FIFO still handles position updates and state management. Pool indices are cached in CachedClipInfo (Living Mode) and stamped into the double-buffered ProcessorTimelineItem (Editor Mode) during player assignment on the message thread.
        • aa6bce2Increased timeline command FIFO to 256 and restricted FIFO matching to already-assigned players. Quadrupled the lock-free command queue size to prevent silent drops when multiple conditions are active simultaneously. Removed the assignedClipID.isEmpty() fallback from processTimelineCommands() so the FIFO path only controls players that setupClipForPlayback() has already assigned, eliminating a potential double-claim between the two playback systems.
        • 393321eReset stale player state on clip release and condition deactivation. Added clipFadeGain, hasStartedPlayingThisClip, and audioLoadRequested resets to forceReleaseClipPlayer() to prevent reused players from inheriting stale fade gain or skipping force-to-position-0 logic. Made condition deactivation in updateConditionClipStates() fully clean up player state by adding stopPlayingAndReset(), releaseEffectProcessors(), smoother resets, and the same flag resets, matching the thoroughness of forceReleaseClipPlayer().
        • 1c5038eApplied targeted correctness audits across real-time safety, async lambda lifetime, destructor ordering, and atomic memory ordering. Disabled DEBUG_TIMING_SYNC which was actively causing juce::String heap allocations and Logger::writeToLog file I/O on the audio thread every processBlock call, replaced a per-block dynamic_cast with the existing cachedProcessor_ pointer in TrackChannel::process(), removed a redundant per-block internalMixBuffer.setSize() that was already handled in prepareToPlay(), and changed the TIMING_SYNC_LOG macro from Logger::writeToLog to DBG to prevent file I/O if re-enabled. Applied SafePointer guards to approximately 50 MessageManager::callAsync sites across 21 Component subclasses including TimelineUnifiedOverrideComponent, ForecastSchedulePanel, BottomBarComponent, CollapsibleBottomPanel, PluginEditor, ExportManagerWindow, all three effect settings panels, tab components, and dialog windows, preventing use-after-free crashes when components are destroyed before queued async lambdas execute. Replaced raw this captures with value-captured broadcaster pointers in SamplePlayer and SequencerState callAsync lambdas, and replaced raw this captures with processor pointer captures in RecordingCoordinator to avoid dangling references through destroyed intermediary objects. Reordered GridTimerManager::shutdown() in the PluginEditor destructor to execute before viewport and component clearing rather than after, preventing potential timer callback dispatch on already-destroyed components. Changed four default seq_cst atomic loads to explicit memory_order_relaxed in the SamplePlayer and SequencerBlockProcessor audio hot paths where only simple flag reads were needed, eliminating unnecessary full memory fences on ARM architectures.
        • 9840f2dFixed waveform display rendering over the mixer by temporarily hiding the OpenGL GPU renderer when the mixer opens and restoring it when the mixer closes, preventing the native GL surface from bypassing JUCE's component z-order.
        • 84d7a29Elevated sample settings panel to premium tier with LED readout header strip, machined double-border bezel, accent-underlined tab bar, recessed filter curve visualization with bloom and atmospheric grid, monospace peak readout boxes with color-coded values in General tab, recessed combo box styling, and accent-dotted resize grip.
        • 7a46c41Applied hardware toggle style to all toggle buttons across Filter, Crossfade, Editing, and Time tabs with per-tab accent colors matching each tab's visual identity.
        • 20cc5b9Applied consistent adaptive panel treatment across all remaining sample settings tabs including FilterTab, GeneralTab, EditingTab, and TimeTab with adaptive luminance for dark hours, edge highlighting, and rounded corners matching the Envelope, Crossfade, and Granular tabs.
        • 551fbe6Overhauled granular tab with glass-beam vertical sliders featuring recessed tracks, glowing fills with bloom, glass-bead thumbs with specular highlights, bipolar center-origin fills for Pitch and Pan, ephemeral grain scatter particle effect on hover, cleaned up label typography, and adaptive dark-hour panel background.
        • 9234d40Upgraded crossfade tab visuals with modern card-style GroupComponent rendering replacing legacy line-through-text borders, recessed horizontal slider tracks with drop-shadowed grip-line thumbs, and adaptive dark-hour panel background for CrossfadeTabComponent.
      • Visualizer
        • d6b5439Increased afterglow animation timer from 30fps to 60fps and halved lerp rates to maintain the same decay timing with smoother interpolation.
      • UI / UX
        • 21ec8fbFix day-of-week header font leak from TODAY badge
        • 4785342Fix waveform resize handle z-order above editor toolbar
        • 0895ce1Waveform resize: allow click+drag without shift key
        • c0cc4efTimeline Grid Playhead Ruler now matches time of day
        • b6bd0a0Applied visual polish batch across 45 UI files, replacing flat dark backgrounds with gradient fills, rounded corners, time-of-day accent stripes, and soft borders in 26 dialog classes, 4 option panels, 9 grid config components, 4 resize handles, and 2 piano roll sub-components to establish consistent premium surface treatment throughout secondary UI surfaces.
        • c896bb4Fixed resize grip dots to render via paintOverChildren with bright white contrast and correct bottom-right triangular orientation, and added shadow-backed readable text labels to the filter curve component.
        • b37479dAdded ephemeral atmospheric styling to granular slider hannels with accent-tinted vertical gradients, scattered grain dust particles, and positional radial glow that follows the thumb and intensifies on hover.
        • 7625037Upgraded rotary knob rendering to flagship-tier with 3D angled gradient body, dynamic specular highlight that follows rotation, recessed thumb dimple pointer with accent LED, bipolar arc mode for Pan, reactive hover bloom, and adaptive dark-hour panel styling with edge highlighting and label brightness boosting in EnvelopeTabComponent.
    • Day 353 · 15 commits
      • Audio engine
        • 43e0c32Mark 8 already-implemented features as completed (LFO-501/502/503, ENV-501/502, MOD-504/506/507) and implement CTRL-005/CTRL-006 parameter copy/paste phases 2 and 3. Extended clipboard support to all synth window sliders (FM, Additive, Wavetable, Granular), envelope tab, LFO control panel, and envelope control panel via static helper methods that tag plain juce::Slider components with parameter IDs through component properties. Added group copy/paste with Ctrl+Shift+C/V for semantically related parameter groups (ADSR, mixer channel, EQ band, FM operator) with automatic group detection and cross-group matching by semantic type. Added system clipboard JSON serialization via juce::SystemClipboard for cross-instance parameter paste with validation and magic header verification. Enhanced paste feedback to show before/after values with undo hint.
        • db253b0Fix use-after-free in GridCellAnimator by cancelling animations in destructors and replacing raw pointer captures in Timer::callAfterDelay callbacks with SafePointer. Add session persistence for sample browser filter panel state (duration, channels, sample rate, file type, BPM) so filter settings survive project save/load cycles.
        • 9ed3971Fix DayOfWeek and Tides condition evaluation in areConditionsMet() Add missing case statements so samples assigned to Day of Week and Tides grids are actually filtered during playback instead of silently ignored. Also make the switch exhaustive over all ConditionType enum values.
        • 9c4ee8bAudio Thread Phase 5: Resolved remaining thread safety issues by making currentAudioState a std::atomic so message-thread UI queries like getPlaybackPositionSamples and getCurrentPlayingCondition no longer race with the audio thread's state machine writes. Added cachedGridTypeIndex atomic shadow to PoolPlayerInfo and replaced all five audio-thread reads of getConditionTypeIndex(assignedCondition.type) with atomic loads, eliminating torn-read risk on the 12-byte ConditionIdentifier struct for per-grid metering and gain calculations. Updated all eleven assignedCondition assignment sites to maintain the shadow in sync. Fixed the granular synthesis fallback path in SamplePlayer::processAdding() which allocated a juce::AudioBuffer on the audio thread when the buffer pool was exhausted, replacing it with a pre-allocated granularFallbackBuffer_ member initialized in prepareToPlay(). Made needsStopAfterFade a std::atomic as a defensive measure to enforce its audio-thread-exclusive contract at the type level.
        • ce6d67fPhase 4: Eliminated the FIFO round-trip by moving position management directly into the audio thread, closing the final latency gap where first-play position and state transitions were delayed by 1-2+ audio blocks. Expanded applyDirectTimelineControl() to handle the full playback lifecycle in a single audio-thread-safe call including position setting, first-play detection via hasStartedPlayingThisClip, scrubbing play state, programmatic pause clearing, and visual flags. Added applyScrubSeek() for the editor UI scrub path which directly sets forceIdleRequested, pauses the player, and applies position via SamplePlayer's atomic-safe setPlaybackPosition(), bypassing the FIFO entirely. Updated setTimelineSampleState() in PluginProcessor to resolve pool indices via findPoolIndexForClip() and call the new direct methods instead of routing through controlTimelinePlayer(). Gutted controlTimelinePlayer() and processTimelineCommands() to no-ops since both audio-thread callers (processConditionClipPlayback and TimelineBlockProcessor::processBlock) now use the expanded applyDirectTimelineControl() for zero-latency same-block control.
        • 3630adePhase 3: Eliminated all juce::String operations from the audio thread by introducing hasAssignedClip and cachedMixerTrack atomic fields on PoolPlayerInfo. Replaced assignedClipID.isEmpty() checks in the audio thread's process() with hasAssignedClip atomic reads, and replaced the string-based mixer track lookup in getMixerTrackForPlayer() with a cached atomic int8_t populated during setupClipForPlayback(). Changed the markClipAsFinished chain across TimelineItemManager, PluginProcessor, and TrackChannel to pass an integer pool index through the finished-clips FIFO instead of copying a juce::String, with the message thread resolving the clip ID from the pool index via the new getClipIDForPoolIndex() method. Updated all nine assignedClipID set/clear sites on the message thread to maintain both atomic shadow fields in sync.
        • 79309ecPhase 2: Replaced conditionTimelineStates std::map with RCU-style double-buffered condition snapshot, eliminating undefined behavior where the audio thread iterated the map without lock while the message thread inserted and erased entries. Introduced ConditionClipSnapshot and ConditionSnapshotEntry structs built by the message thread in an inactive buffer and atomically swapped via pointer store, matching the proven TimelineItemManager pattern. Moved per-condition playbackTimeSec tracking into an audio-thread-owned AudioConditionPlayback vector that is rebuilt on snapshot changes while preserving playback positions for surviving conditions. Pre-computed maxEndSec per condition during snapshot construction to avoid redundant iteration in the audio thread's auto-loop check. Updated stopConditionClipPlayback and hardResetAllPlayersInPool to swap in empty snapshots so the audio thread immediately stops iterating stale condition data. Removed the ConditionTimelineState struct and conditionTimelineStates map entirely.
      • UI / UX
        • dec1066Phase 5: Polished TidesEffectGridComponent to match WeatherEffectGridComponent parity with proper effect cell rendering including pulsating active column highlight, hover state backgrounds, FX Chain count labels, and Empty FX placeholders. Upgraded handleCellLeftClick with smart interaction that opens effect chain panels for populated cells and shows Add First Effect menus for empty cells. Replaced basic context menu with full clipboard handler integration supporting copy, paste, paste to all tracks, paste to track all conditions, and paste to all cells operations via GridClipboardHandler. Switched clearEffectChain calls to undoable variants and added proper visual-to-storage index mapping throughout all menu result handlers.
        • dc62ae6Adjusted Tides grid column width to recalculate from parent viewport width when layer toggles change column count, so columns fill available space proportionally like Moon Phase grid does with 8 columns instead of retaining the wider 4-column sizing.
        • 56c91a1Phase 4: Ocean state modulation with live marine API integration, added OceanStateService fetching wave height, swell period, and ocean current from Open-Meteo Marine API on a 30-minute timer with atomic storage and graceful offline fallback. Created OceanModulationSources with four new ModSourceID entries (TidalPosition, WaveHeight, SwellPeriod, OceanCurrent) and concrete ModulationSource subclasses, registered via late-bind setOceanStateService() in ModulationSourceManager. Added Ocean State Modulation toggle to TidesConfigComponent Grid Layers section that enables/disables the service and syncs location from WeatherService. TidesGridComponent now shows per-cell teal modulation indicator bars scaled by live wave height intensity. Wired OceanStateService as member of PluginProcessor with accessor and modulation routing UI names in ModulationRoutingRowComponent dropdown. Fixed GridListComponent shutdown leak by clearing ListBox model in destructor to release GridListItemComponent instances before leak detector fires.
        • 4a78aabFixed Tides config panel viewport height to 1500px so all sections including Grid Layers are scrollable, wired State Resolution combo bidirectionally with Spring/Neap toggle so selecting 8-State doubles grid columns and 4-State restores base layout, synced both controls during load via stateResolution and springNeapEnabled properties, and fixed CrossfadeSettingsComponent missing Tides case that crashed on startup.
        • 248b792Added override parameters for DayOfWeek and Tides grids, Spring/Neap and Slack Water layer toggles in TidesConfigComponent, Config button on Tides grid header with GridManagerWindow auto-selection, and fixed NumGridConditionTypes overflow, toolbar visibility, CrossfadeSettingsComponent missing Tides case, and GridConfigPanel content height.
        • 8ea66aaPhase 1: Tides Grid — Added layered grid prototype with astronomical tide calculation, introducing the first dynamic-column grid to Ephemera. Created TidesGridComponent (4-column base: High/Falling/Low/Rising Tide) with ocean-themed header rendering, TidesColumnMapper for visual-to-storage index translation supporting future Spring/Neap expansion (10 storage slots pre-allocated), and TideCalculator using lunar cycle position plus longitude offset for real-time tide state computation. Wired Tides into the full editor pipeline: ConditionType enum, AllConditionTypes array, SampleDataManager (10 slots), ConditionMonitor (currentTideIndex atomic with spring/neap derivation from moon phase), TrackChannel addRequiredSample, ParameterHelpersInternal per-cell parameter generation, EditorGridSwitcher, EditorViewManager show/hide/repaint, EditorLayoutManager bounds and toolbar visibility, EditorComponentInitializer registration, EditorDragDropHandler, EditorZoomController, EditorToolbarHandler, GridRegistry ActiveView mapping, TopRowButtonManager backend flag, ProcessorState view persistence bounds, AssignToGridComponent cell layout/names, and NumGridConditionTypes bumped from 7 to 8 in both PluginProcessor and GridTrackStateManager to prevent atomic array overflow. Created TidesEffectGridComponent with full effect chain panel management and context menu handling. New files: TidesGridComponent.h/.cpp, TidesEffectGridComponent.h/.cpp, TidesColumnMapper.h/.cpp, TideCalculator.h/.cpp.
      • Other
        • 6ad13c7Remove debug rectangle drawing from release builds Wrap the drawRect outlines around mainContentComponent and timelineRulerComponent in PluginEditor::paint() with #if JUCE_DEBUG guards so they only render in debug builds.
        • b12717eFixed EditorThemeManager Tides case to use correct parameter name for ConditionMonitor reference.
    • Day 354 · 20 commits
      • Audio engine
        • a544643Persistent MIDI Callback: Moved MIDI forwarding from PluginMidiTabComponent to MainWindow so MIDI input stays active after settings window closes. Fixed MIDI learn requiring monitoring toggle. Upgraded mixer to studio console aesthetic with 3D VCA fader caps featuring wedge gradients, grip indentations and LED indicator lines, hardware toggle styling on Mute/Solo/PFL/AFL buttons, beveled channel strip edges for physical module separation, and gold-accented darker master bus differentiation.
        • 5395a90Persistent MIDI Callback: Moved MIDI forwarding from PluginMidiTabComponent to MainWindow so MIDI input stays active after settings window closes. Fixed MIDI learn requiring monitoring toggle.
        • e0b4d81Relocated Filter Cutoff and Master Volume from the prominent controls section into their respective FILTER and MASTER panels, eliminating the confusing duplicate 'KEY CONTROLS' bar. Moved the wavetable selection combo into a slim 30px bar above the visualizer and enlarged the 3D wavetable visualizer from 240px to 370px using the freed space. Updated FlexBox weights for the FILTER panel (4 knobs) and MASTER panel (3 knobs), and removed the prominent controls group from section glow tracking.
        • 80fcd2cAudio/MIDI Settings window now opens at its maximum size (1600x1200) instead of deriving size from the content component, which was too small to show all controls
        • 85ec231MIDI & Audio Input Auto-Detection: Added 2s polling in MainWindow and PluginMidiTabComponent to detect newly connected MIDI/audio devices. When no input is currently selected, new devices are automatically enabled and selected, eliminating the need to manually refresh and choose them in settings.
        • 2269571MIDI Input Device Immediate Callback Registration: Moved MidiInputCallback registration from monitoring toggle to device selection so MIDI events forward to the audio processor as soon as a device is selected, eliminating the need to toggle Enable Monitoring off/on.
        • c452011Granular ADSR and Effects Panel Bottom Padding Fix: Switched both panels from symmetric vertical padding to asymmetric with minimal 4px bottom margin, recovering 24px on ADSR and 18px on Effects for increased fader vertical throw.
        • d0c5108Granular Synth Layout Fix: Replaced old manual margins with standard reduced(8, 28) padding across all panels to match Subtractive pattern. Fixed tiny knobs in Engine and Filter panels caused by excessive margin stacking with layoutKnobGroup overhead. Simplified Engine panel to clean 2x2 knob grid plus pitch/mod section with half-width splits. Moved bypass buttons from top-left (overlapping section titles) to top-right matching Subtractive convention. Fixed invisible ADSR faders by removing 150px minimum height gate and simplifying to equal-width 4-way split. Removed redundant attachToComponent labels on Window/Reverse/Type controls that collided with nearby knobs. Restructured Effects panel to 2-column Delay/Reverb layout with explicit label positioning.
        • 0c265daGranular Synth Living Glass Visual Identity Upgrade: Migrated GranularWindow to EphemeraSynthWindow subclass, eliminating duplicated window chrome code. Rewrote GranularHeaderBar as SynthHeaderBar subclass with animated grain particle cloud glyph. Migrated all five sub-panels to SynthSectionPanel base class, replacing GroupComponent backgrounds with glass-morphism rendering and removing per-panel theming boilerplate. Rewrote GranularSynthComponent as Living Glass orchestrator with 6-zone section hover glows, ambient particles, semantic color zones (engine→wave, filter/envelope→shape, effects→modulation, master→master), animated header parameter pill, and propagateToPanel time-of-day pattern. Preserved slider getters for waveform coupling, FileDragAndDropTarget, sample source section, ParameterClipboardHandler, and MIDI priority routing.
        • 36c9d3fSubtractive Synth DSP Quality Upgrade: Replaced Hal Chamberlin SVF with unconditionally stable TPT SVF filter using control-rate decimation (every 16 samples) to avoid per-sample tan() calls, added NaN/Inf state guards. Added SmoothedValue for filter cutoff (20ms), master volume (50ms), and master pan (50ms) with per-block target setting and per-sample interpolation for zipper-free parameter changes. Moved oscMix read outside the sample loop. Migrated effects (DelayLine, SimpleReverb, WaveshapeDistortion) from per-voice to post-mix on SubtractiveSynthesiser with shared distortion→delay→reverb chain applied after voice summing. Decomposed monolithic SubtractiveSynthComponent into 8 focused sub-panels (HeaderBar, ProminentPanel, OscillatorPanel, FilterPanel, EnvelopePanel, LFOPanel, EffectsPanel, MasterPanel) following the SynthSectionPanel base class pattern. Rewrote SubtractiveSynthComponent as a slim orchestrator with Living Glass background, ambient particles, section hover glows, and semantic time-of-day color zones. Rewrote SubtractiveWindow as a minimal EphemeraSynthWindow subclass. Removed SubtractiveSynthKeyboard references from Additive synth legacy helpers.
        • 5039f69Wavetable Synth DSP Quality Upgrade (ADR-008): Fixed 13 issues from DSP audit with toggleable Enhanced/Standard quality mode. Unconditional fixes: cached parameter pointers behind a flag to eliminate per-block hash lookups, pre-allocated unison voice vector to max capacity to remove audio-thread allocation, replaced if-based phase wrapping with while loops to handle extreme pitch bends, removed double filter cutoff smoothing between voice SmoothedValue and filter one-pole, decimated std::tan() calls to every 16 samples via control-rate counter. Added 4 new APVTS parameters (QualityMode choice, DelayMix, ReverbMix, DistortionMix). Enhanced mode: added getNextSampleStereo() for true stereo unison output using per-voice pan positions, implemented symmetric linear detune spread replacing the asymmetric alternating pattern, removed per-voice hard clip to preserve dynamics for post-mix effects while keeping NaN guard unconditional. Integrated EphemeralDelayProcessor and ReverbScJuceProcessor as stereo post-mix effects for Enhanced mode, wired wet/dr mix parameters to both mono and stereo effect paths. Protected loadWavetables with Synthesiser::lock for thread safety. Created ADR-008 document and updated ADR index. Added 16 Catch2 unit test cases covering parameter caching, pre-allocation safety, phase wrapping, filter decimation and stability, stereo separation, symmetric detune balance, hard-clip behavior, effect mix, signal frequency accuracy, and regression scenarios. Created Python audio analysis script for verifying rendered WAV frequency accuracy, stereo separation, filter response, dynamic range, and effect presence.
        • a979a6fWavetable Synth DSP: Quality upgrade. Fix critical bugs: static filter cutoff shared across voices, pitch/detune overwriting each other, linear unison gain normalization. Wire dead code: filter envelope modulation with key tracking, LFO with pitch/amplitude/filter destinations, morph rate auto-scanning, stereo width mid-side processing. Replace Hal Chamberlin SVF with unconditionally stable TPT SVF filter. Add SmoothedValue for filter cutoff, master volume, and pan. Move effects (delay/reverb/distortion) from per-voice to post-mix on WavetableSynthesiser. Band-limit procedural wavetables with 128-harmonic additive synthesis.
        • 8e9d7edAdd 5 parameter overlay visualizations: filter response, unison ghosts, sub osc undertone, ADSR mini-curve, effects indicators
      • Visualizer
        • 877f2f9FM Synth: Living Glass visual identity upgrade with enlarged controls and orchestrator rewrite
      • UI / UX
        • 8fcbd2bGranular Synth Effects Panel Label Overlap Fix: Replaced attachToComponent slider labels with directly painted parameter names and section sub-titles at fixed Y positions to eliminate overlap between DELAY/REVERB headers and Time/Feedback/Mix/Size/Damping/Mix labels. Removed setupLabels() call and hid unused Label components. Reduced effects panel padding from reduced(8,28) to reduced(4,22) with 26px text reservation for maximum fader vertical throw. Increased default window mainGridHeight from 400 to 480 and max resize height from 900 to 1000 for more vertical space.
        • 9ffa81cSynth Effects Panel Layout Fix: Switched Subtractive, Additive, Granular, and FM effects sections from stacked multi-row knob/fader grids to single horizontal rows, fixing tiny controls caused by halved row heights leaving insufficient space after layoutKnobGroup label overhead. Subtractive effects changed from 3-column 2-row to single row of 5 knobs with Delay/Reverb/Drive dividers. Additive effects changed from 3-row 2-column to single row of 6 knobs with Delay/Reverb/Chorus dividers and added paint() override for section titles. FM modulation panel changed from 3-column stacked layout to single row of 8 knobs with combos in dedicated bottom row and per-section bypass buttons. Granular effects changed from 2-column 3-fader layout to single row of 6 faders with painted section titles replacing explicit Label components that were overlapping slider labels.
        • 2ce534dExtracted shared Ephemera Synth Visual Identity system (SynthPaintHelper, SynthHeaderBar, SynthSectionPanel, EphemeraSynthWindow) from WavetableWindow patterns into reusable foundation. Decomposed Additive Synth monolith into 9 focused sub-panels (Prominent, Harmonics, Envelope, Modulation, Filter, Effects, HarmonicFX, Master, HeaderBar) following the Granular orchestrator pattern. Rewrote AdditiveWindow as a slim orchestrator with inline centerpiece visualizer, Living Glass background, ambient particles, section hover glows, and semantic color zones. Replaced 48-slider harmonic editing with selected-harmonic detail panel and preset buttons. Removed TwoPanelContainer split layout in favor of single 1200px panel matching Wavetable quality. Added DesignTokens::Synth namespace with shared constants for glow, particle, panel, and tooltip styling. Added setFilterState, setSelectedHarmonic, and onHarmonicSelected API to AdditiveHarmonicVisualizer for orchestrator integration.
        • 13d3347Improve 3D visualizer rendering: continuous fill gradation, universal glow halo, rounded strokes, accent-tinted depth grid
      • Other
        • 79cbca3Wavetable: ncreased default window height to 1120px to show all control panels and enabled window resizing with dynamic visualizer scaling.
        • 9b4095fWire morph rate parameter to visualizer for automatic wavetable position scanning
    • Day 355 · 3 commits
      • Audio engine
        • decf6e2UI: Added transient marker overlay system with cyan vertical line markers supporting manual placement via Ctrl+click, drag repositioning, and right-click delete context menus. Implemented warp marker overlay with orange diamond markers that auto-generate from transient positions, supporting horizontal drag-to-warp with ghost markers at original positions, blue/red stretch region tinting proportional to time-stretch amount, and right-click reset menus. Extended WaveformEditorToolbar with Warp tool in the radio group using orange accent highlighting, Transients toggle button with conditional sensitivity slider, and Quantize button with strength slider that appear contextually when their respective features are active. Integrated both overlays into WaveformDisplayComponent with full zoom/pan view range synchronization, editor mode lifecycle management, and automatic warp marker creation from transient data. Updated WaveformInteractionHandler with layered hit testing priority for warp markers, transient markers, and existing trim/loop/fade markers, including hover cursor feedback across all marker types.
        • 92c21caCompleted mixer console polish pass with LED-style recessed track name headers and dB readout labels, hardware toggle styling on all buttons including EQ, FX, Phase, Mono, Lo-Cut, Pad, and Soft Clipper with per-function accent colors, deep black recessed fader grooves replacing the colored gradient, track number badges at the bottom of each strip, and clean accent top-edge hover glow replacing the heavy multi-layer border effect.
        • c2e1bf4Audio/MIDI Settings Window Reorganization: Added scrollable viewport to MIDI panel, consolidated 7 sections into 5 logical groups (merged Devices+Channels into MIDI Input, merged Clock+Sync into Output & Sync), inlined 16 channel buttons horizontally, and tightened layout spacing for better UX within side-by-side layout.
    • Day 356 · 5 commits
      • Audio engine
        • 49b20d8Plugin Parameter Modulation: Implemented modulation system for hosted VST/AU plugins with lock-free double-buffered route storage (PluginParamModState) supporting unlimited routes sorted by instanceId for efficient audio-thread lookup, real-time modulation processor (PluginParamModProcessor) that applies modulation via AudioProcessorParameter::setValue() immediately before each plugin's processBlock with per-route one-pole smoothing and thread-identity-based base value tracking to distinguish user knob changes from modulation writes, scrollable parameter modulation panel (PluginParamModPanel) with categorized source popup menus and bipolar depth sliders shown as a right-side drawer in plugin editor windows toggled by a new MOD button in PluginEditorHeaderBar, full integration into InsertChainProcessor's processSlotRange loop and PluginProcessor's modulation source pipeline with ValueTree state persistence through ProcessorState, automatic route cleanup on plugin removal via EffectsRackComponent, and transport-stop base value restoration so users edit against unmodulated parameter values when playback is stopped.
        • d609a72UI: Added spectrogram rendering overlay with 2048-point FFT, Hann windowing, logarithmic frequency axis, three color maps (Heat/Grayscale/Rainbow), and cached image rendering for the spectral view mode. Implemented spectral editing overlay with rectangle selection featuring eight resize handles, frequency and time range labels, brush indicator circle for heal and clone stamp tools with Alt-click source crosshair. Extended WaveformEditorToolbar with Spectral toggle that switches between waveform mode (Trim/Loop/Fade/Warp) and spectral mode (Select/Heal/Clone) with purple accent highlighting, brush size slider, and color map dropdown. Added three audio repair tool popover panels launched via CallOutBox: noise reduction with learn-then-adjust workflow including threshold and reduction sliders with preview toggle and selection scope radio buttons, click and pop removal with sensitivity-driven detection list featuring per-row accept and reject controls with prev/next navigation and batch operations plus ClickDetectionMarkerOverlay rendering colored state markers on the waveform, and de-clip repair with threshold slider and quality preset dropdown plus ClipHighlightOverlay that analyzes audio buffers for clipped samples and renders red-tinted regions. Integrated all overlays into WaveformDisplayComponent with full zoom and pan view range synchronization, editor mode lifecycle management, and spectral mode interaction handling in WaveformInteractionHandler supporting rectangle selection drag, brush painting, and clone source placement.
      • Timeline
        • e461803Reorganized timeline clip context menus into logical groups with fewer separators
      • UI / UX
        • a4d3117Disabled all view transition animations for clean instant grid switching
        • b0702d1Added chord detection overlay rendering detected chords as confidence-colored labeled blocks at the top of the waveform canvas with hit testing for click correction and right-click context menu supporting delete and split at playhead actions. Implemented groove template browser popover with ten factory presets across MPC swing, live drummer feel, and straight categories, each with a 16-subdivision timing offset visualization grid showing deviation dots connected to the center line, an amount slider for blend control, and save and delete controls for user grooves. Extended WaveformEditorToolbar with Chords toggle and Groove button in the operations section alongside the existing repair tool buttons. Fixed all four popover panels to properly dismiss their parent CallOutBox on both Cancel and Apply button clicks using findParentComponentOfClass.
    • Day 357 · 11 commits
      • Audio engine
        • 3357a5cWire 5 disconnected delay parameters to DSP and extend per-cell UI to full 9-param parity ---- Simplify pitch shifter: remove FIFO layer, fix quality levels and formant normalization
        • 6f4e33dExtended theme unification to cover 13 additional files (TagManager, SampleList, TimelineMarkerManager, TagInput, TimelineButtonBar, DuplicateReview, PianoRollWindow, SmartCollection, UsageVisualization, PerformanceMonitor, PluginParamModPanel, SequencerShiftOptions, RecordingInputAlert) replacing ~47 hardcoded hex colors with DesignTokens theme-aware functions. Migrated 13 more AlertWindow/NativeMessageBox confirmation dialogs to the themed ConfirmationDialogs API across ArrangementContextMenuHandler, ProjectConsolidationDialog, WaveformValidationHelper, GridConfigPanel, GridManagerComponent, EphemeraStandaloneApplication, GridCommand, PianoRollContextMenuHandler, ShortcutCaptureComponent, and TimelineMarkerManagerComponent. Added DialogAnimationHelper utility and applied 180ms fade-in entrance animations to 22 DialogWindow launch sites, 16 standalone window show methods, and the EditorPanelManager settings/audio-MIDI windows. Enhanced EphemeraLookAndFeel drawLabel with subtle hover brightness feedback on interactive labels. ---- Wire 8 disconnected reverb parameters to DSP and improve reverb quality
        • 0469ee6Tests: Added property-based testing framework with 23 randomized invariant tests covering dB/gain conversion, BPMtiming, compression math, mute/solo group state machines, and serialization round-trips using Catch2 GENERATE(), plus mutation testing validation script
      • UI / UX
        • 9c77420Theme unification: Updated ~55+ files to replace hardcoded hex colors with DesignTokens theme-aware functions across effect settings panels, dialogs, windows, and miscellaneous components. Migrated 27 AlertWindow/NativeMessageBox call sites to the themed ConfirmationDialogs API. All effect settings panels (EQ, Chorus, Flanger, Phaser, Tremolo, Distortion, Compressor, Filter, RingMod) now use time-of-day adaptive backgrounds, borders, visualization colors, and text. Dialog and window backgrounds (AssignToGrid, AudioToMidi, BatchConversion, GridManager, PoolManager, SampleEditor, AutomationEditor, GlobalReplace, etc.) shifted from static hex values to getThemeAwareSurface/getThemeAwareColor. Preserved data-encoding colors (filter types, meter levels, automationbadges, chord qualities) and signal indicators (red/green/yellow) as intentionally theme-invariant.
        • edcd607Final visual polish for Copy To dialog: glass stripe, title glow, multi-stop gradient, breathing animations, panel highlights, gradient separators
        • 6bdcf05Fix Copy To dialog toggle switch to use condition monitor time instead of system clock
        • 47dcb6cAdd vibrancy to Copy To dialog: accent glow, tinted body, panel washes, and button highlights
        • 148cb72Removes the JUCE-rendered title bar and uses the component's own Living Glass header as the sole window chrome. Adds a close button (matching CustomTitleBarComponent style) and drag-to-move support on the header area.
        • 7eedcc4Upgrade Copy To dialog with custom LookAndFeel, all 8 condition grids, and two-column track layout
        • 93b10fdReorganize grid context menus and fix tooltip item font/sizing mismatch
        • ba62715Header menus: Reduced separators in track header (removed separator between Color/Icon and Export/Settings) and condition header (same pattern).
    • Day 358 · 2 commits
      • Audio engine
        • 5b88dc5Fixed subtractive synth pitch control by separating frequency multipliers for UI pitch, fine detune, MIDI pitch wheel, and LFO into independent members combined via recalculateFrequency(), preventing fine tune from overwriting pitch. Aligned LFO destination labels to match parameter definition, implemented all four LFO destinations (filter cutoff, amplitude, pitch, pan), widened fine tune range to ±100 cents, and changed section title text to white with subtle theme tint. ---- Wired professional multi-voice stereo chorus DSP processor through all layers (ChorusProcessor with Hermite interpolation, 5 LFO waveforms, 1-8 voices, stereo spread, feedback damping, dual-path pending atomics with SmoothedValues → 15 Cello::Value properties in SampleCellWrapper → 30 SampleDataManager getters/setters → TrackChannel PoolPlayerInfo with lazy init, both process() switches, configurePoolPlayer, and low-latency bypass). Connected ChorusSettingsPanelComponent to SampleDataManager for persistence and added pushChorusParamsToActivePlayers() real-time push path so UI knob changes reach the audio thread within one block via lock-free atomic stores ---- Fixed wavetable synth filter cutoff and master volume knobs being hidden behind their GroupComponents
        • 6ef82c7Clamped wavetable synth polyphonic sum before effects processing to prevent cascading energy accumulation that corrupted system-wide audio via WASAPI shared mode. Added pre-effects hard-clip on synthTempBuffer, reduced per-voice enhanced mode clamp from ±6.0 to ±1.0, added post-stereo-width clamp, bounded delay feedback buffer writes to ±2.0 with NaN guards on filter state, clamped delay and reverb processor outputs to ±1.0, and flushed filter denormals during release tails.
    • Day 359 · 14 commits
      • Audio engine
        • 12d93ebAdd per-cell Bit Crusher effect: DSP processor, storage, routing, and UI wiring Created BitCrusherProcessor with bit-depth quantization, sample-hold rate reduction, jitter randomization, wet/dry mix, and output gain — all using the pending-atomic real-time pattern. Added 7 Cello::Value properties in SampleCellWrapper and 14 getter/setter pairs in SampleDataManager. Wired into TrackChannel with processBlock switch cases, lazy initialization, configurePoolPlayer reads, and pushBitCrusherParamsToActivePlayers. Built BitCrusherSettingsPanelComponent with 5 rotary sliders, enable/bypass toggles, Cello reactive bindings, and an animated waveform visualization showing clean vs crushed signal. Connected to EffectChainPanelComponent with factory, menu item under Lo-Fi / Creative Effects, and name conversion.
        • 753b573Doubled particle morph transition durations for all integration points except major mode switching, and added waveform display change as a seventh transition point using LeftToRight stagger when switching between samples. ---- unlock mixer tracks 9-16 in cell context menu
        • 32594e2Implemented Flanger and Phaser as fully functional per-cell DSP effects, creating FlangerProcessor (single-voice stereo delay with hermite interpolation, signed feedback, and invertPhase) and PhaserProcessor (up to 12 first-order all-pass stages with LFO-modulated center frequency and resonance feedback loop), both following the existing ChorusProcessor pending-atomic real-time pattern. Wired the full data stack for both effects: 29+28 Cello::Value properties in SampleCellWrapper, 60 getter/setter pairs in SampleDataManager, and flangerProcessor/phaserProcessor members in TrackChannel::PoolPlayerInfo with cached bypass atomics, processBlock switch cases, lazy initialization, reset, and pushXxxParamsToActivePlayers methods. Replaced stub listeners in FlangerSettingsPanelComponent and PhaserSettingsPanelComponent with loadSettingsForCell, writeSliderToStorage, and pushLiveParamsToAudioThread, completing the full UI-to-audio-thread parameter path for both effects. ---- Integrated ParticleMorphTransition pixel-dissolve effect into six UI transition points — major mode switching, project load/new project, browser panel collapse, settings panel open, synth window open, and theme switching. Created ParticleMorphCoordinator with click-to-skip, adaptive FPS abort, and GPU renderer management, plus ParticleMorphConfig preset factory with tuned parameters per use case.
        • 532ccbaFix sample cell ADSR timing: envelope stages now complete in exactly the specified time Previously, the RC time-constant coefficient formula caused each stage to take 4.6× longer than the displayed parameter value (e.g. a 100ms attack actually took ~460ms); multiplying the exponent by -ln(0.01) = 4.605 aligns the coefficient with ENVELOPE_THRESHOLD so the stage transitions at exactly the user-specified duration
      • Effects
        • b5c4cdcRing Mod, Tremelo, Delay updates
        • 2000352Redesigned FMOperatorKnob with a spectral plasma aesthetic replacing the generic pill-and-arc look. Replaced the flat pill background with a value-reactive inner plasma well (radial gradient that fills with energy as the parameter increases), swapped the solid value arc for a four-pass chromatic bloom (outer diffuse halo, mid glow, inner warm glow, solid core) whose hue drifts up to 36° as the value sweeps, giving position a colour identity. Added five radial tick marks that proximity-glow near the current value, an orbit dot pointer with a trailing comet tail that extends during drag, and a complementary-hue harmonic ring for Level and Ratio knobs representing FM sideband energy. Operator badge redesigned with a coloured fill, vivid rim, and soft outer glow halo. computeOperatorColor now enforces a saturation floor of 0.45 and a brightness floor of 0.50 so each operator reads as distinctly coloured in dark themes. Fixed orbit dot coordinate convention: corrected cos/sin to sin/-cos to match JUCE's addCentredArc 12 o'clock clockwise angle system, placing the dot accurately at the arc endpoint.
      • UI / UX
        • 104b91aAdded BitCrusher to the 'Add Effect' right-click submenu across all six condition grid components (Time of Day, Weather, Season, Location, Moon Phase, Tides) with corresponding switch cases for effect assignment. Fixed 'Unknown'
        • d543631Per-cell Delay panel: add scrollable viewport for visualizations
        • a576f5aAdded Tremolo per-cell effect: DSP processor, storage, routing, and UI wiring ---- Wired RingMod DSP: processor, data storage, TrackChannel integration, settings panel I/O
        • e413f07Reverted rotated-block overlay back to paint() after discovering juce::Graphics on an image always uses the software renderer, causing a visible stall at peak rotation.
        • 2cc0b6fReplaced std::pow in easeOutBack with manual polynomial multiplication, substituted a 256-entry sin LUT for the wobble trig calls and a parabola for the z-arc, cached blended colour bytes in updateBlocks to eliminate float math from the render loop, fixed memcpy to use lineStride, moved the rotated-block overlay into renderBlocksToBuffer so paint() is a single drawImageAt blit, switched dt to high-resolution ticks, and cached panel images in the test harness to eliminate per-frame heap allocation.
        • 432ff60Increased bypass button size in FMModulationPanel from 28×16 to 38×22px and reduced combo box height from 24px to 18px, recovering vertical space for the knob row. Grew the FM synth window default width from 1400 to 1500px, expanded operator panel rows from 260 to 290px each, the prominent panel from 140 to 155px, and the modulation panel budget from 200 to 220px, updating resize limits and calculateOptimalHeight to match.
        • 9e4dc2fMade FMOperatorPanel knob layout fully proportional to available panel height, replacing hardcoded pixel sizes (68/56/52px) with sizes computed from the vertical budget split across two rows. Reduced side padding from 6px to 3px, switched to equal-width cells so labels span their full cell rather than just the knob width, and stored the envelope label Y position dynamically in resized() so it tracks correctly at any panel size.
        • 1b12496Fixed parameter wiring across all synth engines: aligned FM LFO destination combo and enum to match parameter definition order, implemented previously non-functional FM LFO processing for all six destinations in renderNextBlock, and widened FM fine tune range to ±100 cents. Aligned Additive LFO destination parameter choices to match UI and engine enum, implemented HarmonicFrequency and GlobalAmplitude LFO destinations in DSP. Added Notch filter type to Granular synth filter enum and processSample switch with corrected jlimit bounds. ---- Added ParticleMorphTransition pixel-dissolve effect with standalone test harness, accessible via Dev Tools menu. Implemented grid-aligned block animation with pseudo-3D depth (sinusoidal Z arc, per-block rotation, radial stagger wave, turbulence wobble, depth-sorted rendering with grounded drop shadows, and elastic landing overshoot). Integrated FPS performance counter that logs resolution, block count, avg/min/max FPS, and frame timing per transition run with Ctrl+C clipboard export for benchmarking across window sizes.
    • Day 360 · 16 commits
      • Audio engine
        • ecd27abWire track-level stock effect processing into the mixer signal chain. Created TrackStockEffectChain class that owns per-track lazy-initialized effect processors and processes them after EQ/pad but before VST3 pre-fader inserts in MixerTrackManager. Added ConditionType::Track branches to all 15 settings panel pushLiveParamsToAudioThread methods so parameter changes from the mixer rack UI route to track-level processors instead of per-cell players. Hooked the EffectsRackComponent timer-based sync to update the audio-thread effect chain when assignments change, and wired state save/load through ProcessorState for compressor parameter persistence
        • fad0770Wired broken per-cell effect parameters across compressor, filter, flanger, delay, and pitch shift ---- Added search syntax help button to sample browser and contextual idle tips to InfoChironComponent. The '?' button next to the search bar shows a cheat sheet for tag:, key:, bpm:, and combined query filters. The scrolling info bar now appends rotating tips every 15 seconds with general usage hints and view-specific guidance that updates when switching grids.
        • ac619b8Improved ParticleMorphTransition performance and robustness. Replaced byte-by-byte pixel stamping with packed uint32_t fills via std::fill_n, optimized source buffer copying with single memcpy when line strides match, and switched from raw pixel pointer reads over getPixelColour in block building. Replaced juce::Timer at fixed 120Hz with juce::VBlankAttachment for vsync-locked frame pacing. Added re-entrancy and zero-size guards to start(), a pixel stride assertion for format safety, and a frameTimes cap to prevent unbounded growth. Smoothed rotation speed ramping to eliminate visual discontinuity at the rotated/non-rotated render threshold. Extracted duplicated stats finalization into a shared finalizeStats() method.
        • 1ed4265Mixer:add solo dim: non-soloed tracks attenuate instead of hard mute
        • 2cf700bThemed the Add Effect context menu in EffectChainPanelComponent to match the app's existing styled context menus by applying ThemedPopupMenuLookAndFeel with time-of-day gradient backgrounds, accent stripes, and highlighted hover states. Reorganized effect menu items into logical category sections (Time/Space, Modulation, Dynamics, Frequency, Distortion/Lo-Fi, Stereo/Imaging, Pitch) with styled section headers. Removed stale placeholder flags and duplicate separators.
        • 01f141aImplemented Mid-Side Processing and Transient Designer as per-cell DSP effects. Mid-Side provides M/S encode/decode with independent mid/side gain controls, width adjustment, and solo modes for mastering and stereo manipulation. Transient Designer uses dual envelope followers (fast/slow) to detect and independently shape attack transients and sustain portions with sensitivity threshold and dry/wet mix. Wired the full data stack for both: 14 Cello::Value properties, 28 SampleDataManager accessors, TrackChannel integration with lazy init and real-time parameter push. Created settings panel UIs with Cello reactive bindings and ComboBox selectors. Added both to all 7 effect grid menus.
        • 1d886b9Stereo Imager: Implemented Stereo Imager as a per-cell DSP effect with M/S encoding, 2-band crossover, per-band width control, and mono bass option. Wired the full data stack: 7 Cello::Value properties, 14 SampleDataManager accessors, TrackChannel integration with lazy init and real-time parameter push. Created settings panel UI with Cello reactive bindings. Added to all 7 effect grid menus. De-Esser: Implemented De-Esser as a per-cell DSP effect with bandpass sidechain detection, envelope follower, and wideband/split-band gain reduction modes. Wired the full data stack: 9 Cello::Value properties, 18 SampleDataManager accessors, TrackChannel integration with lazy init and real-time parameter push. Created settings panel UI with Cello reactive bindings and ComboBox mode selector. Added to all 7 effect grid menus.
        • b1daaefImplemented Distortion as a fully functional per-cell DSP effect with 8 algorithms, 3-band biquad tone EQ, and optional 2x oversampling. Wired the full data stack: 12 Cello::Value properties, 24 SampleDataManager accessors, TrackChannel integration with lazy init and real-time parameter push. Connected settings panel UI to storage and audio thread. Fixed panel layout spacing and removed placeholder menu labels.
        • 1d32e9aCreated PerCellEQProcessor with 3 cascaded biquad peak filters using the Audio EQ Cookbook formula for zero-allocation coefficient calculation, the pending-atomic real-time pattern, dirty-flag gated recalculation, and SmoothedValue output gain. Wired the full data stack: 12 Cello::Value properties in SampleCellWrapper, 24 getter/setter pairs in SampleDataManager, and eqProcessor member in TrackChannel::PoolPlayerInfo with cached bypass atomic, processBlock switch cases, lazy initialization, reset, and pushEQParamsToActivePlayers. Replaced stub listeners in EQSettingsPanelComponent with loadSettingsForCell, writeSliderToStorage, and pushLiveParamsToAudioThread, completing the full UI-to-audio-thread parameter path. Updated EQ menu labels across all effect grid components. Fixed DistortionProcessor AudioBlock constructor for JUCE 8 compatibility.
        • 18f3e26Created PerCellEQProcessor with 3 cascaded biquad peak filters using the pending-atomic real-time pattern, JUCE IIR coefficient calculation with dirty-flag optimization, and SmoothedValue output gain. Wired the full data stack: 12 Cello::Value properties in SampleCellWrapper, 24 getter/setter pairs in SampleDataManager, and eqProcessor member in TrackChannel::PoolPlayerInfo with cached bypass atomic, processBlock switch cases, lazy initialization, reset, and pushEQParamsToActivePlayers. Replaced stub listeners in EQSettingsPanelComponent with loadSettingsForCell, writeSliderToStorage, and pushLiveParamsToAudioThread, completing the full UI-to-audio-thread parameter path. Updated EQ menu labels across all effect grid components.
      • Effects
        • 8cb8b87Per Cell Distortion: Restored controls
        • 3db89a5Per Cell EQ: Fixed popping/click
      • UI / UX
        • 7773248Removed redundant separators from Add Effect menu to fix double-spacing between section header categories.
        • 64bff68Implemented Noise Gate as a per-cell DSP effect with envelope follower, hysteresis, and internal sidechain HPF/LPF filtering. Wired the full data stack: 11 Cello::Value properties, 22 SampleDataManager accessors, TrackChannel integration with lazy init and real-time parameter push. Created settings panel UI with Cello reactive bindings, rotary knob layout, and GR meter display. Added to all 7 effect grid menus
        • 4e662f0Fixed Distortion settings panel layout: added scrollable viewport so all controls are accessible, reorganized into 3 rows (Drive, Tone+Character, Mix+Global), increased group heights to 170px with 65px top insets so group titles and control labels no longer overlap, and hidden level meter display to reclaim space for controls.
      • Other
        • fa0b946Wire VCA groups for non-frozen tracks and implement pre/post fader aux sends
    • Day 361 · 20 commits
      • Audio engine
        • 42278c6Increased limiter GR label to 11pt with orange active color, added IBeam cursor and hover underline to track name labels, tinted preset combo box borders with time-of-day accent, colored fader dB readouts green amber and red based on level for gain staging feedback, added themed active indicator dots on EQ and Effects buttons with new EqCurveThumbnail isActive method, drew 3px time-of-day accent line on selected strip left edge, and implemented 30-second smooth cross-fade for theme color transitions via targetThemeColor interpolation at 0.3 percent per frame.
        • b72cd5cRemoved master strip gold border and added time-of-day visual enhancements across the mixer including left-to-right gradient on track name headers, signal-level fader glow halo, correlation bar color blending toward time-of-day accent, mute and solo button color temperature shifting, EQ curve thumbnail outline glow when bands are active, and enhanced ambient light bleed with higher alpha ceiling, dynamic width, and full-strip tint overlay on loud channels
        • 8a60dfeMixer: Tooltips finishing
        • 4ccfed6Added dynamic per-dot tooltips to aux send activity indicators showing send number, activity status, and routing hint. Added generic SettableTooltipClient fallback to TooltipManager dynamic tooltip path so any component with setTooltip can display in the mixer header
        • c2e05adIncreased mixer header to 80px and tooltip font to 16pt, removed MixerLookAndFeel override from tooltip label so the font size set via setFont is respected instead of being overridden by EphemeraLookAndFeel::getLabelFont.
        • 2f5c11eAdded multi-level tooltip verbosity system with 5 detail levels from minimal parameter names to full production tips and music theory. Extended TooltipManager with registerComponentMultiLevel storing per-component tooltip arrays selected at display time from the global DesignTokens tooltipVerbosity setting. Registered all 18 mixer channel strip controls with 5 verbosity levels each covering volume, pan, width, mute, solo, PFL, AFL, EQ, effects, input gain, delay comp, phase invert, mono sum, low cut, pad, and soft clipper. Added tooltip verbosity slider to the Typography settings tab with level names and descriptions persisted across sessions. Moved the mixer header tooltip label to the left side taking two-thirds of the header width for better readability.
        • e6caa1bMoved StereoCorrelationBarComponent from below the master strip into the mixer header by increasing header height from 40 to 60 pixels. Relocated limiter enable toggle and gain reduction label from inside MixerChannelStrip to a dedicated 22px area below the master strip managed by MixerPanel, restoring track alignment across the mixer
        • 69d385dAdded MasterLimiterProcessor with true-peak brick-wall limiting, 1ms lookahead, instant attack, configurable release, and ceiling control integrated into MixerEngine after the master compressor with latency reported for PDC. Added master-only LIM toggle button to MixerChannelStrip below the soft clipper controls with orange glow indicator during active gain reduction polled from MixerPanel timer callback.
        • 2bc7057Added MasterLimiterProcessor as a true-peak brick-wall limiter with 1ms lookahead, instant attack, configurable release, and ceiling control for the master output stage. Integrated into MixerEngine after themaster compressor and before the pitch shifter with latency reported for host PDC. Added limiter section to OutputMeterComponent with LIM enable toggle, rotary ceiling knob, and gain reduction meter bar that shifts from dark navy to warm amber during active limiting with traffic-light color coding for GR severity
        • cb917a1Added gain reduction metering to NoiseGate, DeEsser, and TransientDesigner settings panels reading from TrackStockEffectChain via new metering getters. Added gainModifierDb atomic to TransientDesignerProcessor published per-block for UI visualization. Added gate state indicator with open/closed dot and threshold/hysteresis band overlay to NoiseGate panel. Updated Distortion waveshaping curve display to use DistortionProcessor::computeTransferFunction for accurate rendering with 1:1 reference line. Added all missing effects to the mixer effects rack menu including Noise Gate, De-Esser, Transient Designer, Bit Crusher, Filter, Stereo Imager, and Mid/Side with corresponding handler cases and display names.
        • 4974d2bUpgraded PerCellEQProcessor with widened Q range from 0.3-3.0 to 0.1-10.0, per-band filter type selection supporting Peak, Low Shelf, and High Shelf via Audio EQ Cookbook formulas, and per-band enable/disable toggles with cached array for zero-overhead skipping. Replaced StereoImagerProcessor one-pole crossover with true Linkwitz-Riley 4th-order using two cascaded Butterworth biquads. Added stereo correlation meter output to both StereoImagerProcessor and MidSideProcessor computed per-block from output samples
        • 1b08b8bAdded tempo sync, Lagrange3rd interpolation, and 5-second max delay to EphemeralDelayProcessor. Added freeze mode, 30-second max decay, stereo early reflections with offset L/R tap positions, and wet signal high-pass filter to ReverbScJuceProcessor. Added LFO waveform selection for frequency modulation in RingModProcessor via ModulationHelpers. Added optional wet signal high-pass filter to ChorusProcessor. Added dry/wet mix and output gain parameters to SignalsmithPitchShifter with optimized fast path for fully wet unity gain
      • Modulation
        • f058324Applied EphemeraLookAndFeel to the 9 effect settings panels that were missing it so all controls render with time-of-day themed colors consistently across NoiseGate, DeEsser, BitCrusher, StereoImager, MidSide, TransientDesigner, PitchShift, Delay, and Reverb.
      • Timeline
        • b9b856eAdded per-dot hover states to aux send activity indicators with bright colored fill, glow halo, and thicker border on hover using per-dot hit testing and pointing hand cursor.
      • Effects
        • a32f52dAdded sidechain high-pass filter and RMS detection mode to CompressorProcessor for reduced low-frequency pumping and smoother musical compression. Improved DeEsserProcessor with soft-knee compression via CompressionMathHelpers, user-controllable ratio parameter, and SC Listen mode with independent filter state. Exposed attack and sustain release time parameters in TransientDesignerProcessor replacing hardcoded 50ms and 200ms values. Added DC blocker after Distortion tone EQ in both oversampled and non-oversampled paths to remove bias from asymmetric waveshaping. Applied tanh soft saturation to Phaser resonance feedback and Flanger feedback paths to prevent self-oscillation at extreme settings
      • UI / UX
        • 97c76c5Added hover states to unticked hardware toggle buttons with fill highlight and border glow, increased generic toggle hover visibility, widened rotary knob hover glow halo to 1.4x radius with 50% more intense bloom layers, and changed rotary slider cursor to pointing hand on hover with dragging hand during drag
        • 59da7d8Set tooltip label minimumHorizontalScale to 1.0 so long tooltips wrap to multiple lines instead of shrinking the font to fit on one line
        • c37c22aFixed EphemeraLookAndFeel drawLabel to respect a label's own font when explicitly set via setFont instead of always overriding with the design token label font.
        • 34569a4Header is now 80px (was 60): 20px for correlation bar, 60px for the tooltip/title area (was 40px). Font bumped from 12pt to 14pt. The extra vertical space also helps when higher verbosity levels produce longer text — the label has more room to breathe
        • fe41e6cWired FilterProcessor DSP to FilterSettingsPanelComponent by building complete FilterParameters from all UI controls and routing to TrackStockEffectChain for track-level processing. Implemented FET compressor algorithm with 2x faster attack, program-dependent ratio that increases with input level, and subtle tanh harmonic saturation. Implemented Optical compressor algorithm with two-stage program-dependent release blending fast initial decay to slow tail and doubled knee width for smoother onset. Re-added FET and Optical to the algorithm ComboBox and updated enum mapping across settings panel, ProcessorState, and TrackChannel.
    • Day 362 · 20 commits
      • Audio engine
        • 55fec58Modulation response curves: per-slot curve shaping for condition-to-parameter mapping. ---- Added weather metric mini-grid infrastructure with Temperature, Humidity, and Air Pressure grids displayed as three equal-width panels above the main weather grid in the Weather view. Created MetricRange data model with unit conversion utilities, MetricRangeManager with default named ranges (Extreme Cold through Extreme Heat, Arid through Oppressive, Very Low through Extreme High), and BaseMetricGridComponent inheriting BaseGridComponent with dynamic track count support (1-16 tracks, defaulting to 4) including an add-track button row and inline header editing. Added Temperature, Humidity, and AirPressure to ConditionType enum with sample storage allocation, refactored BaseGridComponent and 9 handler classes to use virtual getActiveTrackCount() instead of hardcoded NumTracks for dynamic grid sizing, and integrated WeatherMetricPanelComponent into PluginEditor layout with independent viewport scrolling per grid
        • 9d00162Move envelope updates outside channel loop to fix 2x speed on stereo output. Replace mono filter with independent L/R filter instances for correct stereo processing. Allow negative pitch increments with backward wrapping to fix broken reverse grain direction. Cache fully-modulated cutoff so filter envelope no longer overrides velocity, key tracking, mod wheel, and aftertouch modulation. Unify all pitch sources into single accumulation to fix dead mod wheel and aftertouch pitch routing. Pre-allocate temp buffer in prepareToPlay to eliminate heap allocation on audio thread. Add SpinLock with tryEnter around source buffer swap to prevent crash during sample loading. Expand pitch increment clamp from 0.1-4.0 to 0.0625-16.0 for full ±48 semitone range. Check effective tempo-synced rate instead of free rate so synced LFOs work when rate slider is zero. Capture release start level so envelope decays proportionally from current level in exactly releaseTime. Rename struct Grain to SampleGrain in Grain.h to eliminate duplicate class name with GranularSynthEngine. Replace hard clip with tanh soft clip on filter output for smoother high-resonance behavior. Include pitch shift parameter offset in startNote to fix first-block pitch pop.
        • ae12a57Granular synth: LFO tempo sync UI, filter key tracking, and mod wheel plus aftertouch routing
        • 4a04687Granular synth: extended ranges to 1000ms and ±48st, grain direction modes, and LFO tempo sync
        • a8af17fGranular synth: independent time-stretch with decoupled playback speed and pitch control
        • b4e9d1dGranular synth: per-grain pitch jitter, expanded effects panel UI, and position auto-sweep LFO
        • 51891e0Granular synth: grain cloud scatter-plot visualizer and interactive ADSR envelope editor
      • Modulation
        • 7ab9d85Granular synth: grain size and rate LFO modulation with shared modulation source
      • Timeline
        • 572c73eGranular synth: waveform zoom and scroll with mouse wheel and viewport-aware rendering
      • Effects
        • e4790c2Granular synth: 3 independent LFOs with shape and destination routing, and dedicated filter envelope
        • 676071dGranular synth: grain density envelope, velocity-to-rate and filter mapping, and micro-looping down to 1ms
        • f5a8b40Granular synth: per-grain filter cutoff spread with spectral variation and enlarged window
        • 8696f1dGranular synth: replaced per-voice delay and reverb with stereo EphemeralDelay and FDN ReverbSc processors
      • UI / UX
        • a77b7e3Granular modulation panel: side-by-side filter envelope and performance controls layout
        • 6555034Granular modulation panel: fixed LFO layout overflow and added mod wheel, aftertouch, and key track UI controls
        • ae4daccGranular modulation panel layout fix for overlapping controls
        • 9466650Granular synth: modulation panel with 3 routable LFOs, filter envelope, and engine panel cleanup
        • 1c40a3cGranular synth: waveform loop regions, position spray overlay, and rising grain particles
        • 3dad411Shared SynthSectionPanel bypass dimming overlay with granular filter and effects panel integration
      • Other
        • b54adc9Granular synth: stochastic grain scheduling with adjustable jitter
    • Day 363 · 6 commits
      • Audio engine
        • 97e5505FM Synth: fix operator bypass defaults (all enabled), musically voiced init patch, align card ranges to APVTS ---- Fix pitch wheel overwriting accumulated pitch sources, reverse grain wrap for extreme pitch, unprepared voices from setNumVoices, and interpolation index mutation at boundaries. Remove unused GranularDelay/GranularReverb classes. Apply constant-power master pan law and accurate per-grain viz pitch. Refactor per-sample grain rendering to sub-block architecture with O(1) LFO batch advancement for ~500-1600x fewer function calls per audio block ---- Additive synth: performance overhaul and post-mix effects architecture
        • 39c3943Added live weather data integration for metric mini-grids by expanding WeatherService to fetch relative humidity and barometric pressure from the Open-Meteo API alongside existing temperature and wind speed data. Moved MetricRangeManagers from the UI panel into PluginProcessor so both the audio engine and editor share the same range data, and wired ConditionMonitor to map live temperature, humidity, and pressure values to range column indices updated each condition cycle. Integrated metric grid sample triggering into TrackChannel::updateConditionClipStates so Temperature, Humidity, and AirPressure conditions fire additively alongside the existing weather state grid. Added MetricGridState persistence to ProcessorState saving and restoring custom ranges, track counts, and unit preferences across sessions with track count atomics synced between the grid UI and processor
        • 075e1beAdded full-width weather metric panel layout by moving the Temperature, Humidity, and Air Pressure mini-grid positioning to occur before the track control strip takes its left-side space, ensuring the metric panel spans the entire editor width while the track controls and master volume remain in sync with the main weather grid below
      • UI / UX
        • 7cb736dFM Synth: in-window tooltip system with 5-level verbosity, header layout with buttons flush-right and pill after title
      • Other
        • d0c538fGranular synth: fix progressive clipping buildup on sustained notes ---- All synths: 5-level in-window tooltips for Subtractive, Additive, and Granular panels with educational progressive verbosity
        • 3e1a3eaAll synths: 5-level in-window tooltips for Subtractive, Additive, and Granular panels with educational progressive verbosity
    • Day 364 · 18 commits
      • Audio engine
        • cb9b1fbImproved wavetable synth window particle morph animation: reduced duration from 1200ms to 650ms with proportionally lighter turbulence and lift for a snappier feel, added a smoothstep crossfade of the destination image during the last 20% of the animation so particles settle onto an already-visible final image instead of snapping, and eliminated the background flash on open by setting content alpha to zero before the deferred snapshot frame and restoring it only when the particle overlay is in place
        • 5e29dceFixed reverb damping chaos caused by setDampingRealTime triggering recomputeDerivedParameters every audio block, which overwrote feedback with a fixed decay-derived value and forced default modDepth 0.5 (pitch wobble) and diffusion 0.7. Switched to legacy mode by setting decayTime to 0 and modDepth to 0 once during prepareToPlay, then using direct setFeedbackRealTime and setLpFreqRealTime with the correct exponential dampingToLpFreq mapping in updateParameters. This gives the wavetable synth direct control over reverb feedback and LP frequency without per-block derived parameter recomputation
        • 863823fReplaced 133 hardcoded Colour(0x...) values with DesignTokens equivalents across 29 Tier 3 files covering sample management panels (SampleBrowserMetadata, PoolManager, SampleList, SmartCollection), nine grid config components (Weather, MoonPhase, TimeOfDay, Location, DayOfWeek, Seasons, Tides, Halloween, Christmas), seven bus and aux routing components (BusSlider, BusWindow, AuxSendRouting, AuxReturn, AuxWindow, Sidechain, RoutingMatrix), and nine miscellaneous panels and dialogs (ForecastSchedule, CrossfadeEditor, ProjectConsolidation, MissingSampleRelink, MidSideControl, MultibandEditor, PianoRollParameterLane, ColorPickerPopup, SampleGeneralTab). Unified panel background gradients to DarkTheme surface tokens, text hierarchy to getTextPrimary and getTextSecondary, interactive elements to button tokens, and state indicators to semantic success, warning, error, and info tokens. Preserved environmental theme identity colors, bus index palettes, preset color swatches, per-band frequency colors, and CC lane velocity colors as intentionally theme-independent
        • 9ead617Replaced 121 hardcoded Colour(0x...) values with DesignTokens equivalents across 12 Tier 2 files covering effect settings panels (GlobalEffects, Filter, Distortion, Compressor, NoiseGate, BitCrusher, ClickRemoval), timeline components (TimelineGridPainter, TimelineActiveSourcesColumn, ChordTrackComponent), and mixer channel strips. Standardized recurring meter state colors to semantic success/warning/error tokens, panel backgrounds to DarkTheme surface tokens, info indicators to the semantic info token, and text elements to the text hierarchy. Preserved identity colors for filter types, distortion algorithms, chord qualities, and track group presets as intentionally theme-independent
        • 43ef112Diagnosed via the automated audio test pipeline that the wavetable synth's Enhanced mode unison stereo spread produced near-mono output (L/R correlation 0.999) despite correct phase staggering and pan positions. Traced the root cause to the single WavetableFilter instance processing both L and R channels sequentially, where the filter's state variables from processing L dominated the R output and destroyed the stereo image. Added an independent filterR instance for the right channel in Enhanced mode so both channels maintain separate filter state. Replaced the asymmetric linear pan law in getNextSampleStereo where center position gave the left channel double the gain of right with a constant-power cos/sin pan law for perceptually correct stereo distribution. Changed unison voice initial phase assignment from all-zero to golden ratio spacing for maximum inter-voice decorrelation, eliminating the delay before stereo separation emerges. Implemented four new wavetable types (Vocal with formant resonances, Organic with breathy inharmonic partials, Spectral with metallic stretched partials, and Evolving with spectral sweep and wavefold) completing the eight APVTS parameter choices, and exposed all eight in the WavetableWindow combo box. Improved the Python analyzer delay detection to use envelope-based autocorrelation and added _comment filtering to the validator. Expanded the comprehensive test specification from 43 to 65 tests covering fine tune, all five LFO destinations, stereo width, master pan, individual bypass toggles, wavetable envelope modulation, filter key tracking, and auto morph rate
        • 4c865edUpdated mixer header button layout to fill the full header row height at 32px wide matching the main window title bar controls, and fixed the header gradient painting to use the full header bounds before button removal so the time-of-day color extends behind the buttons instead of showing a dark gap
        • cfeeb19Styled mixer header buttons (X, ->, POP, RTN) to match the main window's CustomTitleBarComponent WindowControlButton appearance by adding a 'mixerHeaderButton' property flag and routing through ButtonStyleRenderer. Replaced the metallic gradient and frosted glass border styling with flat, transparent-idle buttons that show a subtle surface highlight on hover and red highlight for the close button, consistent with the title bar controls. Added delegation in MixerLookAndFeel to forward tagged buttons to EphemeraLookAndFeel so the styling works both when docked and when popped out into MixerWindow.
        • 30ee1efContext menu theming: apply ThemedPopupMenuLookAndFeel to 30 files with unthemed right-click menus Adds time-of-day themed styling to all remaining PopupMenu show calls across piano roll lanes, automation editors, grid components, timeline controls, mixer strips, sample browser, routing matrix, and synth preset menus that were still using default JUCE appearance
        • c5681e0Added four new wavetable generation algorithms to WavetableGenerator.h for Vocal (formant resonances), Organic (breathy inharmonic partials), Spectral (metallic stretched partials), and Evolving (spectral sweep with wavefold), and exposed all eight types in the WavetableWindow combo box. Improved the Python analyzer's delay detection to use envelope-based autocorrelation instead of raw signal correlation which was confused by periodic sustained tones. Added _comment filtering to the Python validator matching the C++ runner's skip logic. Expanded the comprehensive wavetable test spec from 43 to 65 tests adding fine tune verification with expected frequency assertions, all five LFO destinations (pitch vibrato, filter sweep, amplitude tremolo, wavetable position morphing, unison detune modulation), stereo width from mono collapse to extra wide, master pan hard left and right, individual bypass toggles for amp envelope and filter envelope and LFO, wavetable envelope position modulation, filter key tracking comparison between off and full tracking, auto morph rate scanning, and all four new wavetable types. Corrected the high-pass filter test to use harmonically rich Analog wavetable source instead of pure sine which was correctly attenuated to silence, and updated unison stereo tests to use Enhanced quality mode with Analog source for stereo content generation
        • 61d58f1Fixed parameter application in headless AudioTestRunner by adding a resolveParamId lookup table that maps C++ constant names used in JSON test specs to their actual APVTS string values, resolving a silent failure where all synth parameters were being ignored. Extracted wavetable generation from WavetableSynthComponent into a shared WavetableGenerator.h header-only utility so the AudioTestRunner can generate and load wavetable data without the UI, which was the root cause of the synth producing only default sine output in headless mode. Refactored WavetableWindow.cpp to delegate to WavetableGenerator::generate() instead of its inline implementation. Switched test execution from reusing a single processor to creating a fresh TimeSamplerAudioProcessor per test to prevent internal DSP state leakage between tests, and added _comment entry filtering to the JSON parser. Created a 43-test comprehensive wavetable specification covering pitch accuracy across octaves with transpose verification, all four implemented wavetable types with spectral differentiation, morph position variation, all four filter types with cutoff and bypass verification, ADSR envelope timing for fast and slow attack and release, unison voicing from 1 to 8 voices with stereo correlation validation, sub-oscillator octave shifting, delay and reverb and distortion effects individually, three phase distortion algorithms, standard versus enhanced quality mode stereo behavior, 8-voice polyphony stress testing, velocity dynamic range, and silence verification. Discovered that wavetable selections 4 through 7 in the APVTS parameter definition have no corresponding generator implementations and fall through to default sine
        • 49abdebAdded three-tier automated audio testing pipeline enabling recursive agent-driven verification of synth and effect output. Created a Python analysis suite (audio_test_analyzer.py) extending the existing wavetable test script with 20+ metrics including frequency detection, RMS/peak levels, spectral analysis, envelope timing, stereo correlation, and effects detection across four modes: single-file analysis, test spec assertion validation, golden master comparison, and golden master creation with structured JSON output. Built header-only C++ audio test helpers (audio_test_helpers.hpp) providing a JUCE-free SimpleWavWriter, DspTestRenderer, and BasicSpectralAnalysis for standalone compilation of DSP simulation tests, and added Catch2 audio-output tests covering Subtractive, FM, and Additive synth sims plus filter response verification with WAV file rendering. Implemented a headless AudioTestRunner with JSON test specification parsing, MIDI event injection with sample-accurate timing, processor configuration, and offline render loop, wired into EphemeraStandaloneApplication as a --audio-test CLI mode following the existing --sandbox pattern. Created initial synth smoke test specifications covering all five synth engines with polyphony and velocity test cases.
      • Modulation
        • 8e35214Fixed AudioParameterChoice float truncation bug across all 5 synth engines by replacing 34 instances of static_cast(param->load()) with juce::roundToInt to prevent choice index truncation when JUCE returns 0.999 instead of 1.0. Affected parameters include oscillator waveform selection, filter type, LFO waveform, LFO destination, algorithm selection, glide mode, window shape, harmonic count, and modulation destinations in Subtractive (8), FM (5), Additive (5), and Granular (8) engines, matching the fix already applied to Wavetable (8). Also fixed the reverb damping LP frequency mapping in Subtractive and Granular from incorrect linear (18000*(1-damping)) to the correct exponential ReverbParameterMapping::dampingToLpFreq curve matching the ReverbScJuceProcessor's internal mapping
        • 21bff45Strengthened wavetable synth test coverage from smoke-only to meaningful verification across 30+ tests in both the rigorous and comprehensive suites. Added three new Python analyzer metrics (windowed spectral centroid early/late/std, RMS std for tremolo detection, reverb tail centroid) to enable assertions that prove parameters actually affect the output. Upgraded the five originally identified weak areas (filter envelope sweep, morph rate, WT envelope modulation, amp release timing, bypass toggles) and filled nine additional gaps including all LFO destinations, phase distortion types, pan L/R levels, reverb damping, filter BP/Notch, distortion, wavetable types 2-7, and filter key tracking. Final results: 35/36 rigorous (only pre-existing sub-oct2 bug) and 65/65 comprehensive, all validated on fresh Release renders
      • Effects
        • 9df5b14Fixed sub-oscillator -2 octave and reverb damping bugs discovered by the strengthened wavetable test suite. The sub-oscillator used static_cast on AudioParameterChoice float values which truncated 0.999 to 0, causing -2 octave mode to behave as -1 octave. Replaced with threshold comparisons for the two binary choice params (sub octave and quality mode) and juce::roundToInt for all other choice params (filter type, LFO waveform, LFO destination, phase distortion type, unison voices). The reverb damping in Enhanced mode called setLpFreqRealTime with a manual linear mapping that was never applied to the reverb engine because the non-legacy code path requires recomputeDerivedParameters; switched to setDampingRealTime which triggers the proper exponential damping-to-LP-frequency recompute. Also fixed the AudioTestRunner not overwriting existing WAV files on re-render by adding deleteFile before write, and reversed the init order to prepareToPlay before configureProcessor so parameter values are set after synth engine initialization
        • b6e6d45Granular synth: fix progressive distortion buildup from uncompensated filter resonance
      • UI / UX
        • 2df875dAdded 20 factory presets for the wavetable synthesizer covering Basic, Pad, Keys, Bass, Lead, Vocal, and FX categories. Created WavetablePresets.h following the established AdditivePresets.h pattern with a Preset struct mapping all 47 wavetable parameters, applyPreset via APVTS, getFactoryPresets returning static const data, and showPresetMenu with categorized ThemedPopupMenuLookAndFeel submenus. Wired the preset button in WavetableWindow.cpp which was previously a stub. Presets range from clean Init Patch and Warm Analog basics through Evolving Pad and Glass Shimmer atmospheres, Pluck Keys and Electric Piano, Sub Bass and Acid Bass, Screaming Lead and Supersaw Stack, Vocal Choir and Breathy Organic textures, to Metallic Shimmer and Alien Texture effects, designed to showcase the full parameter space including morphing, phase distortion, unison, sub-oscillator, filter envelope, LFO destinations, and post-mix effects
        • 77ee2d7Typography: unify font sizes under DesignTokens, remove legacy EphemeraLookAndFeel constants Removed five unused/underused static font size constants (SmallFontSize, StandardFontSize, MediumFontSize, TitleFontSize, LargeTitleFontSize) from EphemeraLookAndFeel and migrated the four remaining references to DesignTokens::Typography equivalents (heading, caption), establishing DesignTokens as the single typography authority.
        • 55d317dReplaced 31 hardcoded Colour(0x...) values with DesignTokens equivalents across the four central UI renderers (ButtonStyleRenderer, ToggleButtonRenderer, RotarySliderRenderer, FaderSliderRenderer), OutputMeterComponent, and BaseGridComponent. Mapped clipping indicators and record buttons to semantic error tokens, limiter states to warning tokens, inactive UI elements to DarkTheme surface and button tokens, and text colors to the text primary and secondary hierarchy. Left physical hardware simulation colors (knob body gradients, fader cap materials, groove recesses) and effect type identity colors unchanged as they are intentionally theme-independent
    • Day 365 · 20 commits
      • Audio engine
        • aabd9d73000th Commit!!! Add Condition Preview Scrubber to mixer for real-time condition auditioning. Wow, what a journey so far. Anf for it to happen on the one year anniversary whwas lucky but then at the end I pushed for 3,000. I am happy with the progress so far, and I'm excited to see what another year of hard work brings to Ephemera. Hopefully I'll be sharing it with people soon
        • bdaf47bFix BPM editor font not applying to existing text by using applyFontToAllText
        • 3c54fccIncrease BPM editor width and font size for better readability in bottom bar
        • d20c18eAdded tooltips to 25 previously uncovered controls in ExportManagerWindow. Registered bitrate, OGG quality, channel mode, preset management, normalization mode and targets, LUFS and true peak settings, platform targets, trim threshold, stem naming template, multi-format toggles, batch condition controls, output path and filename template, and action buttons. Updated unregisterTooltips to match
      • Effects
        • db36f9eAdded tooltips to seven effect processing components. Added setTooltip calls for NoiseReductionPanel, DeClipPanel, ClickRemovalPanel, SidechainRoutingComponent, MultibandEditorComponent, and ParallelChainEditor controls. Registered RoutingMatrixComponent with multi-level tooltips via its existing TooltipManager reference
      • Visualizer
        • 0232df4Migrate AdditiveHarmonicVisualizer hardcoded colors to DesignTokens Moves 24 juce::Colours:: references (lightblue, white, black, yellow) across 6 visualization modes into a new DesignTokens::Synth::Visualizer namespace. Only transparentBlack gradient endpoints remain as standard fade-to-nothing patterns
        • f38996cFixed split-reveal animation by centralizing timer lifecycle
        • 01e9822Bump subheading typography from 16px to 18px for clearer visual hierarchy
      • UI / UX
        • 8dead88Fix stale font size comments in createPanelLabelFont/createPanelButtonFont createPanelLabelFont() comment said 14px but actual default is 16px; createPanelButtonFont() said 15px but is 17px. Comments fell out of sync when defaults were increased
        • c7e3052Replace 8-9px hardcoded font sizes with DesignTokens::Typography::caption across 65 files
        • 8748545Use design tokens for ToggleButtonRenderer font sizes
        • 10c709cReplace hardcoded 13px tab button font with design token createLabelFont
        • 5d71111Added tooltips to four overlay components. Registered SpectrogramOverlay, SpectralSelectionOverlay, and ChordDetectionOverlay with multi-level tooltips in WaveformDisplayComponent, and added setTooltip on ExportStatusOverlay's OK, Cancel, and Show in Explorer buttons
        • bd831e0Fix Location Samples header using oversized font instead of design system subheader font
        • 9bc71fbAdded hover tooltips to seven grid configuration components. Added setTooltip calls in GridConfigPanel, GridListComponent, GridManagerComponent, LocationConfigComponent, SeasonsConfigComponent, DayOfWeekConfigComponent, and TidesConfigComponent covering all interactive controls including combo boxes, sliders, toggles, and buttons
      • Other
        • 19fb7f3Redesign 20 subtractive synth factory presets for musicality
        • 9d53864Added hover tooltips to 12 high-priority dialogs including TempoEventEditDialog, LegatoTransformDialog, StrumTransformDialog, VelocityRangeDialog, PianoRollQuantizeDialog, RepeatClipsDialog, PatternRepeatDialog, PatternDuplicateDialog, CrossfadeEditorDialog, InvertPitchTransformDialog, AutoSaveFirstRunDialog, and DuplicateTrackDialog
        • 2a64c8aAdded tooltips to six miscellaneous interactive components. Added setTooltip calls for GoToTimeDialog, RecordingInputAlertDialog, and MPEZoneConfigPanel controls. Registered CollapsibleBottomPanel instances in EditorPanelManager, EnvironmentVisualizerComponent in EditorComponentInitializer, and MPEExpressionLane in PianoRollViewport. Skipped TempoCurveEditor (not instantiated) and AssignToGridComponent (entirely custom-drawn)
        • dc0b11cAdded hover tooltips to five import and export dialogs. Added setTooltip calls for MidiImportDialog, MidiExportDialog, BatchConversionDialog, AudioToMidiDialog, and MissingSampleRelinkDialog covering all interactive controls
        • 0cc0dbbAdded multi-level tooltips to six synth visualizer components. Registered AdditiveHarmonicVisualizer, GranularCloudVisualizer, SubtractiveVisualizer, and WavetableVisualizer3D via TooltipManager in their synth window creation sites. Registered EnvelopeVisualizer in EnvelopeControlPanel and added setTooltip for LFOWaveformVisualizer in SubtractiveLFOPanel