From 2b7b951e97ac63bcd87d542e30c9772caceb05f9 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Tue, 2 Apr 2013 02:14:20 +0000 Subject: Merge correlation function into process, also add documentation --- timestretch.c | 65 +++++++++++++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/timestretch.c b/timestretch.c index 1f94837..b9ae038 100644 --- a/timestretch.c +++ b/timestretch.c @@ -11,11 +11,11 @@ static short * g_overlap_buffer; static short * g_overlap_heuristic; static size_t g_overlap; -static size_t g_input_length; // Minimal length -static size_t g_output_length; -static size_t g_corr_length; +static size_t g_skip; // Per frame skip << 16, i.e. amount of samples consumed if not FRAME_LAST +static size_t g_input_length; // Minimal length, not everything is used +static size_t g_output_length; // Exact length of output +static size_t g_corr_length; // Length of frame part correlation is attempted in -static size_t g_skip; // Per frame skip static size_t g_offset; // Offset into stream, lower bits #define FRAME_FIRST 0x01 @@ -29,7 +29,7 @@ static size_t g_offset; // Offset into stream, lower bits #define sampcpy(A,B,C) memcpy((A),(B),(C)*sizeof(short)) // Returns the length of one output frame -static size_t calc_convert_values( int sample_rate, float tempo ) { +static size_t calc_convert_values( int sample_rate, double tempo ) { unsigned int i; g_overlap = ( sample_rate * OVERLAP ) / 1000; @@ -48,9 +48,9 @@ static size_t calc_convert_values( int sample_rate, float tempo ) { // boost middle of sequence by top of a flat parabola // slope stolen from soundtouch, precalc table for( i = 0; i < g_corr_length; ++i ) - g_overlap_heuristic[i] = (short)16384.0*(-(double)(i*i)/((double)(g_corr_length*g_corr_length))+(double)i/(double)g_corr_length+0.75f); + g_overlap_heuristic[i] = (short)16384.0*(-(double)(i*i)/((double)(g_corr_length*g_corr_length))+(double)i/(double)g_corr_length+0.75); - g_skip = (size_t)( tempo * (float)g_output_length * 65536.0 ); + g_skip = (size_t)( tempo * (double)g_output_length * 65536.0 ); g_input_length = g_corr_length + g_output_length + g_overlap; if( g_skip / 65536 > g_input_length ) g_input_length = g_skip / 65536; @@ -58,8 +58,7 @@ static size_t calc_convert_values( int sample_rate, float tempo ) { return g_output_length; } -/* - Example: tempo 1.5 with 30/15/10 => skip == 45, out = 30 +/* Example: tempo 1.5 with 30/15/10 => skip == 45, out = 30 we found an offset of 5 msec [#####OOOOOOOOOOVVVVVVVVVVVVVVVVVVVVmmmmmmmmmm?????????????????????????] @@ -68,41 +67,33 @@ we found an offset of 5 msec [ #####OOOOOOOOOOVVVVVVVVVVVVVVVVVVVVmmmmmmmmmm?????????????????????????] */ -static unsigned int find_corr_max(const short *input, const short *mixbuf) { - unsigned int i, j, offs = 0; - int64_t acc, corr_max = 0; - - // Scans for the best correlation value by testing each possible position - for (i = 0; i < g_corr_length; ++i) { - for(j = 0, acc = 0; j < g_overlap; ++j ) - acc += input[i+j] * mixbuf[j]; - - acc *= g_overlap_heuristic[i]; - if ( corr_max < acc ) { - offs = i; - corr_max = acc; - } - } - -//printf( "%03d %016llX\n", offs, corr_max ); - return offs; -} - // Returns the amount of samples that can be discarded from begin of the input buffer size_t process_frame( short *input, short *output, short *overlap, int frame_flag ) { - int i, i_ = (int)g_overlap; - unsigned int offset = 0; + int offset = 0; - // The first frame needs to be copied verbatim, - // we do not have anything to mix, yet. + // The first frame needs to be copied verbatim, we do not have anything to mix, yet. if( frame_flag & FRAME_FIRST ) sampcpy( output, input, g_output_length ); else { - offset = find_corr_max( input, overlap ); + int64_t acc, corr_max = 0; + int i, j; + + // Scans for the best correlation value by testing each possible position + for( i = 0; i < (int)g_corr_length; ++i ) { + for( j = 0, acc = 0; j < (int)g_overlap; ++j ) + acc += input[i+j] * overlap[j]; + + acc *= g_overlap_heuristic[i]; + if ( corr_max < acc ) { + offset = i; + corr_max = acc; + } + } +//printf( "%03d %016llX\n", offset, corr_max ); // Cross fade end of last frame with begin of this frame - for (i = 0; i < (int)g_overlap ; ++i, --i_ ) - output[i] = ( i_ * overlap[i] + i * input[i+offset] ) / (int)g_overlap; + for( i = 0, j = (int)g_overlap; i < (int)g_overlap ; ++i, --j ) + output[i] = ( j * overlap[i] + i * input[i+offset] ) / (int)g_overlap; // Copy rest of the input verbatim sampcpy( output + g_overlap, input + offset + g_overlap, g_output_length - g_overlap ); @@ -122,7 +113,7 @@ size_t process_frame( short *input, short *output, short *overlap, int frame_fla } int main( int args, char **argv ) { - size_t out_chunk_size = calc_convert_values( 8000, 1.25f ); + size_t out_chunk_size = calc_convert_values( 8000, 1.25 ); size_t in_fill = 0; short outbuf[ g_output_length ]; short inbuf [ g_input_length ]; -- cgit v1.2.3