Files
BT411/engine/MUNGA_L4/L4AUDEFX.h
T
arcattackandClaude Opus 4.8 0ca7d269d2 Audio Phase 3 (AUDIO_FIDELITY F9/F11/F12): EFX lowpass + reverb split + cockpit placement
New L4AUDEFX bridge (OpenAL Soft ALC_EXT_EFX): one EAXReverb aux slot at the
authentic AUDIO.INI global_reverb_scale (0.3) + a scratch AL_FILTER_LOWPASS
(params copied at attach).

F9 filters (was: computed then thrown away -- everything full-bright at all
distances): Dynamic3D ExecuteModel drives GAINHF from highFreqCutoffScale x
brightnessScale x maxMIDIFilterCutoff, UNGATED (decomp part_008.c:7496,
7589-7604 -- every moving 3D sound dulls with distance per the AUDIO.INI
knee-60/exp-2.0 model); Static3D from brightness x max (:7831-7884); Direct
inside its existing gated NRPN-rate block.  AWE 100-8000 Hz curve -> EFX
5 kHz-reference gainhf via a 2-pole approximation [T3 curve, endpoints exact].

F11 reverb (was: bone-dry everywhere): 3D patch sources attach an aux send at
Start, exactly where the original sent CC91 = global_reverb_scale
(part_008.c:7278-7394); Direct cockpit sources keep CC91=0 -- dry.  The
wet-exterior vs dry-cockpit contrast is back.

F12 placement (was: every cockpit sound dead-center): DirectPatchSource
Start places sources by the authored 6-value position enum (front/rear card
+ pan CC10, decomp @00463848/@004638a8) as listener-relative directions,
composed with the zone L/C/R pan.  New PatchResource GetBankID/GetPatchID
pass-throughs (the LOD accessor is protected).

Regression (35s drive+fire): EFX READY, stable, deliveries unregressed, no AL
errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 11:59:39 -05:00

45 lines
1.9 KiB
C

#pragma once
//###########################################################################
//
// L4AUDEFX.h -- OpenAL EFX bridge for the authored filter/reverb chains
// (task #50, AUDIO_FIDELITY F9/F11).
//
// The original drove the AWE32 initial-filter-cutoff NRPN per frame
// (brightness x distance HF rolloff) and sent CC91 reverb on the 3D
// channels (global_reverb_scale=0.3, AUDIO.INI) while keeping the cockpit
// Direct channels dry. This bridge reproduces both through OpenAL Soft's
// EFX extension: one EAXReverb aux slot + a scratch AL_FILTER_LOWPASS
// whose parameters are copied at attach time.
//
//###########################################################################
#include "openal/al.h"
// Load the EFX entry points, create the reverb slot (gain = the authentic
// global_reverb_scale) and the scratch lowpass. Call once, with the AL
// context current. Returns false (and stays inert) without ALC_EXT_EFX.
bool EFX_Initialize(float global_reverb_scale);
bool EFX_Available();
// Per-frame direct-path lowpass: gainhf is the linear HF gain at the EFX
// 5 kHz reference. Callers map the AWE cutoff (100 + scale*7900/127 Hz)
// through EFX_CutoffScaleToGainHF below.
void EFX_SetSourceLowpassGainHF(ALuint source, float gainhf);
// AWE NRPN 21 curve -> EFX gainhf: cutoff_scale in [0,1] of the 100-8000 Hz
// span; approximated as the attenuation of a 2-pole lowpass at the 5 kHz
// reference [T3 -- curve shape approximate, endpoints exact].
inline float EFX_CutoffScaleToGainHF(float cutoff_scale)
{
if (cutoff_scale < 0.0f) cutoff_scale = 0.0f;
if (cutoff_scale > 1.0f) cutoff_scale = 1.0f;
float cutoff_hz = 100.0f + cutoff_scale * 7900.0f;
float g = (cutoff_hz / 5000.0f) * (cutoff_hz / 5000.0f);
return (g > 1.0f) ? 1.0f : ((g < 0.001f) ? 0.001f : g);
}
// Wet-exterior routing: attach the source's aux send to the reverb slot
// (Dynamic3D/Static3D). Direct cockpit sources stay dry by default.
void EFX_AttachReverbSend(ALuint source);