summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2013-04-02 02:14:20 +0000
committererdgeist <>2013-04-02 02:14:20 +0000
commit2b7b951e97ac63bcd87d542e30c9772caceb05f9 (patch)
tree0f494efa9e4e20734ada4f32d1c482ed025f5e5c
parent638d2e14ae12948e2965e874df6e1f888394b6f5 (diff)
Merge correlation function into process, also add documentation
-rw-r--r--timestretch.c65
1 files 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;
11static short * g_overlap_heuristic; 11static short * g_overlap_heuristic;
12static size_t g_overlap; 12static size_t g_overlap;
13 13
14static size_t g_input_length; // Minimal length 14static size_t g_skip; // Per frame skip << 16, i.e. amount of samples consumed if not FRAME_LAST
15static size_t g_output_length; 15static size_t g_input_length; // Minimal length, not everything is used
16static size_t g_corr_length; 16static size_t g_output_length; // Exact length of output
17static size_t g_corr_length; // Length of frame part correlation is attempted in
17 18
18static size_t g_skip; // Per frame skip
19static size_t g_offset; // Offset into stream, lower bits 19static size_t g_offset; // Offset into stream, lower bits
20 20
21#define FRAME_FIRST 0x01 21#define FRAME_FIRST 0x01
@@ -29,7 +29,7 @@ static size_t g_offset; // Offset into stream, lower bits
29#define sampcpy(A,B,C) memcpy((A),(B),(C)*sizeof(short)) 29#define sampcpy(A,B,C) memcpy((A),(B),(C)*sizeof(short))
30 30
31// Returns the length of one output frame 31// Returns the length of one output frame
32static size_t calc_convert_values( int sample_rate, float tempo ) { 32static size_t calc_convert_values( int sample_rate, double tempo ) {
33 unsigned int i; 33 unsigned int i;
34 g_overlap = ( sample_rate * OVERLAP ) / 1000; 34 g_overlap = ( sample_rate * OVERLAP ) / 1000;
35 35
@@ -48,9 +48,9 @@ static size_t calc_convert_values( int sample_rate, float tempo ) {
48 // boost middle of sequence by top of a flat parabola 48 // boost middle of sequence by top of a flat parabola
49 // slope stolen from soundtouch, precalc table 49 // slope stolen from soundtouch, precalc table
50 for( i = 0; i < g_corr_length; ++i ) 50 for( i = 0; i < g_corr_length; ++i )
51 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); 51 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);
52 52
53 g_skip = (size_t)( tempo * (float)g_output_length * 65536.0 ); 53 g_skip = (size_t)( tempo * (double)g_output_length * 65536.0 );
54 g_input_length = g_corr_length + g_output_length + g_overlap; 54 g_input_length = g_corr_length + g_output_length + g_overlap;
55 if( g_skip / 65536 > g_input_length ) 55 if( g_skip / 65536 > g_input_length )
56 g_input_length = g_skip / 65536; 56 g_input_length = g_skip / 65536;
@@ -58,8 +58,7 @@ static size_t calc_convert_values( int sample_rate, float tempo ) {
58 return g_output_length; 58 return g_output_length;
59} 59}
60 60
61/* 61/* Example: tempo 1.5 with 30/15/10 => skip == 45, out = 30
62 Example: tempo 1.5 with 30/15/10 => skip == 45, out = 30
63we found an offset of 5 msec 62we found an offset of 5 msec
64 63
65 [#####OOOOOOOOOOVVVVVVVVVVVVVVVVVVVVmmmmmmmmmm?????????????????????????] 64 [#####OOOOOOOOOOVVVVVVVVVVVVVVVVVVVVmmmmmmmmmm?????????????????????????]
@@ -68,41 +67,33 @@ we found an offset of 5 msec
68 [ #####OOOOOOOOOOVVVVVVVVVVVVVVVVVVVVmmmmmmmmmm?????????????????????????] 67 [ #####OOOOOOOOOOVVVVVVVVVVVVVVVVVVVVmmmmmmmmmm?????????????????????????]
69*/ 68*/
70 69
71static unsigned int find_corr_max(const short *input, const short *mixbuf) {
72 unsigned int i, j, offs = 0;
73 int64_t acc, corr_max = 0;
74
75 // Scans for the best correlation value by testing each possible position
76 for (i = 0; i < g_corr_length; ++i) {
77 for(j = 0, acc = 0; j < g_overlap; ++j )
78 acc += input[i+j] * mixbuf[j];
79
80 acc *= g_overlap_heuristic[i];
81 if ( corr_max < acc ) {
82 offs = i;
83 corr_max = acc;
84 }
85 }
86
87//printf( "%03d %016llX\n", offs, corr_max );
88 return offs;
89}
90
91// Returns the amount of samples that can be discarded from begin of the input buffer 70// Returns the amount of samples that can be discarded from begin of the input buffer
92size_t process_frame( short *input, short *output, short *overlap, int frame_flag ) { 71size_t process_frame( short *input, short *output, short *overlap, int frame_flag ) {
93 int i, i_ = (int)g_overlap; 72 int offset = 0;
94 unsigned int offset = 0;
95 73
96 // The first frame needs to be copied verbatim, 74 // The first frame needs to be copied verbatim, we do not have anything to mix, yet.
97 // we do not have anything to mix, yet.
98 if( frame_flag & FRAME_FIRST ) 75 if( frame_flag & FRAME_FIRST )
99 sampcpy( output, input, g_output_length ); 76 sampcpy( output, input, g_output_length );
100 else { 77 else {
101 offset = find_corr_max( input, overlap ); 78 int64_t acc, corr_max = 0;
79 int i, j;
80
81 // Scans for the best correlation value by testing each possible position
82 for( i = 0; i < (int)g_corr_length; ++i ) {
83 for( j = 0, acc = 0; j < (int)g_overlap; ++j )
84 acc += input[i+j] * overlap[j];
85
86 acc *= g_overlap_heuristic[i];
87 if ( corr_max < acc ) {
88 offset = i;
89 corr_max = acc;
90 }
91 }
92//printf( "%03d %016llX\n", offset, corr_max );
102 93
103 // Cross fade end of last frame with begin of this frame 94 // Cross fade end of last frame with begin of this frame
104 for (i = 0; i < (int)g_overlap ; ++i, --i_ ) 95 for( i = 0, j = (int)g_overlap; i < (int)g_overlap ; ++i, --j )
105 output[i] = ( i_ * overlap[i] + i * input[i+offset] ) / (int)g_overlap; 96 output[i] = ( j * overlap[i] + i * input[i+offset] ) / (int)g_overlap;
106 97
107 // Copy rest of the input verbatim 98 // Copy rest of the input verbatim
108 sampcpy( output + g_overlap, input + offset + g_overlap, g_output_length - g_overlap ); 99 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
122} 113}
123 114
124int main( int args, char **argv ) { 115int main( int args, char **argv ) {
125 size_t out_chunk_size = calc_convert_values( 8000, 1.25f ); 116 size_t out_chunk_size = calc_convert_values( 8000, 1.25 );
126 size_t in_fill = 0; 117 size_t in_fill = 0;
127 short outbuf[ g_output_length ]; 118 short outbuf[ g_output_length ];
128 short inbuf [ g_input_length ]; 119 short inbuf [ g_input_length ];