Confirmed Facts
The OpenAL specification defines the gain for AL_INVERSE_DISTANCE_CLAMPED as:
gain = 1 / (1 + rolloff * (distance - reference))
This value is then clamped between AL_MIN_GAIN and AL_MAX_GAIN. If AL_MAX_DISTANCE is non‑zero, the gain is forced to AL_MIN_GAIN for distances greater than or equal to that value. The properties AL_REFERENCE_DISTANCE, AL_ROLLOFF_FACTOR, AL_MAX_DISTANCE, AL_MIN_GAIN, and AL_MAX_GAIN are mutable per source and have no mandated default values in the spec.
Likely Explanation
Observed differences in attenuation curves between OpenAL Soft, Creative’s hardware driver, and platform‑specific OpenAL implementations usually stem from:
- Different internal defaults for
AL_REFERENCE_DISTANCE and AL_MAX_DISTANCE when the application does not set them explicitly.
- Variations in how drivers treat
AL_MIN_GAIN (some enforce a non‑zero floor to avoid silent channels).
- Possible driver‑specific interpretation of the rolloff factor (though the formula is standard, older Creative drivers have been known to apply it as a simple distance multiplier).
Because the spec leaves the defaults undefined, the only way to guarantee identical behavior is to override all relevant parameters to values that are within the supported range of every target backend.
Recommended Settings for Deterministic Attenuation
AL_REFERENCE_DISTANCE = 1.0 (a convenient unit distance).
AL_ROLLOFF_FACTOR = 1.0 (the standard inverse‑distance slope).
AL_MAX_DISTANCE = 0.0 (disables the hard cutoff; the spec treats zero as “no maximum distance”).
AL_MIN_GAIN = 0.0 (allows silence at extreme distances).
AL_MAX_GAIN = 1.0 (full volume at the reference distance).
With AL_MAX_DISTANCE set to zero, the attenuation curve depends solely on the rolloff formula and the min/max gain clamps, which we have fixed to known values.
Verification Steps
- Create a mono buffer containing a steady tone (e.g., 440 Hz sine wave).
- Create a source, attach the buffer, and set the properties as listed above.
- Position the listener at the origin (
0,0,0) with default orientation.
- Place the source on the X‑axis at a series of distances:
1.0, 2.0, 5.0, 10.0, 20.0, 40.0 (or any range that covers the expected use case).
- For each position, render a short segment (e.g., 100 ms) and compute the RMS amplitude of the captured waveform.
- Normalize the RMS values by the value at
distance = AL_REFERENCE_DISTANCE (should be ≈1.0).
- Repeat the measurement on each target backend (OpenAL Soft, Creative driver, macOS OpenAL, etc.).
- Compare the normalized curves; they should match within a tolerance of ±0.01 (or another threshold appropriate for your application).
If the curves diverge, query the actual values after setting them:
alGetf(source, AL_REFERENCE_DISTANCE, &ref);
alGetf(source, AL_MAX_DISTANCE, &maxDist);
alGetf(source, AL_MIN_GAIN, &minGain);
alGetf(source, AL_MAX_GAIN, &maxGain);
Any discrepancy indicates that the driver clamped the value to its internal limits; adjust the requested value to stay within the driver’s reported range and repeat the test.
Missing Diagnostic Detail
To confirm that the observed differences are not caused by an unintended AL_MAX_DISTANCE clamp, please provide the maximum distance you intend to use in your application (or the farthest distance you test). Knowing this lets us verify that AL_MAX_DISTANCE = 0 truly disables the hard cutoff for your range, or whether a finite large value (e.g., 1000.0) is needed to avoid driver‑specific clamping.