diff options
author | erdgeist <> | 2013-04-02 01:47:30 +0000 |
---|---|---|
committer | erdgeist <> | 2013-04-02 01:47:30 +0000 |
commit | 638d2e14ae12948e2965e874df6e1f888394b6f5 (patch) | |
tree | df24d8bb52713ea9a83ff7d69a6c3e72af828a35 | |
parent | 287d0f897567fa7db30f6a6efa163bff1bc66124 (diff) |
have the outside remember, if it is the first frame
-rw-r--r-- | timestretch.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/timestretch.c b/timestretch.c index b15bfe7..1f94837 100644 --- a/timestretch.c +++ b/timestretch.c | |||
@@ -17,7 +17,9 @@ static size_t g_corr_length; | |||
17 | 17 | ||
18 | static size_t g_skip; // Per frame skip | 18 | static size_t g_skip; // Per frame skip |
19 | static size_t g_offset; // Offset into stream, lower bits | 19 | static size_t g_offset; // Offset into stream, lower bits |
20 | static size_t g_firstframe; // If this is set, the caller should provide initial data in g_overlap_buffer | 20 | |
21 | #define FRAME_FIRST 0x01 | ||
22 | #define FRAME_LAST 0x02 | ||
21 | 23 | ||
22 | /* some good default for mixing voice, values in micro seconds */ | 24 | /* some good default for mixing voice, values in micro seconds */ |
23 | #define OVERLAP 10 // overlapping length (music default = 12 ms) | 25 | #define OVERLAP 10 // overlapping length (music default = 12 ms) |
@@ -33,7 +35,6 @@ static size_t calc_convert_values( int sample_rate, float tempo ) { | |||
33 | 35 | ||
34 | free( g_overlap_buffer ); | 36 | free( g_overlap_buffer ); |
35 | g_overlap_buffer = malloc( sizeof(short) * g_overlap ); | 37 | g_overlap_buffer = malloc( sizeof(short) * g_overlap ); |
36 | g_firstframe = 1; | ||
37 | g_offset = 0; | 38 | g_offset = 0; |
38 | 39 | ||
39 | g_output_length = (sample_rate * OUTPUT_LEN ) / 1000; | 40 | g_output_length = (sample_rate * OUTPUT_LEN ) / 1000; |
@@ -47,7 +48,7 @@ static size_t calc_convert_values( int sample_rate, float tempo ) { | |||
47 | // boost middle of sequence by top of a flat parabola | 48 | // boost middle of sequence by top of a flat parabola |
48 | // slope stolen from soundtouch, precalc table | 49 | // slope stolen from soundtouch, precalc table |
49 | for( i = 0; i < g_corr_length; ++i ) | 50 | for( i = 0; i < g_corr_length; ++i ) |
50 | 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); | 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 | 52 | ||
52 | g_skip = (size_t)( tempo * (float)g_output_length * 65536.0 ); | 53 | g_skip = (size_t)( tempo * (float)g_output_length * 65536.0 ); |
53 | g_input_length = g_corr_length + g_output_length + g_overlap; | 54 | g_input_length = g_corr_length + g_output_length + g_overlap; |
@@ -88,16 +89,15 @@ static unsigned int find_corr_max(const short *input, const short *mixbuf) { | |||
88 | } | 89 | } |
89 | 90 | ||
90 | // Returns the amount of samples that can be discarded from begin of the input buffer | 91 | // Returns the amount of samples that can be discarded from begin of the input buffer |
91 | size_t process_frame( short *input, short *output, short *overlap, int lastframe ) { | 92 | size_t process_frame( short *input, short *output, short *overlap, int frame_flag ) { |
92 | int i, i_ = (int)g_overlap; | 93 | int i, i_ = (int)g_overlap; |
93 | unsigned int offset = 0; | 94 | unsigned int offset = 0; |
94 | 95 | ||
95 | // The first frame needs to be copied verbatim, | 96 | // The first frame needs to be copied verbatim, |
96 | // we do not have anything to mix, yet. | 97 | // we do not have anything to mix, yet. |
97 | if( g_firstframe ) { | 98 | if( frame_flag & FRAME_FIRST ) |
98 | sampcpy( output, input, g_output_length ); | 99 | sampcpy( output, input, g_output_length ); |
99 | g_firstframe = 0; | 100 | else { |
100 | } else { | ||
101 | offset = find_corr_max( input, overlap ); | 101 | offset = find_corr_max( input, overlap ); |
102 | 102 | ||
103 | // Cross fade end of last frame with begin of this frame | 103 | // Cross fade end of last frame with begin of this frame |
@@ -109,7 +109,7 @@ size_t process_frame( short *input, short *output, short *overlap, int lastframe | |||
109 | } | 109 | } |
110 | 110 | ||
111 | // On the last frame help connect the next frame from input seamlessly | 111 | // On the last frame help connect the next frame from input seamlessly |
112 | if( lastframe ) | 112 | if( frame_flag & FRAME_LAST ) |
113 | return offset + g_output_length; | 113 | return offset + g_output_length; |
114 | 114 | ||
115 | // Remember end of this frame for next frame | 115 | // Remember end of this frame for next frame |
@@ -126,14 +126,13 @@ int main( int args, char **argv ) { | |||
126 | size_t in_fill = 0; | 126 | size_t in_fill = 0; |
127 | short outbuf[ g_output_length ]; | 127 | short outbuf[ g_output_length ]; |
128 | short inbuf [ g_input_length ]; | 128 | short inbuf [ g_input_length ]; |
129 | int fd_in = open( "in.raw", O_RDONLY ); | ||
130 | int fd_out = open( "out.raw", O_CREAT | O_WRONLY | O_TRUNC ); | ||
131 | int first_frame = FRAME_FIRST; | ||
132 | (void)args; (void)argv; (void)out_chunk_size; | ||
129 | 133 | ||
130 | // printf( "DEBUG: OL: %zd SWL: %zd SL: %zd SK: %zd ICM: %zd\n", g_overlap, g_output_length, g_corr_length, g_skip / 65536, g_input_length ); | 134 | // printf( "DEBUG: OL: %zd SWL: %zd SL: %zd SK: %zd ICM: %zd\n", g_overlap, g_output_length, g_corr_length, g_skip / 65536, g_input_length ); |
131 | 135 | ||
132 | int fd_in = open( "in.raw", O_RDONLY ); | ||
133 | int fd_out = open( "out.raw", O_CREAT | O_WRONLY | O_TRUNC ); | ||
134 | |||
135 | (void)args; (void)argv; (void)out_chunk_size; | ||
136 | |||
137 | while( 1 ) { | 136 | while( 1 ) { |
138 | size_t processed; | 137 | size_t processed; |
139 | size_t missing = g_input_length - in_fill; | 138 | size_t missing = g_input_length - in_fill; |
@@ -148,7 +147,8 @@ int main( int args, char **argv ) { | |||
148 | } | 147 | } |
149 | 148 | ||
150 | // Do one cycle of processing and outputting | 149 | // Do one cycle of processing and outputting |
151 | processed = process_frame( inbuf, outbuf, g_overlap_buffer, 0 ); | 150 | processed = process_frame( inbuf, outbuf, g_overlap_buffer, first_frame ); |
151 | first_frame = 0; | ||
152 | write( fd_out, outbuf, g_output_length * sizeof(short) ); | 152 | write( fd_out, outbuf, g_output_length * sizeof(short) ); |
153 | 153 | ||
154 | memmove( inbuf, inbuf + processed, ( in_fill - processed ) * sizeof(short) ); | 154 | memmove( inbuf, inbuf + processed, ( in_fill - processed ) * sizeof(short) ); |