shithub: audio-stretch

Download patch

ref: 90f421b2909e7131c1ce5403f671cfdc0fe80dc5
parent: 00913a41096f6590dd796df2300df7616c4acbe0
author: David Bryant <david@wavpack.com>
date: Sun Oct 2 12:32:55 EDT 2022

improve speed of "fast" mode (when stretch > 1.5X) by fully consuming each period pair

- note that this can generate more output for each call, so might require client change
- may slightly reduce subjective quality, so use "normal" mode if that's paramount

--- a/main.c
+++ b/main.c
@@ -338,7 +338,7 @@
     write_pcm_wav_header (outfile, 0, WaveHeader.NumChannels, 2, scaled_rate);
 
     short *inbuffer = malloc (BUFFER_SAMPLES * WaveHeader.BlockAlign);
-    short *outbuffer = malloc ((BUFFER_SAMPLES * 2 + max_period * 3) * WaveHeader.BlockAlign);
+    short *outbuffer = malloc ((BUFFER_SAMPLES * 2 + max_period * 4) * WaveHeader.BlockAlign);
 
     while (1) {
         int samples_read = fread (inbuffer, WaveHeader.BlockAlign,
--- a/stretch.c
+++ b/stretch.c
@@ -98,8 +98,8 @@
  * range 0.5 to 2.0). Note that the number of samples refers to total samples for
  * both channels in stereo and can be as large as desired (samples are buffered
  * here). The exact number of samples output is not possible to determine in
- * advance, but it will be close to the number of input samples times the ratio
- * plus or minus 3X the longest period.
+ * advance, but the maximum will be the number of input samples times the ratio
+ * plus 3X the longest period (or 4X the longest period in "fast" mode).
  */
 
 int stretch_samples (StretchHandle handle, const short *samples, int num_samples, short *output, float ratio)
@@ -133,7 +133,7 @@
 
         /* while there are enough samples to process, do so */
 
-        while (cnxt->tail >= cnxt->longest && cnxt->head - cnxt->tail >= cnxt->longest * 2) {
+        while (cnxt->tail >= cnxt->longest && cnxt->head - cnxt->tail >= cnxt->longest * (cnxt->fast_mode ? 3 : 2)) {
             int period = cnxt->fast_mode ? find_period_fast (cnxt, cnxt->inbuff + cnxt->tail) :
                 find_period (cnxt, cnxt->inbuff + cnxt->tail);
             float process_ratio;
@@ -183,6 +183,15 @@
                 cnxt->outsamples_error += (period * 2.0) - (period * ratio);
                 out_samples += period * 2;
                 cnxt->tail += period;
+
+                if (cnxt->fast_mode) {
+                    merge_blocks (output + out_samples, cnxt->inbuff + cnxt->tail,
+                        cnxt->inbuff + cnxt->tail - period, period * 2);
+
+                    cnxt->outsamples_error += (period * 2.0) - (period * ratio);
+                    out_samples += period * 2;
+                    cnxt->tail += period;
+                }
             }
             else
                 fprintf (stderr, "stretch_samples: fatal programming error: process_ratio == %g\n", process_ratio);