GitHunt
ML

mlotinga/sottek-hearing-model

An implementation of the Sottek Hearing Model psychoacoustic sound quality metrics defined in ECMA-418-2.

sottek-hearing-model

sottek-hearing-model

PyPI version
License

An implementation of the psychoacoustic sound quality metrics from the Sottek Hearing Model defined in ECMA-418-2.

How to install

The package can be installed with pip:

pip install sottek-hearing-model

How to use

After installing, the package functions can be imported as follows:

from sottek_hearing_model import (shm_tonality_ecma,
                                  shm_loudness_ecma,
                                  shm_roughness_ecma)

or (since the package currently comprises a small number of functions):

from sottek_hearing_model import *

The functions can be used to analyse 1- or 2-channel audio signals, for example:

import soundfile as sf
from sottek_hearing_model import shm_tonality_ecma

audiodata, samplerate = sf.read('your_audio_file.wav')

tonality = shm_tonality_ecma(p=audiodata, samp_rate_in=samplerate,
                             axis=0, soundfield='free_frontal',
                             out_plot=True)

The above code will import the audio file, analyse it using the Sottek Hearing Model tonality metric, and output the results into a dict object tonality, as well as produce a figure plotting the results (out_plot=True).

By default, a progress bar is displayed illustrating the analysis computation progression. When analysing a batch of files, you may want to suppress this using wait_bar=False, as well as omit output plotting (the default setting is out_plot=False).

For more information on input arguments and output objects, use the help docstrings.

Since the Sottek Hearing Model loudness metric uses the tonal and noise loudness components that are generated using the tonality algorithms, a convenience function, shm_loudness_ecma_from_comp() is provided, which reduces the loudness computation time to negligible when also calculating the tonality metric. The use of this convenience function is demonstrated in the next example below. When using this convenience function, the soundfield type cannot be specified, as this is inherited from the component loudnesses. (Similarly, the A-weighted time-averaged sound level will not be displayed on the corresponding plots, as the sound pressure audio signal is not available to the convenience function to determine this.)

The corresponding reference signals for each metric, which are used for calibration and testing, can be generated and analysed as follows (which also demonstrates the shm_loudness_ecma_from_comp() convenience function):

from sottek_hearing_model import *

(sine_1kHz_40dB,
 sine_1kHz_70Hz_60dB,
 sine_1kHz_4Hz_60dB) = shm_generate_ref_signals(signal_duration=10)

tonality = shm_tonality_ecma(p=sine_1kHz_40dB,
                             samp_rate_in=48e3,
                             soundfield='free_frontal',
                             out_plot=True)

loudness = shm_loudness_ecma_from_comp(tonality['spec_tonal_loudness'],
                                       tonality['spec_noise_loudness'],
                                       out_plot=True)

roughness = shm_roughness_ecma(p=sine_1kHz_70Hz_60dB,
                               samp_rate_in=48e3,
                               soundfield='free_frontal',
                               out_plot=True)

The third reference signal generated above (sine_1kHz_4Hz_60dB) corresponds with the fluctuation strength metric. This metric will be added to the package in a future release.

By default, the functions make use of available parallel processing resources for efficient calculations. For user control of this feature, or if memory overflow issues are encountered (see issue #2), parallel processing can be disabled or controlled using the input argument parallel_cores. Setting parallel_cores=1 will disable parallel processing, while setting parallel_cores to another positive integer value will set the processing to use the specified number of parallel workers (to avoid system freeze, in a multicore system, the number actually used is always capped by the number of available cores minus 1). The default behaviour calculates the number of parallel workers to use from the available CPU cores.

The shm_tonality_ecma function also features a 'tonal annoyance weighting' option via the argument annoy_weight=True, which implements the weighting proposed in:

Sottek, R & Becker, J (2019). Tonal annoyance vs. tonal loudness and tonality. In: Proceedings of Inter-noise 2019, Madrid, Spain, 13-16 June 2019.

(This feature is considered experimental at present.)

Known issues

Memory limitations

The signal duration that can be processed is limited by user RAM, since the whole signal is loaded for processing at once, and the algorithms create multi-dimensional arrays for efficiency in calculation. For longer signals, or on systems with relatively small RAM allocation, memory overflows might occur. The parallel_cores argument can be used to reduce the concurrent memory demand on the system. Very long signals may need to be analysed in discrete segments.

How to cite

The algorithms in this package were initially translated to Python from the MATLAB codes published alongside the following paper:

Lotinga, M. J. B., Torjussen, M., & Felix Greco, G. (2025). Verified implementations of the Sottek psychoacoustic Hearing Model standardised sound quality metrics (ECMA-418-2 loudness, tonality and roughness). Proceedings of Forum Acusticum / Euronoise, Malaga, Spain, 23–26 June 2025. https://www.researchgate.net/publication/392904348

BibTeX:

@inproceedings{Lotinga2025Verified,
   author = {Lotinga, Michael J. B. and Torjussen, Matt and Felix Greco, G.},
   title = {{Verified implementations of the Sottek psychoacoustic Hearing Model standardised sound quality metrics (ECMA-418-2 loudness, tonality and roughness)}},
   booktitle = {Proceedings of Forum Acusticum / Euronoise 2025},
   publisher = {European Acoustics Association},
   url = {https://www.researchgate.net/publication/392904348},
   year = {2025},
   howpublished = {Forum Acusticum / Euronoise, Malaga, Spain, 23--26 June 2025}
}

Acknowledgements

This package was developed during research undertaken as part of the RefMap project (https://www.refmap.eu), funded by UK Research and Innovation / EU HORIZON (grant 10061935).

These implementations first originated in a MATLAB code SottekTonality.m authored by Matt Torjussen, which implemented the ECMA-418-2:2020 tonality algorithms. The code was developed and amended by Mike Lotinga (with permission), who later incorporated the loudness and roughness metrics, undertook verification confirmation, and organised the functions into a software package. Gil Felix Greco contributed further verification testing routines that led to improvement of the accuracy of the metrics.

The MATLAB implementations are also available as part of SQAT (Sound Quality Analysis Toolbox): https://github.com/ggrecow/SQAT.

Thanks are due to Professor Roland Sottek for developing the Hearing Model, and for helpfully answering queries about it.

Licensing

This work is licensed under the copyleft GNU General Public License v3.

Contact

If you would like to report a bug, make suggested improvements or ask a question, please open an issue on GitHub. If you would like to contribute, you could raise a pull request. For anything else, please contact Mike Lotinga (https://github.com/mlotinga).

Languages

Python100.0%

Contributors

GNU General Public License v3.0
Created September 3, 2025
Updated March 14, 2026
mlotinga/sottek-hearing-model | GitHunt