Repository: audeering/audiofile

Issue:
Normalize argument ignored in convert_to_wav()
In https://github.com/audeering/audiofile/pull/99 we switched to use `audiofile.write()` inside `audiofile.convert_to_wav()` and added the `normalize` argument to `audiofile.convert_to_wav()`, but forgot to pass it on to `audiofile.write()`.

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/audeering/audiofile/pull/117?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=audeering) Report
> Merging [#117](https://codecov.io/gh/audeering/audiofile/pull/117?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=audeering) (28729f5) into [main](https://codecov.io/gh/audeering/audiofile/commit/e577593dde37e1abd269b15e75717b96973e1843?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=audeering) (e577593) will **not change** coverage.
> The diff coverage is `100.0%`.

| [Impacted Files](https://codecov.io/gh/audeering/audiofile/pull/117?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=audeering) | Coverage Δ | |
|---|---|---|
| [audiofile/core/io.py](https://codecov.io/gh/audeering/audiofile/pull/117?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=audeering#diff-YXVkaW9maWxlL2NvcmUvaW8ucHk=) | `100.0% <100.0%> (ø)` | |


Patch:
diff --git a/audiofile/core/io.py b/audiofile/core/io.py
index 562db86..7a42be9 100644
--- a/audiofile/core/io.py
+++ b/audiofile/core/io.py
@@ -100,7 +100,14 @@ def convert_to_wav(
         offset=offset,
         duration=duration,
     )
-    write(outfile, signal, sampling_rate, bit_depth=bit_depth, **kwargs)
+    write(
+        outfile,
+        signal,
+        sampling_rate,
+        bit_depth=bit_depth,
+        normalize=normalize,
+        **kwargs,
+    )
     return outfile
 
 


Test patch:
diff --git a/tests/test_audiofile.py b/tests/test_audiofile.py
index 1998970..14113e5 100644
--- a/tests/test_audiofile.py
+++ b/tests/test_audiofile.py
@@ -286,16 +286,19 @@ def test_broken_file(tmpdir, non_audio_file):
         af.convert_to_wav(non_audio_file, converted_file)
 
 
-@pytest.mark.parametrize("bit_depth", [8, 16, 24])
+@pytest.mark.parametrize('normalize', [False, True])
+@pytest.mark.parametrize('bit_depth', [8, 16, 24])
 @pytest.mark.parametrize(
     'file_extension',
     ('wav', 'flac', 'ogg', 'mp3'),
 )
-def test_convert_to_wav(tmpdir, bit_depth, file_extension):
+def test_convert_to_wav(tmpdir, normalize, bit_depth, file_extension):
     sampling_rate = 8000
     channels = 1
+    magnitude_offset = 0.5
     signal = sine(
         duration=0.1,
+        magnitude=1 - magnitude_offset,
         sampling_rate=sampling_rate,
         channels=channels,
     )
@@ -313,29 +316,58 @@ def test_convert_to_wav(tmpdir, bit_depth, file_extension):
             "or provide an 'outfile' argument."
         )
         with pytest.raises(RuntimeError, match=re.escape(error_msg)):
-            outfile = af.convert_to_wav(infile, bit_depth=bit_depth)
+            outfile = af.convert_to_wav(
+                infile,
+                bit_depth=bit_depth,
+                normalize=normalize,
+            )
         outfile = af.convert_to_wav(
             infile,
             bit_depth=bit_depth,
+            normalize=normalize,
             overwrite=True,
         )
     elif file_extension == 'mp3':
-        outfile = af.convert_to_wav(infile, bit_depth=bit_depth)
+        outfile = af.convert_to_wav(
+            infile,
+            bit_depth=bit_depth,
+            normalize=normalize,
+        )
     else:
         outfile = str(tmpdir.join('signal_converted.wav'))
-        af.convert_to_wav(infile, outfile, bit_depth=bit_depth)
+        af.convert_to_wav(
+            infile,
+            outfile,
+            bit_depth=bit_depth,
+            normalize=normalize,
+        )
     converted_signal, converted_sampling_rate = af.read(outfile)
     assert converted_sampling_rate == sampling_rate
+    if normalize:
+        # The actual maximum/minimum value can vary
+        # based on the used codec/format
+        assert converted_signal.max() > 0.95
+        assert converted_signal.max() <= 1.0
+        assert converted_signal.min() < -0.95
+        assert converted_signal.min() >= -1.0
     if file_extension == 'mp3':
         assert af.bit_depth(outfile) == bit_depth
         # Don't compare signals for MP3
         # as duration differs as well
-    elif file_extension == 'ogg':
+    else:
+        abs_difference = np.abs(converted_signal - signal).max()
+    if file_extension == 'ogg':
         assert af.bit_depth(outfile) == bit_depth
-        assert np.abs(converted_signal - signal).max() < 0.06
+        if normalize:
+            assert abs_difference < 0.06 + magnitude_offset
+        else:
+            assert abs_difference < 0.06
     elif file_extension in ['wav', 'flac']:
         assert af.bit_depth(outfile) == bit_depth
-        assert np.abs(converted_signal - signal).max() < tolerance(bit_depth)
+        if normalize:
+            assert abs_difference < tolerance(bit_depth) + magnitude_offset
+        else:
+            assert abs_difference < tolerance(bit_depth)
 
 
 @pytest.mark.parametrize("bit_depth", [8, 16, 24, 32])