이 문서는 사용자 대상 릴리스 요약입니다. 개발자 상세 변경 이력은 CHANGELOG.md 참조. This is a user-facing release summary. For detailed developer change history, see CHANGELOG.md.
- Independent Input Mute / 독립 입력 뮤트: INPUT 전용 뮤트를 추가/정리하여 입력만 무음 처리하고 체인/출력 경로는 유지합니다. Added dedicated INPUT mute behavior that silences mic input only while keeping chain/output paths running.
- Panic Mute Clarification / 패닉 동작 명확화: Panic은 OUT/MON/VST 차단 + 녹음 자동 중지를 유지하고, 해제 시 사용자 뮤트 상태를 복원합니다. Panic still blocks OUT/MON/VST and stops active recording, then restores user mute states on unmute.
- State Model Update / 상태 모델 갱신:
active_slot을0-5(5=Auto,-1=none)로 통합했고auto_slot_active는 deprecated입니다. Unifiedactive_slotto0-5with-1as none;auto_slot_activeis now deprecated. - XRun QoL / XRun 운용성 개선: 60초 윈도우 드리프트를 수정하고 CPU/XRun 라벨 클릭 리셋을 추가했습니다. Fixed 60-second drift and added click-to-reset on CPU/XRun label.
- SR-safe NR timing / SR 안전 NR 타이밍: NR hold/smoothing이 런타임 SR 기준으로 재계산됩니다. NR hold/smoothing now recalculates from runtime sample rate.
- API clients / API 연동:
active_slot(0-5/-1)을 기준으로 사용하고auto_slot_active는 하위 호환용으로만 유지하세요. Preferactive_slotas source of truth and keepauto_slot_activeonly for backward compatibility. - Control integrations / 제어 연동:
input_muted와 panicmuted는 독립 상태입니다.input_mutedis independent from panicmuted; do not assume mirrored state.
- NoiseRemoval: Ring buffer uint32_t overflow causing permanent silence after ~25h continuous use
- HTTP API: Strict numeric validation — reject mixed alpha-numeric input (e.g., "abc0.5")
- UI: Plugin chain editor negative height on very small window
- State Broadcast: activeSlot clamped to 0-4, added
auto_slot_activefield for WebSocket/SD clients - Linux: Complete XDG Desktop Entry Exec key character escaping per spec
- macOS: Notify user when hotkey accessibility permission not granted
- Linux: Show "unsupported" message in Hotkeys tab instead of non-functional UI
- HTTP API: Escape JSON special characters in API responses
- Platform: AutoStart setters return bool, notify user on failure
- IPC: Restrict POSIX semaphore/shm permissions to owner-only (0600)
- XRun Tracking: Device restart no longer clears XRun history — display persists for full 60s window
- Audio RT: Moved MMCSS LoadLibraryA call from RT callback to audioDeviceAboutToStart
- MIDI: Fixed LearnTimeout use-after-free when timer callback destroyed itself
- Preset: Added loadingSlot_ guard to Reset Auto to prevent intermediate state auto-save
- Audio: Recorder now stops on device loss (audioDeviceStopped) to prevent WAV corruption
- Preset: Auto first-click failure now sets partialLoad_ to prevent saving incomplete chain
- Preset: pendingSlot_ cleared on Factory Reset / Clear All Presets
- State: Plugin name now included in quickStateHash — name changes trigger WebSocket broadcast
- WebSocket: broadcastToClients releases clientsMutex_ before socket writes — prevents slow client blocking shutdown
- IPC: Receiver VST now calls detach() before close() on failed producer check — fixes spurious multi-consumer warning
- Thread Safety: audioDeviceAboutToStart non-atomic variable writes deferred to message thread via callAsync
- Update: PowerShell batch script now escapes single quotes in paths
- Audio: Added null guard on outputChannelData for ASIO legacy drivers
- Preset: parseSlotFile now uses .bak fallback for crash resilience
- UI: Plugin removal now identifies by index+name, not name-only (fixes duplicate-name removal)
- WebSocket: Sends RFC 6455 close frame (1009) before disconnecting oversized-message clients
- Settings: importAll/importFullBackup now check platform compatibility internally
- Platform: macOS/Linux AutoStart uses atomicWriteFile for crash-safe writes
- MainComponent split: Reduced
MainComponent.cppfrom ~1835 lines to ~729 lines by extracting 7 focused classes:ActionHandler(Control/) — Centralized action event handling (moved from MainComponent's 200+ line switch-case)SettingsAutosaver(Control/) — Dirty-flag + debounce auto-save logicPresetSlotBar(UI/) — Preset slot A-E buttons, naming, right-click menuStatusUpdater(UI/) — Status bar updates (latency, CPU, format, notifications)UpdateChecker(UI/) — Background GitHub release check + update dialogHotkeyTab,MidiTab,StreamDeckTab(UI/) — Split from monolithicControlSettingsPanel
- ActionResult pattern: New
ActionResultstruct (ActionResult.h) for typed success/failure returns with messages. Replaces barebool/voidreturns on AudioEngine device methods.static ok()/static fail(msg),explicit operator bool(). - onError callback pattern:
std::function<void(const juce::String&)> onErroronAudioSettingsandOutputPanel, wired toMainComponent::showNotification()for clean error propagation.
- 52 → 110+ tests across 6 host test suites (was 2):
WebSocketProtocolTest(30 tests) — expanded with state serialization, error handling, edge casesActionDispatcherTest(31 tests) — expanded with ActionResult integration, error pathsActionResultTest(12 tests) — new: ok/fail factory, bool conversion, message propagationControlMappingTest(16 tests) — new: hotkey/MIDI/server serialization roundtrip, defaults, error handlingNotificationQueueTest(10 tests) — new: lock-free SPSC queue correctness, overflow, cross-thread
- GTest dashboard integration:
pre-release-dashboard.htmlnow loads GTest JSON output files for visual test result inspection. - GTest JSON output:
pre-release-test.shgenerates--gtest_output=json:files for both core and host tests.
- Platform abstraction layer: New
host/Source/Platform/module with per-platform implementations (PlatformAudio, AutoStart, ProcessPriority, MultiInstanceLock). Replaces hardcoded Windows API calls with cross-platform interfaces. - macOS support (Beta): CoreAudio driver, LaunchAgent auto-start, CGEventTap hotkeys (requires Accessibility permission), Gatekeeper instructions.
- Linux support (Experimental): ALSA/JACK drivers, XDG autostart, hotkey stub (use MIDI/HTTP/WebSocket instead).
- Cross-OS backup protection: Backup files (
.dpbackup,.dpfullbackup) now include aplatformfield. Restoring a backup from a different OS is blocked with a warning dialog. - Platform-adaptive UI labels: "Start with Windows" (Windows), "Start at Login" (macOS), "Start on Login" (Linux).
- Plugin scanner cross-platform paths: Scans OS-specific VST directories (Windows:
Program Files\..., macOS:/Library/Audio/Plug-Ins/..., Linux:/usr/lib/vst3/...). - Plugin file browser: Platform-specific file filters (
.dllon Windows,.vst3/.vst/.componenton macOS,.vst3/.soon Linux). - Preset deviceType validation: Skips unavailable device types when importing presets (e.g., WASAPI preset on macOS).
- CJK font per platform: Windows (Malgun Gothic), macOS (Apple SD Gothic Neo), Linux (Noto Sans CJK).
- Core library: Added POSIX library linking for macOS (
-lpthread) and Linux (-lrt -lpthread). - Receiver plugin: Added
JUCE_PLUGINHOST_AU=1for macOS AudioUnit builds. - CMake: Platform-conditional WASAPI/ASIO/CoreAudio/ALSA/JACK defines.
- CI/CD: macOS build artifact changed from
.zipto.dmg— prevents v3 auto-updater from downloading wrong binary (updater looks for.zip→.dmgis invisible to it).
- VST Bypass fix:
setPluginBypassednow syncsnode->setBypassed()+getBypassParameter()->setValueNotifyingHost()and callsrebuildGraph(false)to disconnect bypassed plugins in the signal chain. Fixes bypass not working for plugins with internal bypass parameter (Clear, RNNoise, etc.).rebuildGraphgainssuspendparameter (defaulttrue) — bypass toggle usesfalsefor glitch-free connection-only rebuild. Iterator safety fix (copygetConnections()before removal). - Preload cache race condition fix: Per-slot version counter (
slotVersions_) prevents background preload thread from storing stale plugin instances afterinvalidateSlotwas called mid-preload. Version captured at file-read time, checked before cache store. - Cache structure validation:
saveSlotnow checks plugin structure (names/paths/order) viaisCachedWithStructurebefore deciding to invalidate cache. Parameter-only saves (bypass, state) skip invalidation. Prevents stale cache when plugins are added/removed/replaced/reordered.
- ASIO device iteration fix:
setAudioDeviceTypenow builds an ordered try-list (tryOrder: preferred → lastAsio → all remaining devices) and iterates through all available ASIO devices. Previously only trieddevices[0]— if that device was disconnected, no other ASIO devices were attempted. Individual device failures logwarnandcontinueto next device; full revert to previous driver only when all devices fail. - Driver combo sync on ASIO failure:
AudioSettings::onDriverTypeChangednow checks theboolreturn value ofsetAudioDeviceType. On failure (engine reverted to previous driver), syncs the driver combo to the actual current driver type viagetCurrentDeviceType(). Fixes UI showing "ASIO" while engine was already back on WASAPI.
- Panic mute comprehensive blocking: All action cases in
ActionHandler::handle()now checkengine_.isMuted()— PluginBypass, MasterBypass, InputGainAdjust, SetVolume (input), SetPluginParameter, LoadPreset, SwitchPresetSlot, NextPreset, PreviousPreset, RecordingToggle. Previously some actions (bypass, gain, presets) could execute during panic mute. - Panic mute stops recording:
doPanicMute(true)now stops active recording (recording is mic output → must stop). Recording does not auto-restart on unmute. RecordingToggle is also blocked during panic. - HTTP CORS preflight: Added
OPTIONSrequest handler withAccess-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONSfor browser-based clients (e.g., pre-release dashboard). Without this, browser PUT/DELETE requests got connection reset before reaching the 405 handler. - HTTP gain delta scaling:
/api/gain/:deltanow multiplies delta by 10× to compensate forActionHandler's*0.1fscaling (designed for hotkey steps of ±1.0 meaning ±1 dB = ±0.1 gain). PreviouslyGET /api/gain/1.0only applied +0.1 gain instead of +1.0. - HTTP volume/parameter validation: Volume and parameter endpoints validate numeric input —
indexOfAnyOf("0123456789.")check rejects non-numeric strings like "abc" whichgetFloatValue()silently converts to 0.0. - UpdateChecker lifetime fix:
alive_promoted from local variable to class member. Destructor setsfalsebefore joining threads, preventing use-after-free in pendingcallAsynclambdas. - IPC lock-free assertion:
Protocol.hnow hasstatic_assert(std::atomic<uint64_t/bool>::is_always_lock_free)— compile-time guarantee that shared memory atomics never use hidden mutexes. - MidiTab Learn race fix:
startLearncallback capturesmanager_reference directly instead of rawthis, eliminating potential use-after-free when MIDI thread fires callback during tab destruction. - VSTChain addPlugin double-suspend fix: Removed orphaned
suspendProcessing(true)aroundaddNode(). JUCE uses a counter-based suspend mechanism — the extra suspend without matching resume left the audio graph muted after plugin load. - RingBuffer availableWrite clamp: Added
std::minoverflow guard matchingavailableRead(), preventing underflow if positions are transiently inconsistent. - Receiver VST RT-safety: Replaced
std::vector::resize()insaveLastOutput(called fromprocessBlock) withjassert— buffer is pre-allocated inprepareToPlay. - Code deduplication: Extracted identical
actionToDisplayName(~40 lines) fromHotkeyTab.cppandMidiTab.cppto sharedActionDispatcher.h. input_mutedclarification:input_mutedis independent frommuted(panic mute).InputMuteTogglemutes microphone input only while keeping the VST chain and output paths running.
- Platform Guide (new): OS-specific setup, features, and limitations.
- Pre-release dashboard: Platform selector (Windows/macOS/Linux) for OS-specific test items.
- All docs updated with cross-platform information.
- Multi-instance external control priority: Named Mutex system (
DirectPipe_NormalRunning,DirectPipe_ExternalControl) prevents hotkey/MIDI/WebSocket/HTTP conflicts between instances. Normal mode blocks if portable has control. Portable runs audio-only if another instance already controls. - Audio-only mode indicators: Title bar "(Audio Only)", status bar orange "Portable", tray tooltip "(Portable/Audio Only)".
- IPC blocked in audio-only mode:
setIpcEnabled(true)silently ignored — prevents shared memory name collision between instances. - Quit button: Red "Quit" button in Settings tab (next to auto-start toggle) for closing individual instances.
- Driver type snapshot/restore: Settings (input/output device, SR, BS) saved per driver type before switching. Automatically restored when switching back (e.g., WASAPI → ASIO → WASAPI preserves original WASAPI settings).
- Per-direction device loss: Input and output device loss handled independently.
inputDeviceLost_: Silences input in audio callback (prevents fallback mic audio leak).outputAutoMuted_: Auto-mutes output on device loss, auto-unmutes when restored.- Edge-detection notifications for both directions.
- Reconnection miss counter: After 5 consecutive failed reconnection attempts (~15s), accepts current driver's devices to break cross-driver stale name infinite loops. When
outputAutoMuted_is true (genuine device loss), the counter resets and keeps waiting indefinitely — fallback only applies to stale name issues, not physical disconnection. - Reconnection state cleanup:
setAudioDeviceTypeclearsdeviceLost_,inputDeviceLost_,outputAutoMuted_, and reconnect counters to prevent stale state after intentional driver switch. - Output "None" state on driver switch:
outputNone_cleared when switching driver types (prevents OUT mute button getting stuck after WASAPI "None" → ASIO).DriverTypeSnapshotnow includesoutputNonefor save/restore across driver switches. - Device loss UI: Input/output combos show "DeviceName (Disconnected)" when device is physically lost (instead of showing fallback device name). Clears when device is reconnected or user manually selects another device.
- Manual device selection during loss:
setInputDevice/setOutputDevicenow cleardeviceLost_,inputDeviceLost_, reconnection counters — allows user to manually pick a different device during device loss without interference from reconnection logic.
- LevelMeter: Smoother release (kRelease 0.05→0.12, ~230ms half-life at 30Hz). Lower repaint threshold (0.001→0.0004) for finer visual response.
- PluginChainEditor delete fix: Delete confirmation now uses
slot->nameinstead ofnameLabel_.getText()(which includes row prefix "1. Clear"), fixing silent delete failure from name mismatch.
- PluginPreloadCache
cancelAndWait: Heap-allocatedshared_ptrfor join state — prevents dangling reference if detached joiner thread outlives caller's stack frame. - HttpApiServer thread cleanup: Handler thread join moved outside
handlersMutex_lock (deadlock prevention, same pattern as WebSocketServer). - StateBroadcaster hash:
quickStateHashnow includesinputMuted,sampleRate,bufferSize,channelMode, and pluginloadedstate for more accurate dirty detection.
- ASIO startup buffer size bounce fix (wrong device selection during type switch)
pushNotificationMPSC ring buffer fix- MonitorOutput
alive_flag lifetime guard - AudioRingBuffer
reset()ordering fix - StateBroadcaster
slotNameshash fix
- Output device switching fix (fallback false positive + input channel loss)
- ASIO buffer size persistence fix (
desiredBufferSize_preserves user request)
- Slot naming (right-click Rename,
A|게임display) / Slot naming (right-click Rename,A|Gamedisplay) - Individual slot export/import (
.dppreset) - StateBroadcaster
slot_namesarray
- Device fallback protection
- Hotkey drag-and-drop reorder
- MIDI HTTP API test endpoints
- MIDI Learn / Hotkey recording cancel buttons
- Instant preset switching (keep-old-until-ready)
- Settings scope separation (Save/Load vs Full Backup)
- Full Backup/Restore (
.dpfullbackup)
- Device auto-reconnection (dual mechanism)
- Monitor reconnect
- Click-to-refresh device combos
- StateBroadcaster
device_lost/monitor_lost
- WASAPI Exclusive Mode
- Audio optimizations (timeBeginPeriod, ScopedNoDenormals, RMS decimation)
- XRun monitoring
- 5 driver types
- Modal dialog fixes
- HTTP API input gain range
- Constructor SafePointer
- 25 bug fixes: thread safety, lifetime guards, server fixes, RT-safety
- Categorized logging
- LogPanel batch flush
- VSTChain lock-ordering fix
- Buffer display, SR propagation, monitor SR mismatch, Receiver VST SR warning
- Auto-updater UI, CJK font fix, download thread safety
- Plugin scanner fix (moreThanOneInstanceAllowed)
- IPC Toggle, Receiver VST buffer config, panic mute lockout
- NotificationBar, LogPanel, thread-safety audit (4 callAsync fixes)
- Tray tooltip, plugin search/sort, audio recording, settings save/load, MIDI param mapping, auto-updater