Skip to content

Commit 866e413

Browse files
Make float to int conversion consistent
This ensures rounding is handled properly. This also fixes a bug where 1.0 would be mapped to 32768 and converted back as -1
1 parent c5985de commit 866e413

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

precise/util.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,24 @@ def chunk_audio(audio: np.ndarray, chunk_size: int) -> Generator[np.ndarray, Non
3232
yield audio[i - chunk_size:i]
3333

3434

35+
def float_audio_to_int(audio: np.ndarray) -> np.ndarray:
36+
"""Converts [-1.0, 1.0] -> [-32768, 32767]"""
37+
return (audio.astype(np.float32, order='C') * (0x7FFF + 0.5) - 0.5).astype('<i2')
38+
39+
40+
def int_audio_to_float(int_audio: np.ndarray) -> np.ndarray:
41+
"""Converts [-32768, 32767] -> [-1.0, 1.0]"""
42+
return (int_audio + 0.5) / (0x7FFF + 0.5)
43+
44+
3545
def buffer_to_audio(buffer: bytes) -> np.ndarray:
3646
"""Convert a raw mono audio byte string to numpy array of floats"""
37-
return np.fromstring(buffer, dtype='<i2').astype(np.float32, order='C') / 32768.0
47+
return int_audio_to_float(np.frombuffer(buffer, dtype='<i2'))
3848

3949

4050
def audio_to_buffer(audio: np.ndarray) -> bytes:
4151
"""Convert a numpy array of floats to raw mono audio"""
42-
return (audio * 32768).astype('<i2').tostring()
52+
return float_audio_to_int(audio).tostring()
4353

4454

4555
def load_audio(file: Any) -> np.ndarray:
@@ -61,15 +71,14 @@ def load_audio(file: Any) -> np.ndarray:
6171
if wav.rate != pr.sample_rate:
6272
raise InvalidAudio('Unsupported sample rate: ' + str(wav.rate))
6373

64-
data = np.squeeze(wav.data)
65-
return data.astype(np.float32) / float(np.iinfo(data.dtype).max)
74+
return int_audio_to_float(np.squeeze(wav.data))
6675

6776

6877
def save_audio(filename: str, audio: np.ndarray):
6978
"""Save loaded audio to file using the configured audio parameters"""
7079
import wavio
71-
save_audio = (audio * np.iinfo(np.int16).max).astype(np.int16)
72-
wavio.write(filename, save_audio, pr.sample_rate, sampwidth=pr.sample_depth, scale='none')
80+
int_audio = float_audio_to_int(audio)
81+
wavio.write(filename, int_audio, pr.sample_rate, sampwidth=pr.sample_depth, scale='none')
7382

7483

7584
def play_audio(filename: str):

0 commit comments

Comments
 (0)