diff --git a/otherarch/acestep/dit-vae.cpp b/otherarch/acestep/dit-vae.cpp index c7260769e..ea8cc280f 100644 --- a/otherarch/acestep/dit-vae.cpp +++ b/otherarch/acestep/dit-vae.cpp @@ -992,7 +992,7 @@ std::string acestep_generate_audio(const music_generation_inputs inputs) finalb64 = save_stereo_wav16_base64(audio,T_audio,48000); } else { std::vector mono = mix_planar_stereo_to_mono(audio.data(), T_audio); - std::vector resampled_buf = resample_wav(mono,48000,32000); + std::vector resampled_buf = resample_wav(1,mono,48000,32000); finalb64 = save_wav16_base64(resampled_buf, 32000); } diff --git a/otherarch/utils.cpp b/otherarch/utils.cpp index 372d1c26e..80c072e58 100644 --- a/otherarch/utils.cpp +++ b/otherarch/utils.cpp @@ -383,33 +383,91 @@ std::vector> split_big_vector_in_two(const std::vector& bi return result; } -std::vector resample_wav(const std::vector & input, uint32_t input_rate, uint32_t output_rate) { - if (input.empty() || input_rate == 0 || output_rate == 0) +static double audio_resample_bessel_i0(double x) { + double sum = 1.0; + double term = 1.0; + double y = x * x * 0.25; + for (int k = 1; k < 30; k++) { + term *= y / ((double) k * (double) k); + sum += term; + if (term < sum * 1e-15) { + break; + } + } + return sum; +} + +std::vector resample_wav(int num_channels,const std::vector& input,uint32_t input_rate,uint32_t output_rate) +{ + if (input.empty() || num_channels <= 0 || input_rate == 0 || output_rate == 0) return {}; - const size_t input_size = input.size(); - const double ratio = static_cast(output_rate) / input_rate; // Compute resampling ratio - // Use rounding to avoid systematic truncation error - const size_t output_size = static_cast(std::llround(input_size * ratio)); - std::vector output(output_size); - const double step = static_cast(input_rate) / output_rate; // Precompute step in source domain - double src_pos = 0.0; - for (size_t i = 0; i < output_size; ++i) + if (input.size() % num_channels != 0) + return {}; + + const int n_in = input.size() / num_channels; + + if (input_rate == output_rate) + return input; + + const double ratio = (double)output_rate / (double)input_rate; + const int n_out = (int)std::lround(n_in * ratio); + + std::vector output((size_t)n_out * num_channels); + + const int half_len = 32; + const double beta = 9.0; + + const double inv_i0b = 1.0 / audio_resample_bessel_i0(beta); + const double fc = 0.5 * ((ratio < 1.0) ? ratio : 1.0); + + for (int ch = 0; ch < num_channels; ch++) { - size_t idx = static_cast(src_pos); - if (idx >= input_size - 1) // Clamp to valid range (prevents out-of-bounds) + const float* src = input.data() + ch * n_in; + float* dst = output.data() + ch * n_out; + + for (int i = 0; i < n_out; i++) { - output[i] = input[input_size - 1]; + double center = (double)i / ratio; + + int start = (int)std::floor(center) - half_len + 1; + int end = (int)std::floor(center) + half_len; + + double sum = 0.0; + double wgt = 0.0; + + for (int j = start; j <= end; j++) + { + double d = center - (double)j; + + double sinc_val; + if (std::fabs(d) < 1e-9) + sinc_val = 2.0 * fc; + else + sinc_val = std::sin(2.0 * M_PI * fc * d) / (M_PI * d); + + double t = d / (double)half_len; + + double win; + if (t < -1.0 || t > 1.0) + win = 0.0; + else + win = audio_resample_bessel_i0(beta * std::sqrt(1.0 - t * t)) * inv_i0b; + + double h = sinc_val * win; + + int idx = j; + if (idx < 0) idx = 0; + if (idx >= n_in) idx = n_in - 1; + + sum += src[idx] * h; + wgt += h; + } + + dst[i] = (wgt > 1e-12) ? (float)(sum / wgt) : 0.0f; } - else - { - const double frac = src_pos - idx; - const float s0 = input[idx]; - const float s1 = input[idx + 1]; - output[i] = static_cast(s0 + (s1 - s0) * frac); - } - src_pos += step; } + return output; } diff --git a/otherarch/utils.h b/otherarch/utils.h index 4482cc903..8292eaa44 100644 --- a/otherarch/utils.h +++ b/otherarch/utils.h @@ -64,7 +64,7 @@ std::string get_timestamp_str(); std::vector> split_big_vector(const std::vector& big_arr, size_t chunk_size); std::vector> split_big_vector_in_two(const std::vector& big_arr, size_t chunk_size); -std::vector resample_wav(const std::vector& input, uint32_t input_rate, uint32_t output_rate); +std::vector resample_wav(int num_channels,const std::vector& input, uint32_t input_rate, uint32_t output_rate); std::vector mix_planar_stereo_to_mono(const float* audio, int T_audio); int32_t kcpp_quick_sample(float * logits, const int n_logits, const std::vector & last_n_tokens, float rep_pen, float top_p, int top_k, float temp, std::mt19937 & rng);