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>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
aa004eb7b8
commit
0ca7d269d2
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "l4audio.h"
|
||||
#include "l4audlvl.h"
|
||||
#include "l4audefx.h"
|
||||
#include "l4app.h"
|
||||
#include "l4audrnd.h"
|
||||
#include "..\munga\namelist.h"
|
||||
@@ -964,6 +965,31 @@ void
|
||||
channel->SendController(MIDI_PAN_CONTROL, MIDI_RIGHT_PAN_VALUE);
|
||||
break;
|
||||
}*/
|
||||
// (task #50, AUDIO_FIDELITY F12) the original routed each Direct cockpit
|
||||
// source by its authored 6-value position enum (front/rear CARD + pan
|
||||
// CC10 left/center/right). Reproduce as a listener-relative placement;
|
||||
// a zone's own L/R pan (stereo-pair presets) offsets on top. The
|
||||
// distance model is AL_NONE, so this affects direction only, never gain.
|
||||
{
|
||||
float px = 0.0f, pz = -1.0f; // Front, centered
|
||||
switch (audioPosition)
|
||||
{
|
||||
case FrontDirectPatchPosition: px = 0.0f; pz = -1.0f; break;
|
||||
case RearDirectPatchPosition: px = 0.0f; pz = 1.0f; break;
|
||||
case FrontLeftDirectPatchPosition: px = -0.7f; pz = -0.7f; break;
|
||||
case FrontRightDirectPatchPosition: px = 0.7f; pz = -0.7f; break;
|
||||
case RearLeftDirectPatchPosition: px = -0.7f; pz = 0.7f; break;
|
||||
case RearRightDirectPatchPosition: px = 0.7f; pz = 0.7f; break;
|
||||
}
|
||||
for (int _i = 0; _i < channelSet.count; ++_i)
|
||||
{
|
||||
SAMPLEINFO zinfo = PRESET_getSampleInfo(
|
||||
patch_resource->GetBankID(), patch_resource->GetPatchID(), _i);
|
||||
float pan_x = (zinfo.chan == CHANNEL_LEFT) ? -0.5f :
|
||||
(zinfo.chan == CHANNEL_RIGHT) ? 0.5f : 0.0f;
|
||||
alSource3f(channelSet.sources[_i], AL_POSITION, px + pan_x, 0.0f, pz);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Set midi history to default control values
|
||||
@@ -1082,6 +1108,13 @@ void
|
||||
if (Abs(filter_difference) >= filter_resolution)
|
||||
{
|
||||
lastMIDIFilterCutoff = midi_filter_cutoff;
|
||||
// (task #50, AUDIO_FIDELITY F9) the original sent this cutoff as
|
||||
// AWE NRPN 21; the EFX lowpass is the modern sink (was a dead
|
||||
// bookkeeping write -- ctl-5 Brightness played full-bright).
|
||||
float gainhf = EFX_CutoffScaleToGainHF(
|
||||
(float)lastMIDIFilterCutoff / (float)MIDI_MAX_CONTROL_VALUE);
|
||||
for (int _i = 0; _i < channelSet.count; ++_i)
|
||||
EFX_SetSourceLowpassGainHF(channelSet.sources[_i], gainhf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1260,6 +1293,12 @@ void
|
||||
channel->SendController(MIDI_REVERB_CONTROL, midi_reverb_level);
|
||||
channel->SendController(MIDI_CHORUS_CONTROL, MIDI_MIN_CONTROL_VALUE);
|
||||
}*/
|
||||
// (task #50, AUDIO_FIDELITY F11) the CC91 send above is the authentic
|
||||
// wet-exterior contrast (global_reverb_scale on every 3D channel, decomp
|
||||
// part_008.c:7278-7394); the EFX aux slot is the modern sink. Cockpit
|
||||
// Direct sources stay dry (their CC91 was 0).
|
||||
for (int _i = 0; _i < channelSet.count; ++_i)
|
||||
EFX_AttachReverbSend(channelSet.sources[_i]);
|
||||
|
||||
//
|
||||
// Set the channels to correct pan
|
||||
@@ -1459,11 +1498,22 @@ void
|
||||
<< " loc=(" << locationPosition.x << "," << locationPosition.z << ")"
|
||||
<< " dist=" << posMag << " vol=" << volume_scale << "\n" << std::flush; }
|
||||
|
||||
// (task #50, AUDIO_FIDELITY F9) the original drove the AWE filter cutoff
|
||||
// from highFreqCutoffScale x brightnessScale on this dynamic path --
|
||||
// UNGATED, all channels (part_008.c:7496,7589-7604): every moving 3D
|
||||
// sound gets duller with distance (AUDIO.INI knee 60 / exponent 2.0).
|
||||
float dyn_gainhf = EFX_CutoffScaleToGainHF(
|
||||
(float)(GetAudioLocation()->GetHighFreqCutoffScale()
|
||||
* CalculateSourceBrightnessScale()
|
||||
* (Scalar)patch_resource->GetMaxMIDIFilterCutoff()
|
||||
/ (Scalar)MIDI_MAX_CONTROL_VALUE));
|
||||
|
||||
for (int i=0; i < channelSet.count; i++)
|
||||
{
|
||||
alSource3f(channelSet.sources[i],AL_POSITION,pos.x,pos.y,pos.z);
|
||||
alSourcef(channelSet.sources[i], AL_GAIN, volume_scale * volume_scale); // FIDELITY F4: CC7 squared law (linear was ~+6 dB at mid volumes)
|
||||
alSource3f(channelSet.sources[i],AL_VELOCITY,-relative_velocity.x,-relative_velocity.y,-relative_velocity.z);
|
||||
EFX_SetSourceLowpassGainHF(channelSet.sources[i], dyn_gainhf);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1786,6 +1836,10 @@ void
|
||||
channel->SendController(MIDI_CHORUS_CONTROL, MIDI_MIN_CONTROL_VALUE);
|
||||
}
|
||||
}*/
|
||||
// (task #50, AUDIO_FIDELITY F11) static 3D sources are wet like the
|
||||
// dynamic ones (the CC91 block above); Direct cockpit stays dry.
|
||||
for (int _i = 0; _i < channelSet.count; ++_i)
|
||||
EFX_AttachReverbSend(channelSet.sources[_i]);
|
||||
|
||||
//
|
||||
// Set the channels to correct pan
|
||||
@@ -2006,11 +2060,19 @@ void
|
||||
relative_position = audio_location->GetVectorToSource();
|
||||
}
|
||||
|
||||
// (task #50, AUDIO_FIDELITY F9) static sources: brightness-driven cutoff
|
||||
// only (part_008.c:7831-7884 -- the NRPN block commented below).
|
||||
float static_gainhf = EFX_CutoffScaleToGainHF(
|
||||
(float)(CalculateSourceBrightnessScale()
|
||||
* (Scalar)patch_resource->GetMaxMIDIFilterCutoff()
|
||||
/ (Scalar)MIDI_MAX_CONTROL_VALUE));
|
||||
|
||||
//Static models have their position freely available as relative positions and stand still
|
||||
for (int i=0; i < channelSet.count; i++)
|
||||
{
|
||||
alSourcef(channelSet.sources[i], AL_GAIN, volume_scale * volume_scale); // FIDELITY F4: CC7 squared law (linear was ~+6 dB at mid volumes)
|
||||
alSource3f(channelSet.sources[i],AL_POSITION,relative_position.x,relative_position.y,relative_position.z);
|
||||
EFX_SetSourceLowpassGainHF(channelSet.sources[i], static_gainhf);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user