annotate libaf/af_scaletempo.c @ 25317:7f3cb5408f28

Fixed VIDIX color bug that was introduced when Radeon VIDIX driver was synchronized with vidix.sf.net. The red color was saturating. Corrected value fixes the issue and restore the color to the level it used to have before synchronization. Meaning of the value remains unknow but was retrieved from register's value of a Radeon 9000 card, so it may need further testing. Patch by Guillaume Lecerf (foxcore at gmail dot com)
author ben
date Mon, 10 Dec 2007 19:27:46 +0000
parents 32b0428fbd5a
children b3a38b361fef
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
1 /*
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
2 * scaletempo audio filter
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
3 * Copyright (c) 2007 Robert Juliano
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
4 *
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
5 * This file is part of MPlayer.
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
6 *
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
7 * MPlayer is free software; you can redistribute it and/or modify
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
8 * it under the terms of the GNU General Public License as published by
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
9 * the Free Software Foundation; either version 2 of the License, or
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
10 * (at your option) any later version.
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
11 *
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
12 * MPlayer is distributed in the hope that it will be useful,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
15 * GNU General Public License for more details.
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
16 *
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
17 * You should have received a copy of the GNU General Public License
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
18 * along with MPlayer; if not, write to the Free Software
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
20 *
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
21 * scale tempo while maintaining pitch
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
22 * (WSOLA technique with cross correlation)
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
23 * inspired by SoundTouch library by Olli Parviainen
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
24 *
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
25 * basic algorithm
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
26 * - produce 'stride' output samples per loop
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
27 * - consume stride*scale input samples per loop
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
28 *
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
29 * to produce smoother transitions between strides, blend next overlap
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
30 * samples from last stride with correlated samples of current input
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
31 *
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
32 */
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
33
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
34 #include <stdlib.h>
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
35 #include <string.h>
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
36 #include <limits.h>
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
37
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
38 #include "af.h"
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
39 #include "libavutil/common.h"
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
40 #include "subopt-helper.h"
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
41 #include "help_mp.h"
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
42
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
43 // Data for specific instances of this filter
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
44 typedef struct af_scaletempo_s
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
45 {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
46 // stride
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
47 float scale;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
48 float speed;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
49 float frames_stride_scaled;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
50 float frames_stride_error;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
51 int bytes_per_frame;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
52 int bytes_stride;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
53 float bytes_stride_scaled;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
54 int bytes_queue;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
55 int bytes_queued;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
56 int bytes_to_slide;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
57 int8_t* buf_queue;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
58 // overlap
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
59 int samples_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
60 int samples_standing;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
61 int bytes_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
62 int bytes_standing;
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
63 void* buf_overlap;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
64 void* table_blend;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
65 void (*output_overlap)(struct af_scaletempo_s* s, void* out_buf, int bytes_off);
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
66 // best overlap
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
67 int frames_search;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
68 int num_channels;
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
69 void* buf_pre_corr;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
70 void* table_window;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
71 int (*best_overlap_offset)(struct af_scaletempo_s* s);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
72 // command line
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
73 float scale_nominal;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
74 float ms_stride;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
75 float percent_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
76 float ms_search;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
77 short speed_tempo;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
78 short speed_pitch;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
79 } af_scaletempo_t;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
80
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
81 static int fill_queue(struct af_instance_s* af, af_data_t* data, int offset)
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
82 {
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
83 af_scaletempo_t* s = af->setup;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
84 int bytes_in = data->len - offset;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
85 int offset_unchanged = offset;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
86
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
87 if (s->bytes_to_slide > 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
88 if (s->bytes_to_slide < s->bytes_queued) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
89 int bytes_move = s->bytes_queued - s->bytes_to_slide;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
90 memmove(s->buf_queue,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
91 s->buf_queue + s->bytes_to_slide,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
92 bytes_move);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
93 s->bytes_to_slide = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
94 s->bytes_queued = bytes_move;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
95 } else {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
96 int bytes_skip;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
97 s->bytes_to_slide -= s->bytes_queued;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
98 bytes_skip = FFMIN(s->bytes_to_slide, bytes_in);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
99 s->bytes_queued = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
100 s->bytes_to_slide -= bytes_skip;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
101 offset += bytes_skip;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
102 bytes_in -= bytes_skip;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
103 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
104 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
105
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
106 if (bytes_in > 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
107 int bytes_copy = FFMIN(s->bytes_queue - s->bytes_queued, bytes_in);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
108 memcpy(s->buf_queue + s->bytes_queued,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
109 (int8_t*)data->audio + offset,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
110 bytes_copy);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
111 s->bytes_queued += bytes_copy;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
112 offset += bytes_copy;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
113 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
114
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
115 return offset - offset_unchanged;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
116 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
117
25076
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
118 #define UNROLL_PADDING (4*4)
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
119
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
120 static int best_overlap_offset_float(af_scaletempo_t* s)
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
121 {
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
122 float *pw, *po, *ppc, *search_start;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
123 float best_corr = INT_MIN;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
124 int best_off = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
125 int i, off;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
126
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
127 pw = s->table_window;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
128 po = s->buf_overlap;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
129 po += s->num_channels;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
130 ppc = s->buf_pre_corr;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
131 for (i=s->num_channels; i<s->samples_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
132 *ppc++ = *pw++ * *po++;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
133 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
134
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
135 search_start = (float*)s->buf_queue + s->num_channels;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
136 for (off=0; off<s->frames_search; off++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
137 float corr = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
138 float* ps = search_start;
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
139 ppc = s->buf_pre_corr;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
140 for (i=s->num_channels; i<s->samples_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
141 corr += *ppc++ * *ps++;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
142 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
143 if (corr > best_corr) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
144 best_corr = corr;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
145 best_off = off;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
146 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
147 search_start += s->num_channels;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
148 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
149
24897
d4a8f31df9ba af_scaletempo: Fix audio copy position
uau
parents: 24896
diff changeset
150 return best_off * 4 * s->num_channels;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
151 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
152
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
153 static int best_overlap_offset_s16(af_scaletempo_t* s)
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
154 {
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
155 int32_t *pw, *ppc;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
156 int16_t *po, *search_start;
25075
c18499a044ce Change to a 64 bit accumulation variable instead of shifting.
reimar
parents: 25074
diff changeset
157 int64_t best_corr = INT64_MIN;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
158 int best_off = 0;
25073
21227667b70a Use "long" instead of "int" for innermost loop variable.
reimar
parents: 25072
diff changeset
159 int off;
21227667b70a Use "long" instead of "int" for innermost loop variable.
reimar
parents: 25072
diff changeset
160 long i;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
161
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
162 pw = s->table_window;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
163 po = s->buf_overlap;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
164 po += s->num_channels;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
165 ppc = s->buf_pre_corr;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
166 for (i=s->num_channels; i<s->samples_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
167 *ppc++ = ( *pw++ * *po++ ) >> 15;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
168 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
169
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
170 search_start = (int16_t*)s->buf_queue + s->num_channels;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
171 for (off=0; off<s->frames_search; off++) {
25075
c18499a044ce Change to a 64 bit accumulation variable instead of shifting.
reimar
parents: 25074
diff changeset
172 int64_t corr = 0;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
173 int16_t* ps = search_start;
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
174 ppc = s->buf_pre_corr;
25075
c18499a044ce Change to a 64 bit accumulation variable instead of shifting.
reimar
parents: 25074
diff changeset
175 ppc += s->samples_overlap - s->num_channels;
c18499a044ce Change to a 64 bit accumulation variable instead of shifting.
reimar
parents: 25074
diff changeset
176 ps += s->samples_overlap - s->num_channels;
25072
6c3f9215d606 Rearrange scaletempo inner loop.
reimar
parents: 25070
diff changeset
177 i = -(s->samples_overlap - s->num_channels);
6c3f9215d606 Rearrange scaletempo inner loop.
reimar
parents: 25070
diff changeset
178 do {
25076
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
179 corr += ppc[i+0] * ps[i+0];
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
180 corr += ppc[i+1] * ps[i+1];
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
181 corr += ppc[i+2] * ps[i+2];
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
182 corr += ppc[i+3] * ps[i+3];
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
183 i += 4;
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
184 } while (i < 0);
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
185 if (corr > best_corr) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
186 best_corr = corr;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
187 best_off = off;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
188 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
189 search_start += s->num_channels;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
190 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
191
24897
d4a8f31df9ba af_scaletempo: Fix audio copy position
uau
parents: 24896
diff changeset
192 return best_off * 2 * s->num_channels;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
193 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
194
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
195 static void output_overlap_float(af_scaletempo_t* s, void* buf_out,
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
196 int bytes_off)
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
197 {
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
198 float* pout = buf_out;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
199 float* pb = s->table_blend;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
200 float* po = s->buf_overlap;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
201 float* pin = (float*)(s->buf_queue + bytes_off);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
202 int i;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
203 for (i=0; i<s->samples_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
204 *pout++ = *po - *pb++ * ( *po - *pin++ ); po++;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
205 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
206 }
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
207 static void output_overlap_s16(af_scaletempo_t* s, void* buf_out,
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
208 int bytes_off)
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
209 {
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
210 int16_t* pout = buf_out;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
211 int32_t* pb = s->table_blend;
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
212 int16_t* po = s->buf_overlap;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
213 int16_t* pin = (int16_t*)(s->buf_queue + bytes_off);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
214 int i;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
215 for (i=0; i<s->samples_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
216 *pout++ = *po - ( ( *pb++ * ( *po - *pin++ ) ) >> 16 ); po++;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
217 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
218 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
219
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
220 // Filter data through filter
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
221 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
222 {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
223 af_scaletempo_t* s = af->setup;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
224 int offset_in;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
225 int max_bytes_out;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
226 int8_t* pout;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
227
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
228 if (s->scale == 1.0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
229 return data;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
230 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
231
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
232 // RESIZE_LOCAL_BUFFER - can't use macro
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
233 max_bytes_out = ((int)(data->len / s->bytes_stride_scaled) + 1) * s->bytes_stride;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
234 if (max_bytes_out > af->data->len) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
235 af_msg(AF_MSG_VERBOSE, "[libaf] Reallocating memory in module %s, "
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
236 "old len = %i, new len = %i\n",af->info->name,af->data->len,max_bytes_out);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
237 af->data->audio = realloc(af->data->audio, max_bytes_out);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
238 if (!af->data->audio) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
239 af_msg(AF_MSG_FATAL, "[libaf] Could not allocate memory\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
240 return NULL;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
241 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
242 af->data->len = max_bytes_out;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
243 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
244
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
245 offset_in = fill_queue(af, data, 0);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
246 pout = af->data->audio;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
247 while (s->bytes_queued >= s->bytes_queue) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
248 int ti;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
249 float tf;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
250 int bytes_off = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
251
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
252 // output stride
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
253 if (s->output_overlap) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
254 if (s->best_overlap_offset)
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
255 bytes_off = s->best_overlap_offset(s);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
256 s->output_overlap(s, pout, bytes_off);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
257 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
258 memcpy(pout + s->bytes_overlap,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
259 s->buf_queue + bytes_off + s->bytes_overlap,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
260 s->bytes_standing);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
261 pout += s->bytes_stride;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
262
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
263 // input stride
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
264 memcpy(s->buf_overlap,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
265 s->buf_queue + bytes_off + s->bytes_stride,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
266 s->bytes_overlap);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
267 tf = s->frames_stride_scaled + s->frames_stride_error;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
268 ti = (int)tf;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
269 s->frames_stride_error = tf - ti;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
270 s->bytes_to_slide = ti * s->bytes_per_frame;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
271
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
272 offset_in += fill_queue(af, data, offset_in);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
273 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
274
24900
9079c9745ff9 A/V sync: take audio filter buffers into account
uau
parents: 24899
diff changeset
275 // This filter can have a negative delay when scale > 1:
9079c9745ff9 A/V sync: take audio filter buffers into account
uau
parents: 24899
diff changeset
276 // output corresponding to some length of input can be decided and written
9079c9745ff9 A/V sync: take audio filter buffers into account
uau
parents: 24899
diff changeset
277 // after receiving only a part of that input.
9079c9745ff9 A/V sync: take audio filter buffers into account
uau
parents: 24899
diff changeset
278 af->delay = s->bytes_queued - s->bytes_to_slide;
9079c9745ff9 A/V sync: take audio filter buffers into account
uau
parents: 24899
diff changeset
279
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
280 data->audio = af->data->audio;
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
281 data->len = pout - (int8_t *)af->data->audio;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
282 return data;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
283 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
284
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
285 // Initialization and runtime control
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
286 static int control(struct af_instance_s* af, int cmd, void* arg)
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
287 {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
288 af_scaletempo_t* s = af->setup;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
289 switch(cmd){
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
290 case AF_CONTROL_REINIT:{
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
291 af_data_t* data = (af_data_t*)arg;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
292 float srate = data->rate / 1000;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
293 int nch = data->nch;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
294 int bps;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
295 int use_int = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
296 int frames_stride, frames_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
297 int i, j;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
298
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
299 af_msg(AF_MSG_VERBOSE,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
300 "[scaletempo] %.3f speed * %.3f scale_nominal = %.3f\n",
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
301 s->speed, s->scale_nominal, s->scale);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
302
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
303 if (s->scale == 1.0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
304 if (s->speed_tempo && s->speed_pitch)
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
305 return AF_DETACH;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
306 memcpy(af->data, data, sizeof(af_data_t));
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
307 return af_test_output(af, data);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
308 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
309
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
310 af->data->rate = data->rate;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
311 af->data->nch = data->nch;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
312 if ( data->format == AF_FORMAT_S16_LE
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
313 || data->format == AF_FORMAT_S16_BE ) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
314 use_int = 1;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
315 af->data->format = AF_FORMAT_S16_NE;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
316 af->data->bps = bps = 2;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
317 } else {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
318 af->data->format = AF_FORMAT_FLOAT_NE;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
319 af->data->bps = bps = 4;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
320 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
321
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
322 frames_stride = srate * s->ms_stride;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
323 s->bytes_stride = frames_stride * bps * nch;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
324 s->bytes_stride_scaled = s->scale * s->bytes_stride;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
325 s->frames_stride_scaled = s->scale * frames_stride;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
326 s->frames_stride_error = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
327 af->mul = (double)s->bytes_stride / s->bytes_stride_scaled;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
328
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
329 frames_overlap = frames_stride * s->percent_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
330 if (frames_overlap <= 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
331 s->bytes_standing = s->bytes_stride;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
332 s->samples_standing = s->bytes_standing / bps;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
333 s->output_overlap = NULL;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
334 } else {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
335 s->samples_overlap = frames_overlap * nch;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
336 s->bytes_overlap = frames_overlap * nch * bps;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
337 s->bytes_standing = s->bytes_stride - s->bytes_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
338 s->samples_standing = s->bytes_standing / bps;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
339 s->buf_overlap = realloc(s->buf_overlap, s->bytes_overlap);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
340 s->table_blend = realloc(s->table_blend, s->bytes_overlap * 4);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
341 if(!s->buf_overlap || !s->table_blend) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
342 af_msg(AF_MSG_FATAL, "[scaletempo] Out of memory\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
343 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
344 }
25188
32b0428fbd5a 100l, bzero is deprecated, use memset instead
reimar
parents: 25076
diff changeset
345 memset(s->buf_overlap, 0, s->bytes_overlap);
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
346 if (use_int) {
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
347 int32_t* pb = s->table_blend;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
348 int64_t blend = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
349 for (i=0; i<frames_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
350 int32_t v = blend / frames_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
351 for (j=0; j<nch; j++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
352 *pb++ = v;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
353 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
354 blend += 65536; // 2^16
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
355 }
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
356 s->output_overlap = output_overlap_s16;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
357 } else {
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
358 float* pb = s->table_blend;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
359 for (i=0; i<frames_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
360 float v = i / (float)frames_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
361 for (j=0; j<nch; j++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
362 *pb++ = v;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
363 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
364 }
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
365 s->output_overlap = output_overlap_float;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
366 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
367 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
368
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
369 s->frames_search = (frames_overlap > 1) ? srate * s->ms_search : 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
370 if (s->frames_search <= 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
371 s->best_overlap_offset = NULL;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
372 } else {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
373 if (use_int) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
374 int64_t t = frames_overlap;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
375 int32_t n = 8589934588LL / (t * t); // 4 * (2^31 - 1) / t^2
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
376 int32_t* pw;
25076
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
377 s->buf_pre_corr = realloc(s->buf_pre_corr, s->bytes_overlap * 2 + UNROLL_PADDING);
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
378 s->table_window = realloc(s->table_window, s->bytes_overlap * 2 - nch * bps * 2);
25070
60b34bf9a41e 100l, someone mixed up && and ||, so if allocation of only one buffers failed
reimar
parents: 25069
diff changeset
379 if(!s->buf_pre_corr || !s->table_window) {
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
380 af_msg(AF_MSG_FATAL, "[scaletempo] Out of memory\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
381 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
382 }
25076
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
383 memset((char *)s->buf_pre_corr + s->bytes_overlap * 2, 0, UNROLL_PADDING);
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
384 pw = s->table_window;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
385 for (i=1; i<frames_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
386 int32_t v = ( i * (t - i) * n ) >> 15;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
387 for (j=0; j<nch; j++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
388 *pw++ = v;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
389 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
390 }
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
391 s->best_overlap_offset = best_overlap_offset_s16;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
392 } else {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
393 float* pw;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
394 s->buf_pre_corr = realloc(s->buf_pre_corr, s->bytes_overlap);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
395 s->table_window = realloc(s->table_window, s->bytes_overlap - nch * bps);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
396 if(!s->buf_pre_corr || !s->table_window) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
397 af_msg(AF_MSG_FATAL, "[scaletempo] Out of memory\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
398 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
399 }
25069
d2f7027f0556 Avoid some casts by changing int8_t* to void* in af_scaletempo
reimar
parents: 24900
diff changeset
400 pw = s->table_window;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
401 for (i=1; i<frames_overlap; i++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
402 float v = i * (frames_overlap - i);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
403 for (j=0; j<nch; j++) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
404 *pw++ = v;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
405 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
406 }
24899
3245638ab801 af_scaletempo: code cleanup
uau
parents: 24898
diff changeset
407 s->best_overlap_offset = best_overlap_offset_float;
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
408 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
409 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
410
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
411 s->bytes_per_frame = bps * nch;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
412 s->num_channels = nch;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
413
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
414 s->bytes_queue
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
415 = (s->frames_search + frames_stride + frames_overlap) * bps * nch;
25076
dfd3c5702d32 Add padding and unroll loop 4x for at least another 10% speedup
reimar
parents: 25075
diff changeset
416 s->buf_queue = realloc(s->buf_queue, s->bytes_queue + UNROLL_PADDING);
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
417 if(!s->buf_queue) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
418 af_msg(AF_MSG_FATAL, "[scaletempo] Out of memory\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
419 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
420 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
421
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
422 af_msg (AF_MSG_DEBUG0, "[scaletempo] "
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
423 "%.2f stride_in, %i stride_out, %i standing, "
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
424 "%i overlap, %i search, %i queue, %s mode\n",
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
425 s->frames_stride_scaled,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
426 (int)(s->bytes_stride / nch / bps),
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
427 (int)(s->bytes_standing / nch / bps),
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
428 (int)(s->bytes_overlap / nch / bps),
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
429 s->frames_search,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
430 (int)(s->bytes_queue / nch / bps),
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
431 (use_int?"s16":"float"));
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
432
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
433 return af_test_output(af, (af_data_t*)arg);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
434 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
435 case AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET:{
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
436 if (s->speed_tempo) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
437 if (s->speed_pitch) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
438 break;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
439 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
440 s->speed = *(float*)arg;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
441 s->scale = s->speed * s->scale_nominal;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
442 } else {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
443 if (s->speed_pitch) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
444 s->speed = 1 / *(float*)arg;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
445 s->scale = s->speed * s->scale_nominal;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
446 break;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
447 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
448 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
449 return AF_OK;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
450 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
451 case AF_CONTROL_SCALETEMPO_AMOUNT | AF_CONTROL_SET:{
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
452 s->scale = *(float*)arg;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
453 s->scale = s->speed * s->scale_nominal;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
454 return AF_OK;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
455 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
456 case AF_CONTROL_SCALETEMPO_AMOUNT | AF_CONTROL_GET:
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
457 *(float*)arg = s->scale;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
458 return AF_OK;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
459 case AF_CONTROL_COMMAND_LINE:{
24898
0701957d2bf7 af_scaletempo: Fix crash in option parsing
uau
parents: 24897
diff changeset
460 strarg_t speed = {};
24896
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
461 opt_t subopts[] = {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
462 {"scale", OPT_ARG_FLOAT, &s->scale_nominal, NULL},
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
463 {"stride", OPT_ARG_FLOAT, &s->ms_stride, NULL},
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
464 {"overlap", OPT_ARG_FLOAT, &s->percent_overlap, NULL},
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
465 {"search", OPT_ARG_FLOAT, &s->ms_search, NULL},
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
466 {"speed", OPT_ARG_STR, &speed, NULL},
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
467 {NULL},
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
468 };
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
469 if (subopt_parse(arg, subopts) != 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
470 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
471 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
472 if (s->scale_nominal <= 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
473 af_msg(AF_MSG_ERROR, "[scaletempo] "
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
474 MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
475 ": scale > 0\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
476 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
477 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
478 if (s->ms_stride <= 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
479 af_msg(AF_MSG_ERROR, "[scaletempo] "
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
480 MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
481 ": stride > 0\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
482 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
483 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
484 if (s->percent_overlap < 0 || s->percent_overlap > 1) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
485 af_msg(AF_MSG_ERROR, "[scaletempo] "
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
486 MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
487 ": 0 <= overlap <= 1\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
488 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
489 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
490 if (s->ms_search < 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
491 af_msg(AF_MSG_ERROR, "[scaletempo] "
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
492 MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
493 ": search >= 0\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
494 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
495 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
496 if (speed.len > 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
497 if (strcmp(speed.str, "pitch") == 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
498 s->speed_tempo = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
499 s->speed_pitch = 1;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
500 } else if (strcmp(speed.str, "tempo") == 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
501 s->speed_tempo = 1;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
502 s->speed_pitch = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
503 } else if (strcmp(speed.str, "none") == 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
504 s->speed_tempo = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
505 s->speed_pitch = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
506 } else if (strcmp(speed.str, "both") == 0) {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
507 s->speed_tempo = 1;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
508 s->speed_pitch = 1;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
509 } else {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
510 af_msg(AF_MSG_ERROR, "[scaletempo] "
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
511 MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
512 ": speed=[pitch|tempo|none|both]\n");
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
513 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
514 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
515 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
516 s->scale = s->speed * s->scale_nominal;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
517 af_msg(AF_MSG_DEBUG0, "[scaletempo] %6.3f scale, %6.2f stride, %6.2f overlap, %6.2f search, speed = %s\n", s->scale_nominal, s->ms_stride, s->percent_overlap, s->ms_search, (s->speed_tempo?(s->speed_pitch?"tempo and speed":"tempo"):(s->speed_pitch?"pitch":"none")));
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
518 return AF_OK;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
519 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
520 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
521 return AF_UNKNOWN;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
522 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
523
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
524 // Deallocate memory
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
525 static void uninit(struct af_instance_s* af)
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
526 {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
527 af_scaletempo_t* s = af->setup;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
528 free(af->data->audio);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
529 free(af->data);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
530 free(s->buf_queue);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
531 free(s->buf_overlap);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
532 free(s->buf_pre_corr);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
533 free(s->table_blend);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
534 free(s->table_window);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
535 free(af->setup);
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
536 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
537
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
538 // Allocate memory and set function pointers
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
539 static int af_open(af_instance_t* af){
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
540 af_scaletempo_t* s;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
541
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
542 af->control = control;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
543 af->uninit = uninit;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
544 af->play = play;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
545 af->mul = 1;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
546 af->data = calloc(1,sizeof(af_data_t));
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
547 af->setup = calloc(1,sizeof(af_scaletempo_t));
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
548 if(af->data == NULL || af->setup == NULL)
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
549 return AF_ERROR;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
550
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
551 s = af->setup;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
552 s->scale = s->speed = s->scale_nominal = 1.0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
553 s->speed_tempo = 1;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
554 s->speed_pitch = 0;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
555 s->ms_stride = 60;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
556 s->percent_overlap = .20;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
557 s->ms_search = 14;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
558
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
559 return AF_OK;
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
560 }
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
561
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
562 // Description of this filter
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
563 af_info_t af_info_scaletempo = {
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
564 "Scale audio tempo while maintaining pitch",
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
565 "scaletempo",
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
566 "Robert Juliano",
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
567 "",
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
568 AF_FLAGS_REENTRANT,
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
569 af_open
8133163bd1dd Add audio filter scaletempo
uau
parents:
diff changeset
570 };