Files
game_engine/docs/superpowers/specs/2026-03-25-phase6-3-mixer.md
2026-03-25 11:37:16 +09:00

3.3 KiB

Phase 6-3: Mixer — Design Spec

Overview

voltex_audio에 그룹 기반 믹서를 추가한다. BGM/SFX/Voice 그룹별 독립 볼륨 제어와 페이드 인/아웃을 지원한다.

Scope

  • MixGroup enum (Master, Bgm, Sfx, Voice)
  • GroupState (볼륨 + 페이드)
  • MixerState (전체 그룹 관리, effective_volume = group * master)
  • PlayingSound에 group 필드 추가
  • mix_sounds에 mixer 파라미터 추가
  • AudioSystem API: set_group_volume, fade_group

Out of Scope

  • 동적 그룹 생성 (고정 4개만)
  • 그룹 간 라우팅/버스
  • 이펙트 체인 (reverb, EQ 등)
  • 페이드 커브 (선형만)

Module Structure

  • crates/voltex_audio/src/mix_group.rs — MixGroup, GroupState, MixerState (Create)
  • crates/voltex_audio/src/mixing.rs — PlayingSound에 group, mix_sounds에 mixer (Modify)
  • crates/voltex_audio/src/audio_system.rs — SetGroupVolume, FadeGroup 명령 (Modify)
  • crates/voltex_audio/src/lib.rs — mix_group 모듈 등록 (Modify)

Types

MixGroup

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MixGroup {
    Master,
    Bgm,
    Sfx,
    Voice,
}

GroupState

pub struct GroupState {
    pub volume: f32,
    pub fade_target: f32,
    pub fade_speed: f32,
}
  • new() → volume=1.0, fade_target=1.0, fade_speed=0.0
  • tick(dt: f32) — volume을 fade_target으로 fade_speed * dt만큼 이동. 도달하면 fade_speed=0.

MixerState

pub struct MixerState {
    groups: [GroupState; 4], // Master, Bgm, Sfx, Voice 순서
}

배열 인덱스로 접근 (HashMap 대신 간결하게).

  • new() — 전부 volume=1.0
  • set_volume(group, volume) — 즉시 설정, fade 중지
  • fade(group, target, duration) — fade_speed = |target - current| / duration
  • tick(dt) — 모든 그룹 업데이트
  • volume(group) -> f32 — 해당 그룹 현재 볼륨
  • effective_volume(group) -> f32 — group.volume * master.volume (Master 그룹은 자기 자신만)

Mixing Integration

PlayingSound 변경

pub group: MixGroup,  // 기본 Sfx
  • new() → group = MixGroup::Sfx
  • new_3d() → group = MixGroup::Sfx
  • 기존 생성자에 group 파라미터 추가하지 않음 (기본값 사용). 필요 시 직접 설정.

mix_sounds 변경

mixer: &MixerState 파라미터 추가.

각 사운드의 최종 볼륨 계산:

base_volume = sound.volume * mixer.effective_volume(sound.group)

이후 spatial gains 적용은 기존과 동일.

AudioCommand 추가

SetGroupVolume { group: MixGroup, volume: f32 },
FadeGroup { group: MixGroup, target: f32, duration: f32 },

AudioSystem 메서드 추가

pub fn set_group_volume(&self, group: MixGroup, volume: f32)
pub fn fade_group(&self, group: MixGroup, target: f32, duration: f32)

오디오 스레드

  • MixerState 인스턴스 보유
  • 매 루프: mixer.tick(dt) 호출 (dt ≈ 5ms)
  • mix_sounds에 &mixer 전달

Test Plan

mix_group.rs

  • GroupState::tick: 페이드 진행, 목표 도달 시 정지
  • MixerState::set_volume: 즉시 반영
  • MixerState::fade: 여러 tick 후 목표 도달
  • MixerState::effective_volume: group * master
  • Master=0이면 모든 그룹 effective=0

mixing.rs (통합)

  • group 볼륨 적용: Sfx volume=0.5 → 출력 절반
  • master=0 → 전체 무음
  • 기존 2D/3D 테스트는 mixer volume=1.0으로 변화 없음