From 7e45aa6bbdb7cd3fa3c3f3d2875fae3626fee4ed Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 30 Jul 2025 17:10:51 +0530 Subject: [PATCH] Normalize audio output --- src/calibre/utils/tts/piper.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/calibre/utils/tts/piper.cpp b/src/calibre/utils/tts/piper.cpp index 02d73dc77b..85e797f320 100644 --- a/src/calibre/utils/tts/piper.cpp +++ b/src/calibre/utils/tts/piper.cpp @@ -440,13 +440,23 @@ next(PyObject *self, PyObject *args) { PyObject *ans = NULL, *data = NULL; int num_of_silence_samples = 0; if (current_sentence_delay > 0) num_of_silence_samples = (int)(current_sample_rate * current_sentence_delay); + const float *normalized = audio_tensor_data; + if (num_samples) { + float maxval = std::abs(audio_tensor_data[0]), q; + for (int i = 1; i < num_samples; i++) if ((q = std::abs(audio_tensor_data[i])) > maxval) maxval = q; + if (maxval > 1e-8) { + float *temp = (float*)malloc(num_samples * sizeof(audio_tensor_data[0])); + for (int i = 0; i < num_samples; i++) temp[i] /= maxval; + normalized = temp; + } + } if (as_16bit_samples) { data = PyBytes_FromStringAndSize(NULL, sizeof(int16_t) * (num_samples + num_of_silence_samples)); if (data) { Py_BEGIN_ALLOW_THREADS; int16_t *x = (int16_t*)PyBytes_AS_STRING(data); for (int i = 0; i < num_samples; i++) { - x[i] = (int16_t)(std::max(-1.f, std::min(audio_tensor_data[i], 1.f)) * std::numeric_limits::max()); + x[i] = (int16_t)(audio_tensor_data[i] * std::numeric_limits::max()); } memset(x + num_samples, 0, num_of_silence_samples * sizeof(int16_t)); Py_END_ALLOW_THREADS; @@ -461,6 +471,7 @@ next(PyObject *self, PyObject *args) { Py_END_ALLOW_THREADS; } } + if (normalized != audio_tensor_data) free((void*)normalized); if (data) { ans = Py_BuildValue( "OiiO", data, num_samples, current_sample_rate, phoneme_id_queue.empty() ? Py_True : Py_False);