Python implementation of the ISO 226:2023 standard for normal equal-loudness-level contours. This library provides formulas for converting between sound pressure levels (SPL) and loudness levels (phon) for pure tones.
The ISO 226:2023 standard defines equal-loudness-level contours that describe how human hearing perceives different frequencies at various loudness levels. This implementation provides:
- Conversion from loudness level (phon) to sound pressure level (dB)
- Conversion from sound pressure level (dB) to loudness level (phon)
- Generation of equal-loudness contours
- Calibration file generator for audio applications
- Python 3.6 or higher
- NumPy
pip install numpyClone this repository:
git clone https://github.com/GrigoryEvko/iso226-2023.git
cd iso226-2023from iso226_2023 import spl_from_loudness_level, loudness_level_from_spl
# Convert 60 phon at 1000 Hz to SPL
spl = spl_from_loudness_level(loudness_level=60, frequency=1000)
print(f"SPL: {spl:.2f} dB") # Output: SPL: 60.00 dB
# Convert 70 dB SPL at 100 Hz to loudness level
loudness = loudness_level_from_spl(sound_pressure_level=70, frequency=100)
print(f"Loudness: {loudness:.2f} phon")
# Generate equal-loudness contour for 60 phon
from iso226_2023 import generate_equal_loudness_contour
frequencies, spls = generate_equal_loudness_contour(loudness_level=60)Both functions support NumPy arrays for batch processing:
import numpy as np
# Multiple frequencies at same loudness level
frequencies = np.array([100, 500, 1000, 2000, 5000])
spls = spl_from_loudness_level(60, frequencies)
# Multiple loudness levels at same frequency
loudness_levels = np.array([20, 40, 60, 80])
spls = spl_from_loudness_level(loudness_levels, 1000)The included script generates frequency-dependent calibration data for audio applications:
python generate_calibration.pyThis creates:
- Individual calibration files for each phon level (10-100 phon)
- CSV format files for easy import
- Summary file with all phon levels
- Statistics file with frequency response characteristics
- A-weighting comparison (based on 40 phon curve)
All files are generated in the calibration_files/ directory.
Calculate sound pressure level from loudness level (Formula 1 from ISO 226:2023).
Parameters:
loudness_level(float or array): Loudness level in phon- Valid range: 20-90 phon for 20-4000 Hz
- Valid range: 20-80 phon for 5000-12500 Hz
- Values below 20 phon are informative only
frequency(float or array): Frequency in Hz (20-12500 Hz)
Returns:
- Sound pressure level in dB (float or ndarray)
Calculate loudness level from sound pressure level (Formula 2 from ISO 226:2023).
Parameters:
sound_pressure_level(float or array): Sound pressure level in dBfrequency(float or array): Frequency in Hz (20-12500 Hz)
Returns:
- Loudness level in phon (float or ndarray)
Generate an equal-loudness-level contour for a given loudness level.
Parameters:
loudness_level(float): Loudness level in phonfrequencies(ndarray, optional): Array of frequencies in Hz. Defaults to standard 1/3 octave frequencies.
Returns:
- Tuple of (frequencies, sound_pressure_levels)
Get interpolated parameters (αf, LU, Tf) for a given frequency.
Parameters:
frequency(float): Frequency in Hz
Returns:
- Tuple of (alpha_f, l_u, t_f)
The implementation uses the 29 standard 1/3-octave frequencies defined in ISO 226:2023:
20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500 Hz
For frequencies between the standard values, logarithmic interpolation is used on all parameters (αf, LU, Tf).
All loudness levels are referenced to 1000 Hz, where loudness level in phon equals sound pressure level in dB.
The implementation follows ISO 226:2023 Formulas 1 and 2:
Formula 1 (SPL from loudness level):
Lf = (10/αf) · lg{(4×10⁻¹⁰)^(αr-αf) · [10^(αr·LN/10) - 10^(αr·Tr/10)] + 10^(αf·(Tf+LU)/10)} - LU
Formula 2 (Loudness level from SPL):
LN = (10/αr) · lg{[10^(αf·(Lf+LU)/10) - 10^(αf·(Tf+LU)/10)] / [(4×10⁻¹⁰)^(αr-αf)] + 10^(αr·Tr/10)}
Where:
αf= Exponent for loudness perception at frequency fαr= 0.300 (Reference exponent at 1000 Hz)LU= Magnitude of linear transfer function normalized at 1000 HzTf= Threshold of hearing at frequency fTr= 2.4 dB (Threshold of hearing at 1000 Hz)
- Loudness compensation: Apply frequency-dependent gain based on listening level
- Audio measurement: Convert between physical SPL and perceived loudness
- Psychoacoustic research: Study frequency-dependent hearing sensitivity
- A-weighting: The 40 phon curve approximates A-weighting filters
- Hearing test calibration: Generate reference contours for audiometry
- Music production: Understand frequency balance at different listening levels
The generated calibration files show how much adjustment (in dB) each frequency needs relative to 1000 Hz to maintain equal loudness:
- Positive values: Frequency needs MORE SPL than 1000 Hz (less sensitive)
- Negative values: Frequency needs LESS SPL than 1000 Hz (more sensitive)
- Low frequencies at quiet levels: At 20-30 phon, bass frequencies need significant boost (human hearing is less sensitive to bass at quiet levels)
- High loudness levels: At 70-90 phon, frequency response flattens (human hearing becomes more linear at loud levels)
- Maximum sensitivity: Around 1-4 kHz (minimal adjustment needed)
- A-weighting: Based on the inverse of the 40 phon curve
The implementation includes verification against ISO 226:2023 standard values:
python iso226_2023.pyThis runs validation tests including:
- Round-trip conversion accuracy at 1000 Hz
- Equal-loudness contour generation
- Hearing threshold verification (0 phon should equal Tf values)
iso226-2023/
├── iso226_2023.py # Core implementation
├── generate_calibration.py # Calibration file generator
├── calibration_files/ # Generated calibration data
│ ├── csv/ # CSV format files
│ ├── iso226_calibration_*phon.txt
│ ├── iso226_all_phons_summary.txt
│ ├── calibration_statistics.txt
│ └── aweighting_comparison.txt
├── README.md
└── .gitignore
This implementation strictly follows:
- ISO 226:2023 - Acoustics — Normal equal-loudness-level contours
ISO 226:2023 provides updated contours based on more recent research. The main changes include:
- Updated parameter tables
- Refined formulas for better accuracy
- Extended validity ranges
Contributions are welcome! Please feel free to submit issues or pull requests.
This implementation is provided as-is for research and educational purposes. Please refer to the ISO 226:2023 standard for the authoritative specification.
- ISO 226:2023 - Acoustics — Normal equal-loudness-level contours
- Fletcher, H., & Munson, W. A. (1933). "Loudness, its definition, measurement and calculation". Journal of the Acoustical Society of America.
- Robinson, D. W., & Dadson, R. S. (1956). "A re-determination of the equal-loudness relations for pure tones". British Journal of Applied Physics.
Grigory Evko
Thanks to the ISO TC 43/SC 1 committee for developing and maintaining the ISO 226 standard.