Skip to content

Commit

Permalink
Merge pull request #15 from mglesser/master
Browse files Browse the repository at this point in the history
Test architecture rework + update of doc + small bug fixes
  • Loading branch information
mglesser authored Aug 13, 2021
2 parents 92a5d53 + 6100568 commit 696520e
Show file tree
Hide file tree
Showing 212 changed files with 207 additions and 158 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
__pycache__/
.pytest_cache/
.vscode/
.ipynb_checkpoints/
.ipynb_checkpoints/
tests/output
2 changes: 1 addition & 1 deletion documentation/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ For the users that would like to use MOSQITO independently, a scripting interfac
Each function in the function library shall come with:
- a documentation presenting the sources used for the implementation and showing how the implementation is validated (in the [documentation folder](.))
- a tutorial (in the [tutorial folder](../tutorials))
- a unit test (in the [tests folder](../mosqito/tests))
- a unit test (in the [tests folder](../tests))

The scripting interface, relies upon an object oriented approach. All operations on audio signals are managed through the Audio class and its methods.
16 changes: 8 additions & 8 deletions documentation/loudness-stationary.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,33 @@ In MOSQITO, the code is based on the BASIC program published in Zwicker and Fast
### Validation of the implementation
The ISO 532-1:2017 standard provides a set of synthetic and technical signals covering representative applications to be used to validate any of its implementation. The standards also provides the compliance requirements.

The test signal n°1 (annex B2 of the standard) provides third octave levels to be used as input for stationary loudness calculation. A step by step description of how to use MOSQITO to calculate the loudness and the specific loudness from this input is given in [tutorial n°1](../tutorials/tuto1_Loudness-zwicker-from-3oct.ipynb).
The test signal n°1 (annex B2 of the standard) provides third octave levels to be used as input for stationary loudness calculation.

The test signals n°2 to 5 (annex B3 of the standard) provides .wav files to be used as input for stationary loudness calculation. A step by step description of how to use MOSQITO to calculate the loudness and the specific loudness from signal n°3 is given in [tutorial n°2](../tutorials/tuto2_Loudness-zwicker-from-wav.ipynb).
The test signals n°2 to 5 (annex B3 of the standard) provides .wav files to be used as input for stationary loudness calculation. A step by step description of how to use MOSQITO to calculate the loudness and the specific loudness from signal n°3 is given in [this tutorial](../tutorials/tuto_loudness.ipynb).

The plots below compares the MOSQITO loudness calculations for all the tests signals to the compliance requirements of the standards.

![](../mosqito/validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_1.png)
![](../validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_1.png)

*Loudness calculation for ISO 532-1 test signal n°1 (machinery noise in free field)*

![](../mosqito/validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_2_(250_Hz_80_dB).png)
![](../validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_2_(250_Hz_80_dB).png)

*Loudness calculation for ISO 532-1 test signal n°2 (250 Hz tone in free field with a level of 80 dB)*

![](../mosqito/validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_3_(1_kHz_60_dB).png)
![](../validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_3_(1_kHz_60_dB).png)

*Loudness calculation for ISO 532-1 test signal n°3 (1 kHz tone in free field with a level of 60 dB)*

![](../mosqito/validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_4_(4_kHz_40_dB).png)
![](../validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_4_(4_kHz_40_dB).png)

*Loudness calculation for ISO 532-1 test signal n°4 (4 kHz tone in free field with a level of 40 dB)*

![](../mosqito/validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_5_(pinknoise_60_dB).png)
![](../validations/loudness_zwicker/output/validation_loudness_zwicker_stationary_Test_signal_5_(pinknoise_60_dB).png)

*Loudness calculation for ISO 532-1 test signal n°5 (pink noise in free field with an overall level of 60 dB)*

*All the validation plots and scripts can be found in [this folder](../mosqito/validations/loudness_zwicker).*
*All the validation plots and scripts can be found in [this folder](../validations/loudness_zwicker).*

### References

Expand Down
14 changes: 7 additions & 7 deletions documentation/loudness-time-varying.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ The acoustic loudness calculation according to Zwicker method was initially intr
In MOSQITO, the code is based on the C++ program published with ISO 532-1:2017.

### Validation of the implementation
The ISO 532-1:2017 standard provides a set of synthetic and technical signals covering representative applications to be used to validate any of its implementation. The standards also provides the compliance requirements. A step by step description of how to use MOSQITO to calculate the loudness and the specific loudness from a .wav file is given in [tutorial n°3](./tuto3_Loudness-zwicker-time-varying.ipynb).
The ISO 532-1:2017 standard provides a set of synthetic and technical signals covering representative applications to be used to validate any of its implementation. The standards also provides the compliance requirements. A step by step description of how to use MOSQITO to calculate the loudness and the specific loudness from a .wav file is given in [this tutorial](../tutorials/tuto_loudness.ipynb).

Annex B4 of the standard provides .wav files of synthetic signals to be used as input for time-varying loudness calculation. The plots below compare the MOSQITO loudness calculations for the test signal n°6 to the compliance requirements of the standards. MOSQITO implementation passes successfully the 8 tests from annex B4 (all compliance plots can be found in the [tests/loudness/output folder](../mosqito/tests/loudness/output)).
Annex B4 of the standard provides .wav files of synthetic signals to be used as input for time-varying loudness calculation. The plots below compare the MOSQITO loudness calculations for the test signal n°6 to the compliance requirements of the standards. MOSQITO implementation passes successfully the 8 tests from annex B4 (all compliance plots can be found in [this folder](../tests/loudness/output)).

![](../mosqito/validations/loudness_zwicker/output/validation_loudness_zwicker_time_Test_signal_6_(tone_250_Hz_30_dB_-_80_dB)_Loudness.png)
![](../mosqito/validations/loudness_zwicker/output/validation_loudness_zwicker_time_Test_signal_6_(tone_250_Hz_30_dB_-_80_dB)_Specific.png)
![](../validations/loudness_zwicker/output/validation_loudness_zwicker_time_Test_signal_6_(tone_250_Hz_30_dB_-_80_dB)_Loudness.png)
![](../validations/loudness_zwicker/output/validation_loudness_zwicker_time_Test_signal_6_(tone_250_Hz_30_dB_-_80_dB)_Specific.png)

*Loudness calculation for ISO 532-1 test signal n°6 (A 250 Hz tone with a time-varying sound pressure level starting with 30 dB and increasing linearly to 80 dB). Top: overall loudness, Bottom: specific loudness at 2.5 Barks*

Annex B5 of the standard provides .wav files of technical signals to be used as input for time-varying loudness calculation. The plot below compares the MOSQITO loudness calculations for the test signal n°14 to the compliance requirements of the standards. MOSQITO implementation passes successfully 11 tests over the 12 from annex B4 (all compliance plots can be found in [this folder](../mosqito/validations/loudness_zwicker/output)).
Annex B5 of the standard provides .wav files of technical signals to be used as input for time-varying loudness calculation. The plot below compares the MOSQITO loudness calculations for the test signal n°14 to the compliance requirements of the standards. MOSQITO implementation passes successfully 11 tests over the 12 from annex B4 (all compliance plots can be found in [this folder](../tests/loudness/output)).

![](../mosqito/validations/loudness_zwicker/output/validation_loudness_zwicker_time_Test_signal_14_(propeller-driven_airplane)_Loudness.png)
![](../validations/loudness_zwicker/output/validation_loudness_zwicker_time_Test_signal_14_(propeller-driven_airplane)_Loudness.png)

*Loudness calculation for ISO 532-1 test signal n°14 (Propeller-driven airplane noise)*

The test on signal 16 fails because the 5% tolerance limit is exceeded for more than 1% of the time at the end of the signal, during the decay from hairdryer noise to silence (see figure below). This issue is currently under investigation.

![](../mosqito/validations/loudness_zwicker/output/FAILED_validation_loudness_zwicker_time_Test_signal_16_(hairdryer)_Loudness.png)
![](../validations/loudness_zwicker/output/FAILED_validation_loudness_zwicker_time_Test_signal_16_(hairdryer)_Loudness.png)

*Loudness calculation for ISO 532-1 test signal n°14 (Hairdryer noise)*

Expand Down
1 change: 1 addition & 0 deletions documentation/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ In this folder, you will find the documentation and validation of the different

## Generalities

- [Scope of the project](./scope.md)
- [Architecture of the toolbox](./architecture.md)

## Sound Quality metrics
Expand Down
8 changes: 4 additions & 4 deletions documentation/roughness.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
Several models have been developed to calculate the acoustic roughness, but there is no official standardization yet.

In MOSQITO, the code is based on the algorithm described in Daniel and Weber, 1997.
A step by step description of how to use MOSQITO to calculate the roughness is given in [tutorial n°6](../tutorials/tuto6_Roughness-from-wav.ipynb)
A step by step description of how to use MOSQITO to calculate the roughness is given in [this tutorial](../tutorials/tuto_roughness.ipynb)

### Validation of the implementation

H.Fastl and E.Zwicker proposed some reference values for the roughness of amplitude-modulated tones in figure 11.2 of Zwicker and Fastl, 2007.

In Mosqito the test AM tones are generated using the '[test_signal_generation](../mosqito/tests/roughness/test_signal_generation.py)' script, in accordance with the equation (1) from the Daniel and Weber article.
In Mosqito the test AM tones are generated using the '[signals_test_generation](../tests/roughness/signals_test_generation.py)' script, in accordance with the equation (1) from the Daniel and Weber article.

The plot below compare different roughness implementations' results for amplitude-modulated tones (carrier frequency of 250, 1000, 4000 Hz and modulation frequency from 10 to 400 Hz):
- Daniel and Weber implementation described in the 1997 article (results from figure 3)
Expand All @@ -21,10 +21,10 @@ The plot below compare different roughness implementations' results for amplitud

Mosqito implementation give similar results as other implementations. Zwicker and Fastl recommand that any roughness calculation should give results within a +/- 17% range around their reference values. Note that none of the 3 implementations respect this criteria. However, Daniel and Weber algorithm is considered as a reference. Any improvement of the roughness assessment is welcome to be implemented in Mosqito.

![](../mosqito/validations/roughness_danielweber/roughness_implementations_comparison.png)
![](../validations/roughness_danielweber/roughness_implementations_comparison.png)


*All the plots and scripts for more detailed validation can be found in [this folder](../mosqito/validations/roughness_danielweber).*
*All the plots and scripts for more detailed validation can be found in [this folder](../validations/roughness_danielweber).*


### References
Expand Down
52 changes: 52 additions & 0 deletions documentation/scope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Scope of the project

## Sound quality metrics
The scope of the project is to implement the following first set of
metrics:

| | Reference | Validated | Available | Under dev. | To do |
|:-------------------------------------------------- |:---------------------------------------------------- |:--------------------------------------------------:|:---------------------------------------------:|:----------:|:-----:|
| Loudness for<br>steady signals<br>(Zwicker method) | ISO 532B:1975<br>DIN 45631:1991<br>ISO 532-1:2017 §5 | [x](./mosqito/validations/loudness_zwicker/output) | [x](./documentation/loudness-stationary.md) | | |
| Loudness for non-stationary<br>(Zwicker method) | DIN 45631/A1:2010<br>ISO 532-1:2017 §6 | [x](./mosqito/validations/loudness_zwicker/output) | [x](./documentation/loudness-time-varying.md) | | |
| Loudness for non-stationary<br>(ECMA-74 method) | ECMA-74:2019, annex F<br>Sottek, 2016 | | | x | |
| Roughness | Daniel and Weber, 1997 | [x](./mosqito/validations/roughness_danielweber) | [x](./documentation/roughness.md) | | |
| Roughness | ECMA-418-2:2020 | | | | x |
| Fluctuation Strength | To be defined | | | | x |
| Sharpness | DIN 45692:2009 | [x](./mosqito/validations/sharpness/output) | [x](./documentation/sharpness.md) | | |
| Tonality (Hearing model) | ECMA-74:2019 annex G | | | x | |

As a second priority, the project could address the following metrics:

| | Reference | Validated | Available | Under dev. | To do |
|:----------------------------------------------------------------------------------- |:------------------------------------- |:---------:|:---------:|:----------:|:-----:|
| Loudness for steady signals<br>(Moore/Glasberg method) | ISO 532-2:2017 | | | | x |
| Loudness for non-stationary<br>(Moore/Glasberg method) | Moore, 2014 | | | | x |
| Sharpness (using <br>Moore/Glasberg loudness) | Hales-Swift<br>and Gee, 2017 | | | | x |
| Tone-to-noise ratio / Prominence <br> ratio (occupational noise,<br>discrete tones) | ECMA-74:2019 annex D<br>ISO 7719:2018 | | x | | |
| Tone-to-noise ratio<br>(environmental noise,<br>automatic tone detection) | DIN 45681 | | | | x |
| Tone-to-noise ratio<br>(environmental noise) | ISO 1996-2 | | | | x |
| Tone-to-noise ratio<br>(environmental noise) | ANSI S1.13:2005 | | | | x |


## Other SQ tools
In parallel, tools for signal listening and manipulation will be
developed. The objective is to be able to apply some modification to a
signal (filtering, tone removal, etc.) and assess the impact on
different SQ metrics. The integration of tools to define jury tests and
analyze the results is also planned.

Of course, any other sound quality related implementation by anyone who
wants to contribute is welcome.

## References

Daniel, P., and Weber, R. (1997). “Psychoacoustical Roughness: Implementation
of an Optimized Model”, Acta Acustica, Vol. 83: 113-123

Hales Swift, S., and Gee, K. L. (2017). “Extending sharpness calculation
for an alternative loudness metric input,” J. Acoust. Soc. Am.142,
EL549.

Moore, B. C. J. et al. (2016) ‘A Loudness Model for Time-Varying Sounds Incorporating Binaural Inhibition’, Trends in Hearing. [doi: 10.1177/2331216516682698](https://doi.org/10.1177/2331216516682698).

Sottek, R. (2016) A Hearing Model Approach to Time-Varying Loudness, Acta Acustica united with Acustica, vol. 102, no. 4, pp. 725-744.
6 changes: 3 additions & 3 deletions documentation/sharpness.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ The code is based on the version of the standard published in 2009 and the loudn

The DIN 45692:2009 standard provides a set of synthetic and technical signals covering representative applications to be used to validate any of its implementation. The standards also provides the compliance requirements for a set of broad-band noises and narrow-band noises. The sharpness is calculated by mosqito for the 20 broad-band signals and for the 21 narrow-band signals filtered with different center frequencies provided with the standard. The results are compared to the requirements in the figures below.

![](../mosqito/validations/sharpness/output/validation_sharpness_Broad-band_noise.png)
![](../validations/sharpness/output/validation_sharpness_Broad-band_noise.png)

![](../mosqito/validations/sharpness/output/validation_sharpness_Narrow-band_noise.png)
![](../validations/sharpness/output/validation_sharpness_Narrow-band_noise.png)

*The validation plots and scripts can be found in [this folder](../mosqito/validations/sharpness).*
*The validation plots and scripts can be found in [this folder](../validations/sharpness).*

## Sharpness of stationary and time-varying signals (other methods)

Expand Down
10 changes: 9 additions & 1 deletion mosqito/functions/oct3filter/oct3spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from mosqito.functions.oct3filter.oct3level import oct3level


def oct3spec(sig, fs, fc_min=20, fc_max=20000, sig_type="stationary", dec_factor=24):
def oct3spec(sig, fs, fc_min=25, fc_max=12500, sig_type="stationary", dec_factor=24):
"""Calculate third-octave band spectrum
Calculate the rms level of the signal "sig" sampled at freqency "fs"
Expand Down Expand Up @@ -55,6 +55,8 @@ def oct3spec(sig, fs, fc_min=20, fc_max=20000, sig_type="stationary", dec_factor
# Définition of the range of preferred filter center frequency
fpref = np.array(
[
16,
20,
25,
31.5,
40,
Expand Down Expand Up @@ -83,11 +85,15 @@ def oct3spec(sig, fs, fc_min=20, fc_max=20000, sig_type="stationary", dec_factor
8000,
10000,
12500,
16000,
20000,
]
)

fexact = np.array(
[
15.849,
19.953,
25.119,
31.623,
39.811,
Expand Down Expand Up @@ -116,6 +122,8 @@ def oct3spec(sig, fs, fc_min=20, fc_max=20000, sig_type="stationary", dec_factor
7943,
10000,
12589,
15849,
19953,
]
)

Expand Down
4 changes: 3 additions & 1 deletion mosqito/functions/shared/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ def load(is_stationary, file, calib=1, mat_signal="", mat_fs=""):
signal = calib * signal / (2 ** 15 - 1)
elif isinstance(signal[0], np.int32):
signal = calib * signal / (2 ** 31 - 1)
elif isinstance(signal[0], np.float):
signal = calib * signal

# load the .uff file content
elif file[-3:] == "uff" or file[-3:] == "UFF":
elif file[-3:].lower() == "uff" or file[-3:].lower() == "unv":
uff_file = pyuff.UFF(file)
data = uff_file.read_sets()
data.keys()
Expand Down
16 changes: 12 additions & 4 deletions mosqito/methods/Audio/comp_3oct_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,27 @@
from mosqito.functions.oct3filter.oct3spec import oct3spec


def comp_3oct_spec(self, unit="dB"):
def comp_3oct_spec(
self,
fc_min=25,
fc_max=12800,
):
"""Method to compute third-octave spectrum according to ISO
Parameter
---------
unit : string
'dB' or 'dBA'
fc_min : float
Filter center frequency of the lowest 1/3 oct. band [Hz]
fc_max : float
Filter center frequency of the highest 1/3 oct. band [Hz]
"""

# Compute third octave band spectrum
if self.is_stationary:
third_spec, freq_val = oct3spec(self.signal.values, self.fs)
third_spec, freq_val = oct3spec(
self.signal.values, self.fs, fc_min=fc_min, fc_max=fc_max
)
else:
third_spec, freq_val, time_val = calc_third_octave_levels(
self.signal.values, self.fs
Expand Down
Binary file removed mosqito/tests/Audio/output/test_comp_3oct_spec.png
Binary file not shown.
Binary file removed mosqito/tests/Audio/output/test_compute_loudness.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed mosqito/tests/Audio/output/test_import_signal.png
Binary file not shown.
Loading

0 comments on commit 696520e

Please sign in to comment.