shithub: audio-stretch

Download patch

ref: 8dd33167aa615949f423c870d78415aa42b9afe6
parent: 38f9e022c7449058c12902f51218134baf807c95
author: qwx <qwx@sciops.net>
date: Wed Aug 6 07:05:35 EDT 2025

fix precision issues leading to truncated buffer when pitching up

--- a/stretch.c
+++ b/stretch.c
@@ -45,7 +45,7 @@
 struct stretch_cnxt {
     int num_chans, inbuff_samples, shortest, longest, tail, head, fast_mode;
     int16_t *inbuff, *calcbuff;
-    float outsamples_error;
+    double outsamples_error;
     uint32_t *results;
 
     struct stretch_cnxt *next;
@@ -138,12 +138,12 @@
  * maximum values that will be passed to stretch_samples().
  */
 
-int stretch_output_capacity (StretchHandle handle, int max_num_samples, float max_ratio)
+int stretch_output_capacity (StretchHandle handle, int max_num_samples, double max_ratio)
 {
     struct stretch_cnxt *cnxt = (struct stretch_cnxt *) handle;
     int max_period = cnxt->longest / cnxt->num_chans;
     int max_expected_samples;
-    float next_ratio;
+    double next_ratio;
 
 	next_ratio = 0.0;
     if (cnxt->next) {
@@ -184,12 +184,12 @@
  * multiply the return value by the number channels!
  */
 
-int stretch_samples (StretchHandle handle, const int16_t *samples, int num_samples, int16_t *output, float ratio)
+int stretch_samples (StretchHandle handle, const int16_t *samples, int num_samples, int16_t *output, double ratio)
 {
     struct stretch_cnxt *cnxt = (struct stretch_cnxt *) handle;
     int out_samples = 0, next_samples = 0;
     int16_t *outbuf = output;
-    float next_ratio;
+    double next_ratio;
 
     /* if there's a cascaded instance after this one, try to do as much of the ratio here and the rest in "next" */
 
@@ -237,7 +237,7 @@
         /* while there are enough samples to process (3 or 4 times the longest period), do so */
 
         while (cnxt->tail >= cnxt->longest && cnxt->head - cnxt->tail >= cnxt->longest * (cnxt->fast_mode ? 3 : 2)) {
-            float process_ratio;
+            double process_ratio;
             int period;
 
             if (ratio != 1.0 || cnxt->outsamples_error)
--- a/stretch.h
+++ b/stretch.h
@@ -35,8 +35,8 @@
 typedef void *StretchHandle;
 
 StretchHandle stretch_init (int shortest_period, int longest_period, int num_chans, int flags);
-int stretch_output_capacity (StretchHandle handle, int max_num_samples, float max_ratio);
-int stretch_samples (StretchHandle handle, const int16_t *samples, int num_samples, int16_t *output, float ratio);
+int stretch_output_capacity (StretchHandle handle, int max_num_samples, double max_ratio);
+int stretch_samples (StretchHandle handle, const int16_t *samples, int num_samples, int16_t *output, double ratio);
 int stretch_flush (StretchHandle handle, int16_t *output);
 void stretch_reset (StretchHandle handle);
 void stretch_deinit (StretchHandle handle);
--- a/this.c
+++ b/this.c
@@ -54,8 +54,7 @@
 	char *r;
 	s16int *prebuf, *ibuf, *obuf;
 	u32int insamp, outsamp;
-	float max_ratio;
-	double level, ratio, gap, smin;
+	double level, ratio, max_ratio, gap, smin;
 	StretchHandle S;
 
 	fd = 0;
--