From ddcb4ab4507cac8b3ec36f9d454e98c336b920b5 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Thu, 28 Mar 2013 15:31:22 +0000 Subject: Use specialized memcpy wrapper to avoid missing a sizeof(short). Also get rid off floats around the innerloop. Use precalc table. --- timestretch.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/timestretch.c b/timestretch.c index 63ba059..7f9bcd6 100644 --- a/timestretch.c +++ b/timestretch.c @@ -10,6 +10,7 @@ // global values static short * g_overlap_buffer; +static short * g_overlap_heuristic; static size_t g_overlap; static size_t g_input_length; // Minimal length @@ -25,8 +26,11 @@ static size_t g_firstframe; // If this is set, the caller should provide ini #define CORR_WINDOW 15 // overlapping correlation window length (music default = 28 ms) #define OUTPUT_LEN 30 // one processing sequence length in milliseconds (music default = 82 ms) +#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 ) { + unsigned int i; g_overlap = ( sample_rate * OVERLAP ) / 1000; free( g_overlap_buffer ); @@ -38,6 +42,11 @@ static size_t calc_convert_values( int sample_rate, float tempo ) { g_output_length = g_overlap; g_corr_length = ( sample_rate * CORR_WINDOW ) / 1000; + free( g_overlap_heuristic ); + g_overlap_heuristic = malloc( sizeof(short) * g_corr_length ); + for( i = 0; i < g_corr_length; ++i ) + g_overlap_heuristic[i] = (short)16384.0*(-(double)i*(double)i/((double)g_corr_length*(double)g_corr_length)+(double)i/(double)g_corr_length+0.75f); + g_skip = (size_t)( tempo * (float)g_output_length * 65536.0 ); g_input_length = g_corr_length + g_output_length + g_overlap; if( g_skip / 65536 > g_input_length ) @@ -62,22 +71,21 @@ static unsigned int find_corr_max(const short *input, const short *mixbuf) { // Scans for the best correlation value by testing each possible position for (i = 0; i < g_corr_length; ++i) { - double acc, i_f = (double)i, sl_f = (double)g_corr_length; - double heur = 0.75 - ( i_f * i_f ) / ( sl_f * sl_f ) + i_f / sl_f; - int64_t acc_i; + int64_t acc = 0; - for(j = 0, acc_i = 0; j < g_overlap; ++j ) - acc_i += input[i+j] * mixbuf[j]; + for(j = 0; j < g_overlap; ++j ) + acc += input[i+j] * mixbuf[j]; // boost middle of sequence by top of a flat parabola // slope stolen from soundtouch - acc = (double)acc_i * heur; + acc *= g_overlap_heuristic[i]; if ( corr_max < acc ) { offs = i; corr_max = acc; } } -// printf( "%03d %014.0lf\n", best_offs, best_corr ); + +printf( "%03d %016llX\n", offs, (int64_t)corr_max ); return offs; } @@ -89,7 +97,7 @@ size_t process_frame( short *input, short *output, short *overlap ) { // The first frame needs to be copied verbatim, // we do not have anything to mix, yet. if( g_firstframe ) { - memcpy( output, input, g_output_length * sizeof(short) ); + sampcpy( output, input, g_output_length ); g_firstframe = 0; } else { offset = find_corr_max( input, overlap ); @@ -99,11 +107,11 @@ size_t process_frame( short *input, short *output, short *overlap ) { output[i] = ( i_ * overlap[i] + i * input[i+offset] ) / (int)g_overlap; // Copy rest of the input verbatim - memcpy( output + g_overlap, input + offset + g_overlap, ( g_output_length - g_overlap ) * sizeof(short) ); + sampcpy( output + g_overlap, input + offset + g_overlap, g_output_length - g_overlap ); } // Remember end of this frame for next frame - memcpy( overlap, input + offset + g_output_length, g_overlap * sizeof(short) ); + sampcpy( overlap, input + offset + g_output_length, g_overlap ); // Remove the processed samples from the input buffer. g_offset &= 0xffff; -- cgit v1.2.3