diff src/sndstretch/sndstretch.c @ 881:6bb0e52df3d6 trunk

[svn] - Made port of XMMS plugin SndStretch
author mf0102
date Tue, 20 Mar 2007 12:22:25 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sndstretch/sndstretch.c	Tue Mar 20 12:22:25 2007 -0700
@@ -0,0 +1,1298 @@
+// sndstretch.c
+//
+//    sndstretch - algorithm for adjusting pitch and speed of s16le data
+//    Copyright (C) 2000  Florian Berger
+//    Email: florian.berger@jk.uni-linz.ac.at
+//
+//    This program is free software; you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License Version 2 as
+//    published by the Free Software Foundation;
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program; if not, write to the Free Software
+//    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+//
+
+//#define DEBUG
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<math.h>
+#include"sndstretch.h"
+
+
+static double _1_div_e     = 0.367879441;  // 1/e
+static double _1_m_1_div_e = 0.632120558;  // 1-1/e
+
+#define    RESMAX      65536
+#define    RESMAXVC    32768
+#define    LOG2RESMAX     16
+#define    LOG2RESMAXVC   15
+static int    _1_div_e_i     = 24109;  // 1/e   * 2^LOG2RESMAX
+static int    _1_m_1_div_e_i = 41427;  // 1-1/e * 2^LOG2RESMAX
+static int    _1_div_e_i_vc   = 12055;  // 1/e   * 2^LOG2RESMAXVC
+static int    _1_m_1_div_e_i_vc = 28333;  // sqrt(1-1/e^2) * 2^LOG2RESMAXVC
+//static int    _1_div_e_i     = 12055;  // 1/e   * 2^LOG2RESMAX
+//static int    _1_m_1_div_e_i = 20713;  // 1-1/e * 2^LOG2RESMAX
+
+
+void InitScaleJob( ScaleJob * job )
+{
+    /* nothing to do */
+}
+
+
+void InitStretchJob( StretchJob * job )
+{
+    job->is_initialized=0;
+    job->snr_rest=0.0;
+}
+
+
+void InitPitchSpeedJob( PitchSpeedJob * job )
+{
+    job->ring_buff = (s16*)0;        // init me = (s16*)0
+    job->ring_buff_old = (s16*)0;    // init me = (s16*)0
+    job->buff_help = (s16*)0;        // init me = (s16*)0
+    job->ring_size = 1;              // init me = 1
+    job->ring_size_old = 0;          // init me = 0
+    job->ring_pos_w = 0;             // init me = 0
+    job->ring_pos_r = 0;             // init me = 0
+    job->is_init = 0;                // init me = 0
+    job->speed_act = 0;              // init me = 0
+    job->pitch_act = 0;              // init me = 0
+    job->fade_shift_act = 0;
+    InitStretchJob(&(job->stretch_job));
+    InitScaleJob(&(job->scale_job));
+}
+
+
+
+void CleanupPitchSpeedJob( PitchSpeedJob * job )
+{
+    free(job->ring_buff);
+    free(job->ring_buff_old);
+    free(job->buff_help);
+}
+
+
+
+inline int ringpos( int pos, int size )
+{
+    while ( pos >= size ) pos-=size;
+    while ( pos <  0    ) pos+=size;
+    return( pos );
+}
+
+
+void ringload( s16 * ringbuff, int ring_size, int pos, s16 *buffer, int size )
+/* put <size> samples to ring with size <ring_size> on position <pos> */
+{
+    int i,j;
+
+    j=0;
+    if( pos+size > ring_size ){
+        for( i=pos; i<ring_size;          i++,j++ ) ringbuff[i]=buffer[j];
+        for( i=0;   i<size-ring_size+pos; i++,j++ ) ringbuff[i]=buffer[j];
+    }else{
+        for( i=pos; i<size+pos;           i++,j++ ) ringbuff[i]=buffer[j];
+    }
+}
+
+
+void ringcopy( s16 * src_ring,  int src_size,  int src_from, int src_to,
+               s16 * dest_ring, int dest_size, int dest_pos )
+{
+    int is,id;
+
+    is=src_from; id=dest_pos;
+    while( is!=src_to ){
+        dest_ring[id]=src_ring[is];
+        is=ringpos(is+1,src_size);
+        id=ringpos(id+1,dest_size);
+    }
+}
+
+
+void ringload_IIR_1_div_e_echo_d( s16 * ringbuff, int ring_size, int pos, s16 *buffer, int size , int delay)
+/* put <size> samples to ring with size <ring_size> on position <pos> */
+{
+    int i,p1,p2;
+
+    p1=pos, p2=ringpos(p1-delay, ring_size);
+    for( i=0; i<size; i++ ){
+        ringbuff[p1] =(s16)( (double)buffer[i]*_1_m_1_div_e + (double)ringbuff[p2]*_1_div_e );
+        p1++; if(p1>=ring_size) p1-=ring_size;
+        p2++; if(p2>=ring_size) p2-=ring_size;
+    }
+}
+
+
+void ringload_IIR_1_div_e_echo_i( s16 * ringbuff, int ring_size, int pos, s16 *buffer, int size , int delay)
+/* put <size> samples to ring with size <ring_size> on position <pos> */
+{
+    int i,p1,p2;
+
+    p1=pos, p2=ringpos(p1-delay, ring_size);
+    for( i=0; i<size; i++ ){
+        ringbuff[p1] =(s16)( (
+                              _1_m_1_div_e_i * buffer[i] +
+                              _1_div_e_i     * ringbuff[p2]
+                             ) >> LOG2RESMAX );
+        p1++; if(p1>=ring_size) p1-=ring_size;
+        p2++; if(p2>=ring_size) p2-=ring_size;
+    }
+}
+
+
+void ringload_IIR_1_div_e_echo_i_vc( s16 * ringbuff, int ring_size, int pos, s16 *buffer, int size , int delay)
+/* put <size> samples to ring with size <ring_size> on position <pos> */
+{
+    int i,p1,p2;
+    int actval;
+
+    p1=pos, p2=ringpos(p1-delay, ring_size);
+    for( i=0; i<size; i++ ){
+/*        ringbuff[p1] =(s16)( (
+                              _1_m_1_div_e_i_vc * buffer[i] +
+                              _1_div_e_i_vc     * ringbuff[p2]
+                             ) >> LOG2RESMAXVC );*/
+        actval = _1_m_1_div_e_i_vc * buffer[i] +
+                 _1_div_e_i_vc     * ringbuff[p2];
+        /* prevent overflow */
+        if( actval > (int)0x3FFFFFFF ) actval=(int)0x3FFFFFFF;
+        if( actval < (int)0xC0000000 ) actval=(int)0xC0000000;
+        ringbuff[p1] = actval >> LOG2RESMAXVC;
+        p1++; if(p1>=ring_size) p1-=ring_size;
+        p2++; if(p2>=ring_size) p2-=ring_size;
+    }
+}
+
+
+/*void ringget ( s16 * ringbuff, int ring_size, int pos, s16 *buffer, int size )
+{
+    int i;
+    
+    if( pos+size > ring_size ){
+        for( i=pos; i<ring_size;          i++ ) buffer[i]=ringbuff[i];
+        for( i=0;   i<size-ring_size+pos; i++ ) buffer[i]=ringbuff[i];
+    }else{
+        for( i=pos; i<size+pos;           i++ ) buffer[i]=ringbuff[i];
+    }
+}
+*/
+
+//int sndstretch( // not optimized
+int sndstretch_not_optimized(
+/* stretches the sound (not changing pitch !!!)                          */
+/* returns number of output samples produced                             */
+/* chnr simply gives multiples of chnr as snr_prod                       */
+           s16 * buffer, int buff_size,   /* ring buffer                    */
+           int pos_init,                  /* only initial pos in ringbuffer */
+           int snr_i, int snr_o,          /* enlarge - spec                 */
+           int chnr,                      /* # of channels                  */
+           s16 * outbuff,                 /* output                         */
+           int * out_prod,                /* # of output-samples produced   */
+           int snr_proc,                  /* # of in-samples to process     */
+           int initialize                 /* bool                           */
+          )
+{
+    static int     is_initialized=0;
+    static int     snr_o_prod;
+    static int     snr_i_act;
+    static int     snr_o_act;
+/*    static int     snr_offs; */
+    static int     pos_act;
+    static int     dsnr;
+/*    static int     p1,p2;    */
+    static double  snr_rest=0.0;
+
+    int            snr;
+    double         snr_d;
+    
+    int            i,p1,p2;
+    double         fade_in, fade_out;
+    double         outd;
+
+/*    s16 *          outbuff; */
+
+    /* reset */
+    if( !is_initialized || initialize ||
+        snr_i!=snr_i_act || snr_o!=snr_o_act ){
+        
+        snr_rest   = 0.0;
+        snr_o_prod = 0;
+        snr_i_act  = snr_i;
+        snr_o_act  = snr_o;
+        dsnr       = snr_o_act-snr_i_act;
+        pos_act    = pos_init;
+        
+        is_initialized = 1;
+
+    }
+    
+/*    fprintf(stderr,"pos_act=%d\n",pos_act);
+*/
+    snr_d      = (double)snr_proc*(double)snr_o_act/(double)snr_i_act
+                 + snr_rest;
+    snr        = (int) (snr_d) / 2 * 2;
+    snr_rest   = snr_d - (double)snr;
+    
+/*    fprintf(stderr,"snr=%d\n",snr);
+*/
+/*    outbuff=malloc(snr*sizeof(s16));
+*/
+    /* produce snr samples */
+    i=0;
+    do {
+        if( snr_o_prod == snr_o_act ) {
+            snr_o_prod=0;
+/*            fprintf(stderr,"!!!!!!!!!!!!!!!!!!!!!!!!!! dsnr = %d\n",dsnr);*/
+            pos_act = ringpos( pos_act-dsnr, buff_size );
+        }
+        for ( ; snr_o_prod < snr_o_act && i<snr ; snr_o_prod++,i++ ){
+            p1=pos_act;
+            p2=ringpos( p1-dsnr, buff_size );
+//            p3=ringpos( p2-dsnr, buff_size );
+//            p4=ringpos( p3-dsnr, buff_size );
+//            p2=ringpos( p1-abs(dsnr), buff_size );
+//            p3=ringpos( p2-abs(dsnr), buff_size );
+//            p4=ringpos( p3-abs(dsnr), buff_size );
+            fade_in  = (double)snr_o_prod/(double)snr_o_act;
+            fade_out = 1.0-fade_in;
+//            fade1 = (dsnr>0)?fade_out:fade_in;
+//            fade2 = (dsnr>0)?fade_in:fade_out;
+            outd = (
+                      (double)buffer[p1] * fade_out  /* fade out */
+                    + (double)buffer[p2] * fade_in   /* fade in  */
+//                    +( 0.67 * (double)buffer[p1]             /* fade out for lengthen */
+//                     + 0.24 * (double)buffer[p2]             /* fade out */
+//                     + 0.09 * (double)buffer[p3]) * fade_out /* fade out */
+//                    +( 0.67 * (double)buffer[p2]             /* fade in  */
+//                     + 0.24 * (double)buffer[p3]             /* fade in  */
+//                     + 0.09 * (double)buffer[p4]) * fade_in  /* fade in  */
+                   );
+            outbuff[i] = outd+0.5;
+            pos_act=ringpos( pos_act+1, buff_size );
+        }
+    } while( i<snr );
+
+/*    fwrite( outbuff, sizeof(s16), snr, stdout );
+*/
+/*    free(outbuff);
+*/
+    *out_prod = snr;
+
+/*    fprintf(stderr,"snr = %d\n",snr);
+*/
+    return( *out_prod );
+}
+
+
+int sndstretch( // optimized
+//int sndstretch_optimized( // optimized
+/* stretches the sound (not changing pitch !!!)                          */
+/* returns number of output samples produced                             */
+/* chnr simply gives multiples of chnr as snr_prod                       */
+           s16 * buffer, int buff_size,   /* ring buffer                    */
+           int pos_init,                  /* only initial pos in ringbuffer */
+           int snr_i, int snr_o,          /* enlarge - spec                 */
+           int chnr,                      /* # of channels                  */
+           s16 * outbuff,                 /* output                         */
+           int * out_prod,                /* # of output-samples produced   */
+           int snr_proc,                  /* # of in-samples to process     */
+           int initialize                 /* bool                           */
+          )
+{
+    static int     is_initialized=0;
+    static int     snr_o_prod;
+    static int     snr_i_act;
+    static int     snr_o_act;
+    static int     pos_act;
+    static int     dsnr;
+    static double  snr_rest=0.0;
+
+    static int     _RESMAX_div_max, _RESMAX_mod_max;
+    static int     fade_in_i, fade_out_i, fade_rest_i;
+
+    /* not necessarily static */
+    static int            snr;
+    static double         snr_d;
+    static int            i,p2;
+
+    /* reset */
+    if( !is_initialized || initialize ||
+        snr_i!=snr_i_act || snr_o!=snr_o_act ){
+        
+        snr_rest   = 0.0;
+        snr_o_prod = 0;
+        snr_i_act  = snr_i;
+        snr_o_act  = snr_o;
+        dsnr       = snr_o_act-snr_i_act;
+        pos_act    = pos_init;
+        
+        is_initialized = 1;
+
+    }
+    
+    snr_d      = (double)snr_proc*(double)snr_o_act/(double)snr_i_act
+                 + snr_rest;
+    snr        = (int) (snr_d) / 2 * 2;
+    snr_rest   = snr_d - (double)snr;
+    
+    /* produce snr samples */
+    i=0;
+    do {
+        if( snr_o_prod == snr_o_act ) {
+            snr_o_prod=0;
+            pos_act = ringpos( pos_act-dsnr, buff_size );
+        }
+        fade_in_i  = RESMAX*((double)snr_o_prod/(double)snr_o_act);
+        fade_out_i = RESMAX-fade_in_i;
+        fade_rest_i= (RESMAX*snr_o_prod)%snr_o_act;
+        _RESMAX_div_max=RESMAX/snr_o_act;
+        _RESMAX_mod_max=RESMAX%snr_o_act;
+        p2=ringpos( pos_act-dsnr, buff_size );
+        for ( ; snr_o_prod < snr_o_act && i<snr ; snr_o_prod++,i++ ){
+            fade_in_i  +=_RESMAX_div_max;
+            fade_out_i -=_RESMAX_div_max;
+            fade_rest_i+=_RESMAX_mod_max;
+            if(fade_rest_i>snr_o_act){
+                fade_rest_i-=snr_o_act;
+                fade_in_i++;
+                fade_out_i--;
+            }
+            outbuff[i] = (s16)( (
+                                 + (int)buffer[pos_act] * fade_out_i
+                                 + (int)buffer[p2]      * fade_in_i
+                                ) >> LOG2RESMAX );
+            pos_act++; if(pos_act>=buff_size) pos_act-=buff_size;
+            p2++;      if(p2     >=buff_size) p2     -=buff_size;
+        }
+    } while( i<snr );
+
+    *out_prod = snr;
+
+    return( *out_prod );
+}
+
+
+int sndstretch_job( // optimized
+//int sndstretch_optimized( // optimized
+/* stretches the sound (not changing pitch !!!)                          */
+/* returns number of output samples produced                             */
+/* chnr simply gives multiples of chnr as snr_prod                       */
+           s16 * buffer, int buff_size,   /* ring buffer                    */
+           int pos_init,                  /* only initial pos in ringbuffer */
+           int snr_i, int snr_o,          /* enlarge - spec                 */
+           int chnr,                      /* # of channels                  */
+           s16 * outbuff,                 /* output                         */
+           int * out_prod,                /* # of output-samples produced   */
+           int snr_proc,                  /* # of in-samples to process     */
+           int initialize,                 /* bool                           */
+           StretchJob * job
+          )
+{
+/*    static int     is_initialized=0;
+    static int     snr_o_prod;
+    static int     snr_i_act;
+    static int     snr_o_act;
+    static int     pos_act;
+    static int     dsnr;
+    static double  snr_rest=0.0;
+
+    static int     _RESMAX_div_max, _RESMAX_mod_max;
+    static int     fade_in_i, fade_out_i, fade_rest_i;*/
+
+    /* not necessarily static */
+    static int            snr;
+    static double         snr_d;
+    static int            i,p2;
+
+#define    is_initialized    (job->is_initialized )
+#define    snr_o_prod        (job->snr_o_prod     )
+#define    snr_i_act         (job->snr_i_act      )
+#define    snr_o_act         (job->snr_o_act      )
+#define    pos_act           (job->pos_act        )
+#define    dsnr              (job->dsnr           )
+#define    snr_rest          (job->snr_rest       )
+#define    _RESMAX_div_max   (job->_RESMAX_div_max)
+#define    _RESMAX_mod_max   (job->_RESMAX_mod_max)
+#define    fade_in_i         (job->fade_in_i      )
+#define    fade_out_i        (job->fade_out_i     )
+#define    fade_rest_i       (job->fade_rest_i    )
+
+    /* reset */
+    if( !is_initialized || initialize ||
+        snr_i!=snr_i_act || snr_o!=snr_o_act ){
+        
+        snr_rest   = 0.0;
+        snr_o_prod = 0;
+        snr_i_act  = snr_i;
+        snr_o_act  = snr_o;
+        dsnr       = snr_o_act-snr_i_act;
+        pos_act    = pos_init;
+        
+        is_initialized = 1;
+
+    }
+    
+    snr_d      = (double)snr_proc*(double)snr_o_act/(double)snr_i_act
+                 + snr_rest;
+    snr        = (int) (snr_d) / 2 * 2;
+    snr_rest   = snr_d - (double)snr;
+    
+    /* produce snr samples */
+    i=0;
+    do {
+        if( snr_o_prod == snr_o_act ) {
+            snr_o_prod=0;
+            pos_act = ringpos( pos_act-dsnr, buff_size );
+        }
+        fade_in_i  = RESMAX*((double)snr_o_prod/(double)snr_o_act);
+        fade_out_i = RESMAX-fade_in_i;
+        fade_rest_i= (RESMAX*snr_o_prod)%snr_o_act;
+        _RESMAX_div_max=RESMAX/snr_o_act;
+        _RESMAX_mod_max=RESMAX%snr_o_act;
+        p2=ringpos( pos_act-dsnr, buff_size );
+        for ( ; snr_o_prod < snr_o_act && i<snr ; snr_o_prod++,i++ ){
+            fade_in_i  +=_RESMAX_div_max;
+            fade_out_i -=_RESMAX_div_max;
+            fade_rest_i+=_RESMAX_mod_max;
+            if(fade_rest_i>snr_o_act){
+                fade_rest_i-=snr_o_act;
+                fade_in_i++;
+                fade_out_i--;
+            }
+            outbuff[i] = (s16)( (
+                                 + (int)buffer[pos_act] * fade_out_i
+                                 + (int)buffer[p2]      * fade_in_i
+                                ) >> LOG2RESMAX );
+            pos_act++; if(pos_act>=buff_size) pos_act-=buff_size;
+            p2++;      if(p2     >=buff_size) p2     -=buff_size;
+        }
+    } while( i<snr );
+
+    *out_prod = snr;
+
+    return( *out_prod );
+
+#undef    is_initialized
+#undef    snr_o_prod
+#undef    snr_i_act
+#undef    snr_o_act
+#undef    pos_act
+#undef    dsnr
+#undef    snr_rest
+#undef    _RESMAX_div_max
+#undef    _RESMAX_mod_max
+#undef    fade_in_i
+#undef    fade_out_i
+#undef    fade_rest_i
+}
+
+
+//int sndscale(
+int sndscale_not_optimized(
+/* rescales the sound (including pitch)       */
+/* returns number of output samples produced  */
+           s16 * buffer,                  /* ring buffer                  */
+           int snr_i, int snr_o,          /* enlarge - spec               */
+           int chnr,                      /* # of channels                */
+           s16 * outbuff,                 /* output                       */
+           int * out_prod,                /* # of output-samples produced */
+           int snr_proc,                  /* # of in-samples to process   */
+                                          /* must be manifold of channels */
+           int initialize                 /* bool                         */
+          )
+{
+    static s16     last_samp[10];        /* 10 channels maximum ;) */
+    static double  pos_d     = 0.0;
+    
+    int            snr;
+    int            pos1, pos2;
+    s16            samp1, samp2;
+    int            index1, index2;
+    int            ch;
+    double         ds;
+    double         ratio1, ratio2, outd;
+
+    
+    if ( initialize ){
+        for( ch=0; ch<chnr; ch++ ){
+            last_samp[ch] = 0;
+        }
+        pos_d     = 0.0;
+    }
+
+    ds         = 1.0*(double)snr_i/(double)snr_o;
+
+/*    fprintf(stderr,"ds=%f\n",ds); */
+/*    fprintf(stderr,"pos_d    =%f\n",pos_d);*/
+    
+    /* produce proper amount of samples */
+    for( snr=0 ; pos_d < snr_proc/chnr-1 ; pos_d+=ds ){
+        
+        pos1  = (int)floor(pos_d);
+        pos2  = pos1+1;
+        ratio1 = 1-pos_d+floor(pos_d);
+        ratio2 = pos_d-floor(pos_d);
+        
+        for( ch=0; ch<chnr; ch++ ){
+
+            index1    = pos1*chnr+ch;
+            index2    = pos2*chnr+ch;
+
+            samp1 = (pos_d<0) ? last_samp[ch] : buffer[index1] ;
+            samp2 = buffer[index2];
+
+            outd = (double)samp1 * ratio1
+                 + (double)samp2 * ratio2 ;
+
+            outbuff[snr+ch] = outd+0.5;
+
+        }
+
+        snr+=chnr;
+
+    }
+    
+    pos_d -= (double)(snr_proc/chnr);
+    
+    for( ch=0; ch<chnr; ch++ ){
+        last_samp[ch] = buffer[snr_proc-chnr+ch];
+    }
+    
+    *out_prod = snr;
+    
+/*    fprintf(stderr,"snr = %d\n",snr);*/
+    
+/*    last_samp = buffer[snr_proc-1]; */
+    
+    return( snr );
+}
+
+
+
+int sndscale( //optimized
+//int sndscale2p_optimized(
+/* rescales the sound (including pitch)       */
+/* returns number of output samples produced  */
+           s16 * buffer,                  /* ring buffer                  */
+           int snr_i, int snr_o,          /* enlarge - spec   snr_o must not exceed RESMAX */
+           int chnr,                      /* # of channels                */
+           s16 * outbuff,                 /* output                       */
+           int * out_prod,                /* # of output-samples produced */
+           int snr_proc,                  /* # of in-samples to process   */
+                                          /* must be manifold of channels */
+           int initialize                 /* bool                         */
+          )
+{
+    static s16     last_samp[10];        /* 10 channels maximum ;) */
+    static int            pos_rest;
+    
+    static int            snr;
+    static int            pos1, pos2;
+    static int            ch;
+    static int            ratio1_i;
+    static int            ds_li, ds_li_c, ds_rest;
+    static int            snr_proc_m_chnr;
+
+    
+    if ( initialize ){
+        for( ch=0; ch<chnr; ch++ ){
+            last_samp[ch] = 0;
+        }
+        pos1    = 0;
+    }
+
+    ds_li      = snr_i/snr_o;
+    ds_li_c    = ds_li*chnr;
+    ds_rest    = snr_i%snr_o;
+    
+    snr_proc_m_chnr = snr_proc-chnr;
+    for( snr=0 ; pos1 < snr_proc_m_chnr ; pos1+=ds_li_c ){
+        
+        pos2  = pos1+chnr;
+        ratio1_i = snr_o-pos_rest;
+        
+        if (pos1<0){
+            for( ch=0; ch<chnr; ch++ ){
+                outbuff[snr+ch] = (s16)
+                    ( ( (int)last_samp[ch]   * ratio1_i +
+                        (int)buffer[pos2+ch] * pos_rest ) / snr_o ) ;
+            }
+        } else {
+            for( ch=0; ch<chnr; ch++ ){
+                outbuff[snr+ch] = (s16)
+                    ( ( (int)buffer[pos1+ch] * ratio1_i +
+                        (int)buffer[pos2+ch] * pos_rest ) / snr_o ) ;
+            }
+        }
+
+        snr+=chnr;
+
+        pos_rest+=ds_rest;
+        if( pos_rest>=snr_o ){ pos_rest-=snr_o; pos1+=chnr; }
+    }
+
+    pos1 -= snr_proc;
+    
+    for( ch=0; ch<chnr; ch++ ){
+        last_samp[ch] = buffer[snr_proc-chnr+ch];
+    }
+    
+    *out_prod = snr;
+
+    return( snr );
+}
+
+
+
+int sndscale_job( //optimized
+//int sndscale2p_optimized(
+/* rescales the sound (including pitch)       */
+/* returns number of output samples produced  */
+           s16 * buffer,                  /* ring buffer                  */
+           int snr_i, int snr_o,          /* enlarge - spec   snr_o must not exceed RESMAX */
+           int chnr,                      /* # of channels                */
+           s16 * outbuff,                 /* output                       */
+           int * out_prod,                /* # of output-samples produced */
+           int snr_proc,                  /* # of in-samples to process   */
+                                          /* must be manifold of channels */
+           int initialize,                /* bool                         */
+           ScaleJob * job
+          )
+{
+/*    static s16  *         last_samp;
+    static int            pos_rest;
+    
+    static int            snr;
+    static int            pos1, pos2;
+    static int            ch;
+    static int            ratio1_i;
+    static int            ds_li, ds_li_c, ds_rest;
+    static int            snr_proc_m_chnr;*/
+
+#define    last_samp          job->last_samp
+#define    pos_rest           job->pos_rest
+#define    snr                job->snr
+#define    pos1               job->pos1
+#define    pos2               job->pos2
+#define    ch                 job->ch
+#define    ratio1_i           job->ratio1_i
+#define    ds_li              job->ds_li
+#define    ds_li_c            job->ds_li_c
+#define    ds_rest            job->ds_rest
+#define    snr_proc_m_chnr    job->snr_proc_m_chnr
+
+    if ( initialize ){
+        for( ch=0; ch<chnr; ch++ ){
+            last_samp[ch] = 0;
+        }
+        pos1    = 0;
+    }
+
+    ds_li      = snr_i/snr_o;
+    ds_li_c    = ds_li*chnr;
+    ds_rest    = snr_i%snr_o;
+    
+    snr_proc_m_chnr = snr_proc-chnr;
+    for( snr=0 ; pos1 < snr_proc_m_chnr ; pos1+=ds_li_c ){
+        
+        pos2  = pos1+chnr;
+        ratio1_i = snr_o-pos_rest;
+        
+        if (pos1<0){
+            for( ch=0; ch<chnr; ch++ ){
+                outbuff[snr+ch] = (s16)
+                    ( ( (int)last_samp[ch]   * ratio1_i +
+                        (int)buffer[pos2+ch] * pos_rest ) / snr_o ) ;
+            }
+        } else {
+            for( ch=0; ch<chnr; ch++ ){
+                outbuff[snr+ch] = (s16)
+                    ( ( (int)buffer[pos1+ch] * ratio1_i +
+                        (int)buffer[pos2+ch] * pos_rest ) / snr_o ) ;
+            }
+        }
+
+        snr+=chnr;
+
+        pos_rest+=ds_rest;
+        if( pos_rest>=snr_o ){ pos_rest-=snr_o; pos1+=chnr; }
+    }
+
+    pos1 -= snr_proc;
+    
+    for( ch=0; ch<chnr; ch++ ){
+        last_samp[ch] = buffer[snr_proc-chnr+ch];
+    }
+    
+    *out_prod = snr;
+
+    return( snr );
+
+#undef    last_samp      
+#undef    pos_rest       
+#undef    snr            
+#undef    pos1           
+#undef    pos2           
+#undef    ch             
+#undef    ratio1_i       
+#undef    ds_li          
+#undef    ds_li_c        
+#undef    ds_rest        
+#undef    snr_proc_m_chnr
+}
+
+
+
+int snd_pitch_speed(
+                    /* input */
+                    s16 *buff_i, int channels, int snr_proc,
+                    /* algorihm parameters */
+                    int initialize, double pitch, double speed, int fade_shift,
+                    /* output */
+                    s16 * buff_o, int * snr_produced
+                   )
+{
+    static s16 *  ring_buff = (s16*)0;
+    static s16 *  ring_buff_old = (s16*)0;
+    static s16 *  buff_help = (s16*)0;
+    static int    ring_size = 1;
+    static int    ring_size_old = 0;
+    static int    ring_pos_w = 0;
+    static int    ring_pos_r = 0;
+    static int    snr_scale_i;
+    static int    snr_scale_o;
+    static int    snr_stretch_i;
+    static int    snr_stretch_o;
+    static int    snr_proc_scale;
+    static int    snr_proc_stretch;
+    static int    is_init = 0;
+    static int    dsnr;
+    static double speed_act = 0;
+    static double pitch_act = 0;
+    static double fade_shift_act = 0;
+    
+    int       snr_prod;
+    double    speed_eff;
+    double    pitch_eff;
+    int       scaling_first;
+    int       snr_stretching_i_max;
+    int       snr_stretching_o_max;
+
+//    int       channels = 2;
+    int       init_me  = 0;
+
+    speed_eff = speed/pitch;
+    pitch_eff = pitch;
+
+    scaling_first=0;
+//    if( pitch > 1.0 ) scaling_first=0; else scaling_first=1;
+    
+    if ( !is_init || initialize || speed!=speed_act || pitch!=pitch_act ||
+         fade_shift!=fade_shift_act ){
+
+        if( !is_init || initialize ) init_me=1; else init_me=0;
+        
+#ifdef DEBUG
+        fprintf(stderr,"snd_stretch_scale - init - pitch:%f, speed:%f\n",pitch,speed);
+#endif
+        
+        speed_act = speed;
+        pitch_act = pitch;
+        fade_shift_act = fade_shift;
+
+//        if (ring_buff!=0) free(ring_buff);
+//        if (buff_help!=0) free(buff_help);
+
+        if (initialize != -1){
+            
+            dsnr       = fade_shift;
+//            dsnr       = 1764; // 25Hz
+//            dsnr       = 1536; // 30Hz
+//            dsnr       = 1102; // 40Hz
+//            dsnr       = 882;  // 50Hz
+
+            if( scaling_first ){
+                snr_stretching_i_max = ceil((double)snr_proc/pitch_act);
+                snr_stretching_i_max += channels-1;
+                snr_stretching_i_max /= channels;
+                snr_stretching_i_max *= channels;
+            } else {
+                snr_stretching_i_max = (snr_proc+channels-1)/channels*channels;
+            }
+
+            snr_stretching_o_max =
+                ceil((double)snr_stretching_i_max / speed_eff);
+            snr_stretching_o_max =
+                (snr_stretching_o_max+channels-1)/channels*channels;
+
+            ring_size  = snr_stretching_o_max     /* for reading */
+                       + dsnr*channels            /* for grabbing back */
+                       + dsnr*channels            /* for readpos catching */
+                                                  /* up with writepos     */
+                       + 2*dsnr*channels ;          /* for 2 pre - echos */
+//            ring_size  = snr_stretching_o_max+3*dsnr*channels;
+
+            if( ring_size <= ring_size_old ){
+                ring_size = ring_size_old;
+#ifdef DEBUG
+                fprintf(stderr," ring_size =  %d \n",ring_size);
+#endif
+            } else {
+/*                if (ring_buff!=0) free(ring_buff);
+                if (buff_help!=0) free(buff_help);
+                ring_buff  = calloc( ring_size, sizeof(s16) );
+                buff_help  = calloc( 65536, sizeof(s16) );
+                ring_pos_r = 0;*/
+                if (buff_help!=0) free(buff_help);
+                ring_buff_old = ring_buff;
+                ring_buff = calloc( ring_size, sizeof(s16) );
+                buff_help = calloc( 65536, sizeof(s16) );
+                if (ring_buff_old!=0) ringcopy( ring_buff, ring_size, ring_pos_r, ring_pos_w, ring_buff_old, ring_size_old, ring_pos_r );
+                if (ring_buff_old!=0) free(ring_buff_old);
+//                ring_pos_w=ringpos(ring_pos_w+ring_size_old,ring_size);
+#ifdef DEBUG
+                fprintf(stderr,"    %d s16-samples reserved\n",ring_size);
+#endif
+            }
+
+            ring_pos_w =
+                ringpos( ring_pos_r +         /* base             */
+                         dsnr*channels        /* for grabing back */
+//                         dsnr*2             /* for grabing back */ // why *2
+                         , ring_size );
+#ifdef DEBUG
+            fprintf(stderr,"    ring_pos_w = %d\n",ring_pos_w);
+#endif
+            ring_pos_w = (ring_pos_w+(channels-1))/channels*channels;
+
+            ring_size_old = ring_size;
+            
+            is_init = 1;
+
+        } else {  /* initialize == -1 */
+            if (ring_buff!=0) free(ring_buff);
+            if (buff_help!=0) free(buff_help);
+            /* buffers are released -> leave the function */
+            return 0;                            /* !!! sloppy */
+        }
+        
+    }
+    
+    if ( fabs(speed_eff-1.0)>0.001 ){ /*
+                                     0.001 ?!
+                                     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+                                       this should be examined to the limits
+                                     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+                                  */
+        snr_stretch_i = (double)dsnr/(1.0/speed_eff-1.0);
+        snr_stretch_o = fabs(snr_stretch_i + dsnr);
+        snr_stretch_i = abs(snr_stretch_i);
+//        fprintf(stderr,"snd_stretch_scale - snr_str_i=%d\n",snr_stretch_i);
+//        fprintf(stderr,"snd_stretch_scale - snr_str_o=%d\n",snr_stretch_o);
+    } else {
+        snr_stretch_i = 10;
+        snr_stretch_o = 10;
+    }
+
+    if ( pitch_eff!=1.0 ){
+        snr_scale_i   = (double)dsnr/(1.0/pitch_eff-1.0);
+        snr_scale_o   = fabs(snr_scale_i + dsnr);
+        snr_scale_i   = abs(snr_scale_i);
+        if( 1 /* optimized version doesnt support all scaling */ ){
+            if( snr_scale_o > 65536 ){
+                snr_scale_i = (int)((double)snr_scale_i*((double)65536/(double)snr_scale_o)+0.5);
+                snr_scale_o = 65536;
+                // make sure that snr_o for sndscale wont exceed 2^16
+            }
+        }
+//        fprintf(stderr,"snd_stretch_scale - snr_sc_i=%d\n",snr_stretch_i);
+//        fprintf(stderr,"snd_stretch_scale - snr_sc_o=%d\n",snr_stretch_o);
+    } else {
+//        fprintf(stderr,"snd_stretch_scale - snr_scale_i=snr_scale_o=10\n");
+        snr_scale_i   = 65536;
+        snr_scale_o   = 65536;
+    }
+
+    if( 0/*scaling_first*/ ){
+        
+        snr_proc_scale = snr_proc;
+        sndscale ( buff_i,
+                   snr_scale_i, snr_scale_o, channels,
+                   buff_help, &snr_prod, snr_proc_scale, init_me );
+/*                   buff_o, &snr_prod, snr_proc_scale, 0 ); */
+        
+        if( speed_eff!=1.0 ){   /* add echo only when really stretching */
+            ringload_IIR_1_div_e_echo_i( ring_buff, ring_size, ring_pos_w, buff_help, snr_prod, dsnr*channels );
+        } else {
+            ringload( ring_buff, ring_size, ring_pos_w, buff_help, snr_prod );
+        }
+        ring_pos_w = ringpos( ring_pos_w+snr_prod, ring_size );
+        
+        snr_proc_stretch = snr_prod;
+        sndstretch ( ring_buff, ring_size, ring_pos_r,
+                     snr_stretch_i*channels, snr_stretch_o*channels, channels,
+                     buff_o, &snr_prod, snr_proc_stretch, init_me );
+
+        ring_pos_r = ringpos( ring_pos_r+snr_prod, ring_size );
+
+    } else {
+
+//        fprintf(stderr,"sndstretch: ring_pos_r = %d\n",ring_pos_r);
+//        fprintf(stderr,"sndstretch: ring_pos_w = %d\n\n",ring_pos_w);
+        snr_prod = snr_proc;
+        if( speed_eff!=1.0 ){   /* add echo only when really stretching */
+            ringload_IIR_1_div_e_echo_i( ring_buff, ring_size, ring_pos_w, buff_i, snr_proc, dsnr*channels );
+        } else {
+            ringload( ring_buff, ring_size, ring_pos_w, buff_i, snr_proc );
+        }
+        ring_pos_w = ringpos( ring_pos_w+snr_proc, ring_size );
+        
+        snr_proc_stretch = snr_proc;
+        sndstretch ( ring_buff, ring_size, ring_pos_r,
+                     snr_stretch_i*channels, snr_stretch_o*channels, channels,
+                     buff_help, &snr_prod, snr_proc_stretch, init_me );
+        
+        ring_pos_r = ringpos( ring_pos_r+snr_prod, ring_size );
+
+        snr_proc_scale = snr_prod;
+//        fprintf(stderr,"snr_scale_i, snr_scale_o = %d,%d\n",snr_scale_i, snr_scale_o);
+        sndscale ( buff_help,
+                   snr_scale_i, snr_scale_o, channels,
+                   buff_o, &snr_prod, snr_proc_scale, init_me );
+
+    }
+    
+    *snr_produced = snr_prod;
+    
+    return snr_prod;
+}
+
+
+int snd_pitch_speed_job(
+                    /* input */
+                    s16 *buff_i, int channels, int snr_proc,
+                    /* algorihm parameters */
+                    int initialize, double pitch, double speed, int fade_shift,
+                    /* output */
+                    s16 * buff_o, int * snr_produced, PitchSpeedJob * job,
+                    int vol_corr
+                   )
+{
+/*    static s16 *  ring_buff = (s16*)0;
+    static s16 *  ring_buff_old = (s16*)0;
+    static s16 *  buff_help = (s16*)0;
+    static int    ring_size = 1;
+    static int    ring_size_old = 0;
+    static int    ring_pos_w = 0;
+    static int    ring_pos_r = 0;
+    static int    snr_scale_i;
+    static int    snr_scale_o;
+    static int    snr_stretch_i;
+    static int    snr_stretch_o;
+    static int    snr_proc_scale;
+    static int    snr_proc_stretch;
+    static int    is_init = 0;
+    static int    dsnr;
+    static double speed_act = 0;
+    static double pitch_act = 0;*/
+
+    int       snr_prod;
+    double    speed_eff;
+    double    pitch_eff;
+    int       scaling_first;
+    int       snr_stretching_i_max;
+    int       snr_stretching_o_max;
+
+//    int       channels = 2;
+    int       init_me  = 0;
+
+#define    ring_buff         job->ring_buff
+#define    ring_buff_old     job->ring_buff_old
+#define    buff_help         job->buff_help
+#define    ring_size         job->ring_size
+#define    ring_size_old     job->ring_size_old
+#define    ring_pos_w        job->ring_pos_w
+#define    ring_pos_r        job->ring_pos_r
+#define    snr_scale_i       job->snr_scale_i
+#define    snr_scale_o       job->snr_scale_o
+#define    snr_stretch_i     job->snr_stretch_i
+#define    snr_stretch_o     job->snr_stretch_o
+#define    snr_proc_scale    job->snr_proc_scale
+#define    snr_proc_stretch  job->snr_proc_stretch
+#define    is_init           job->is_init
+#define    dsnr              job->dsnr
+#define    speed_act         job->speed_act
+#define    pitch_act         job->pitch_act
+#define    fade_shift_act    job->fade_shift_act
+    
+    speed_eff = speed/pitch;
+    pitch_eff = pitch;
+
+    scaling_first=0;
+//    if( pitch > 1.0 ) scaling_first=0; else scaling_first=1;
+    
+    if ( !is_init || initialize || speed!=speed_act || pitch!=pitch_act ||
+         fade_shift != fade_shift_act ){
+
+        if( !is_init || initialize ) init_me=1; else init_me=0;
+        
+#ifdef DEBUG
+        fprintf(stderr,"snd_stretch_scale - init - pitch:%f, speed:%f\n",pitch,speed);
+#endif
+        
+        speed_act = speed;
+        pitch_act = pitch;
+        if ( fade_shift != fade_shift_act ){
+            fprintf(stderr,"changed fade_shift_act\n");
+        }
+        fade_shift_act = fade_shift;
+
+//        if (ring_buff!=0) free(ring_buff);
+//        if (buff_help!=0) free(buff_help);
+
+        if (initialize != -1){
+            
+            dsnr       = fade_shift;
+//            dsnr       = 1764; // 25Hz
+//            dsnr       = 1536; // 30Hz
+//            dsnr       = 1102; // 40Hz
+//            dsnr       = 882;  // 50Hz
+
+            if( scaling_first ){
+                snr_stretching_i_max = ceil((double)snr_proc/pitch_act);
+                snr_stretching_i_max += channels-1;
+                snr_stretching_i_max /= channels;
+                snr_stretching_i_max *= channels;
+            } else {
+                snr_stretching_i_max = (snr_proc+channels-1)/channels*channels;
+            }
+
+            snr_stretching_o_max =
+                ceil((double)snr_stretching_i_max / speed_eff);
+            snr_stretching_o_max =
+                (snr_stretching_o_max+channels-1)/channels*channels;
+
+            ring_size  = snr_stretching_o_max     /* for reading */
+                       + dsnr*channels            /* for grabbing back */
+                       + dsnr*channels            /* for readpos catching */
+                                                  /* up with writepos     */
+                       + 2*dsnr*channels ;          /* for 2 pre - echos */
+//            ring_size  = snr_stretching_o_max+3*dsnr*channels;
+
+            if( ring_size <= ring_size_old ){
+                ring_size = ring_size_old;
+#ifdef DEBUG
+                fprintf(stderr," ring_size =  %d \n",ring_size);
+#endif
+            } else {
+/*                if (ring_buff!=0) free(ring_buff);
+                if (buff_help!=0) free(buff_help);
+                ring_buff  = calloc( ring_size, sizeof(s16) );
+                buff_help  = calloc( 65536, sizeof(s16) );
+                ring_pos_r = 0;*/
+                if (buff_help!=0) free(buff_help);
+                ring_buff_old = ring_buff;
+                ring_buff = calloc( ring_size, sizeof(s16) );
+                buff_help = calloc( 65536, sizeof(s16) );
+                if (ring_buff_old!=0) ringcopy( ring_buff, ring_size, ring_pos_r, ring_pos_w, ring_buff_old, ring_size_old, ring_pos_r );
+                if (ring_buff_old!=0) free(ring_buff_old);
+//                ring_pos_w=ringpos(ring_pos_w+ring_size_old,ring_size);
+#ifdef DEBUG
+                fprintf(stderr,"    %d s16-samples reserved\n",ring_size);
+#endif
+            }
+
+            ring_pos_w =
+                ringpos( ring_pos_r +         /* base             */
+                         dsnr*channels        /* for grabing back */
+//                         dsnr*2             /* for grabing back */ // why *2
+                         , ring_size );
+#ifdef DEBUG
+            fprintf(stderr,"    ring_pos_w = %d\n",ring_pos_w);
+#endif
+            ring_pos_w = (ring_pos_w+(channels-1))/channels*channels;
+
+            ring_size_old = ring_size;
+            
+            is_init = 1;
+
+        } else {  /* initialize == -1 */
+            if (ring_buff!=0) free(ring_buff);
+            if (buff_help!=0) free(buff_help);
+            /* buffers are released -> leave the function */
+            return 0;                            /* !!! sloppy */
+        }
+        
+    }
+    
+    if ( fabs(speed_eff-1.0)>0.001 ){ /*
+                                     0.001 ?!
+                                     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+                                       this should be examined to the limits
+                                     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+                                  */
+        snr_stretch_i = (double)dsnr/(1.0/speed_eff-1.0);
+        snr_stretch_o = fabs(snr_stretch_i + dsnr);
+        snr_stretch_i = abs(snr_stretch_i);
+//        fprintf(stderr,"snd_stretch_scale - snr_str_i=%d\n",snr_stretch_i);
+//        fprintf(stderr,"snd_stretch_scale - snr_str_o=%d\n",snr_stretch_o);
+    } else {
+        snr_stretch_i = 10;
+        snr_stretch_o = 10;
+    }
+
+    if ( pitch_eff!=1.0 ){
+        snr_scale_i   = (double)dsnr/(1.0/pitch_eff-1.0);
+        snr_scale_o   = fabs(snr_scale_i + dsnr);
+        snr_scale_i   = abs(snr_scale_i);
+        if( 1 /* optimized version doesnt support all scaling */ ){
+            if( snr_scale_o > 65536 ){
+                snr_scale_i = (int)((double)snr_scale_i*((double)65536/(double)snr_scale_o)+0.5);
+                snr_scale_o = 65536;
+                // make sure that snr_o for sndscale wont exceed 2^16
+            }
+        }
+//        fprintf(stderr,"snd_stretch_scale - snr_sc_i=%d\n",snr_stretch_i);
+//        fprintf(stderr,"snd_stretch_scale - snr_sc_o=%d\n",snr_stretch_o);
+    } else {
+//        fprintf(stderr,"snd_stretch_scale - snr_scale_i=snr_scale_o=10\n");
+        snr_scale_i   = 65536;
+        snr_scale_o   = 65536;
+    }
+
+    if( 0/*scaling_first*/ ){
+        
+        snr_proc_scale = snr_proc;
+        sndscale_job ( buff_i,
+                       snr_scale_i, snr_scale_o, channels,
+                       buff_help, &snr_prod, snr_proc_scale, init_me,
+                       &(job->scale_job) );
+/*                   buff_o, &snr_prod, snr_proc_scale, 0 ); */
+        
+        if( speed_eff!=1.0 ){   /* add echo only when really stretching */
+            if( !vol_corr ){
+                ringload_IIR_1_div_e_echo_i( ring_buff, ring_size, ring_pos_w, buff_help, snr_prod, dsnr*channels );
+            } else {
+                ringload_IIR_1_div_e_echo_i_vc( ring_buff, ring_size, ring_pos_w, buff_help, snr_prod, dsnr*channels );
+            }
+        } else {
+            ringload( ring_buff, ring_size, ring_pos_w, buff_help, snr_prod );
+        }
+        ring_pos_w = ringpos( ring_pos_w+snr_prod, ring_size );
+        
+        snr_proc_stretch = snr_prod;
+        sndstretch_job ( ring_buff, ring_size, ring_pos_r,
+                         snr_stretch_i*channels, snr_stretch_o*channels, channels,
+                         buff_o, &snr_prod, snr_proc_stretch, init_me,
+                         &(job->stretch_job)
+                       );
+
+        ring_pos_r = ringpos( ring_pos_r+snr_prod, ring_size );
+
+    } else {
+
+//        fprintf(stderr,"sndstretch: ring_pos_r = %d\n",ring_pos_r);
+//        fprintf(stderr,"sndstretch: ring_pos_w = %d\n\n",ring_pos_w);
+        snr_prod = snr_proc;
+        if( speed_eff!=1.0 ){   /* add echo only when really stretching */
+            if( !vol_corr ){
+                ringload_IIR_1_div_e_echo_i( ring_buff, ring_size, ring_pos_w, buff_i, snr_proc, dsnr*channels );
+            }else{
+                ringload_IIR_1_div_e_echo_i_vc( ring_buff, ring_size, ring_pos_w, buff_i, snr_proc, dsnr*channels );
+            }
+        } else {
+            ringload( ring_buff, ring_size, ring_pos_w, buff_i, snr_proc );
+        }
+        ring_pos_w = ringpos( ring_pos_w+snr_proc, ring_size );
+        
+        snr_proc_stretch = snr_proc;
+        sndstretch_job ( ring_buff, ring_size, ring_pos_r,
+                         snr_stretch_i*channels, snr_stretch_o*channels, channels,
+                         buff_help, &snr_prod, snr_proc_stretch, init_me,
+                         &(job->stretch_job)
+                       );
+        
+        ring_pos_r = ringpos( ring_pos_r+snr_prod, ring_size );
+
+        snr_proc_scale = snr_prod;
+//        fprintf(stderr,"snr_scale_i, snr_scale_o = %d,%d\n",snr_scale_i, snr_scale_o);
+        sndscale_job ( buff_help,
+                       snr_scale_i, snr_scale_o, channels,
+                       buff_o, &snr_prod, snr_proc_scale, init_me,
+                       &(job->scale_job)
+                     );
+
+    }
+    
+    *snr_produced = snr_prod;
+    
+    return snr_prod;
+#undef    ring_buff
+#undef    ring_buff_old
+#undef    buff_help
+#undef    ring_size
+#undef    ring_size_old
+#undef    ring_pos_w
+#undef    ring_pos_r
+#undef    snr_scale_i
+#undef    snr_scale_o
+#undef    snr_stretch_i
+#undef    snr_stretch_o
+#undef    snr_proc_scale
+#undef    snr_proc_stretch
+#undef    is_init
+#undef    dsnr
+#undef    speed_act
+#undef    pitch_act
+#undef    fade_shift_act
+}
+
+
+int snd_stretch_scale(s16 *buff_i, s16 * buff_o,
+                      double pitch, double speed, int channels,
+                      int snr_proc, int * snr_produced, int initialize
+                     )
+{
+    return snd_pitch_speed(
+                           /* input */
+                           buff_i, channels, snr_proc,
+                           /* algorihm parameters */
+                           initialize, pitch, speed, 1764,
+                           /* output */
+                           buff_o, snr_produced
+                          );
+}
+
+
+int snd_stretch_scale_job(s16 *buff_i, s16 * buff_o,
+                      double pitch, double speed, int channels,
+                      int snr_proc, int * snr_produced, int initialize,
+                      PitchSpeedJob * job, int init_job)
+/* init_job should be set to one the first time the routine is called with
+   the actual job (e.g. for creating a new job) */
+{
+    if(init_job){
+        InitPitchSpeedJob(job);
+    }
+    return snd_pitch_speed_job(
+                               /* input */
+                               buff_i, channels, snr_proc,
+                               /* algorihm parameters */
+                               initialize, pitch, speed, 1764 ,
+                               /* output */
+                               buff_o, snr_produced,
+                               /* job data */
+                               job, 0
+                              );
+}