blob: 8c489fc8b768038ad9ebd7649a13e83c97e676ed [file] [log] [blame]
Benny Prijono5887d022008-02-29 12:05:33 +00001#include <pjmedia/wsola.h>
2#include <pj/log.h>
3#include <pj/pool.h>
4#include <pj/os.h>
5#include <stdio.h>
6#include <assert.h>
7
Benny Prijono98b6df82008-03-04 15:37:45 +00008#define CLOCK_RATE 16000
Benny Prijono5887d022008-02-29 12:05:33 +00009#define SAMPLES_PER_FRAME (10 * CLOCK_RATE / 1000)
10
11#define RESET() memset(buf1, 0, sizeof(buf1)), \
12 memset(buf2, 0, sizeof(buf2)), \
13 memset(frm1, 0, sizeof(frm1)), \
14 memset(frm2, 0, sizeof(frm2))
15
16#if 0
17void test_find_pitch(void)
18{
19 enum { ON = 111, FRM_PART_LEN=20 };
20 short buf2[SAMPLES_PER_FRAME*2], buf1[SAMPLES_PER_FRAME*2],
21 frm2[SAMPLES_PER_FRAME], frm1[SAMPLES_PER_FRAME];
22 short *ref, *pos;
23
24 /* Case 1. all contiguous */
25 RESET();
26 ref = buf1 + 10;
27 *ref = ON;
28 frm1[0] = ON;
29
30 pos = pjmedia_wsola_find_pitch(frm1, SAMPLES_PER_FRAME, NULL, 0,
31 buf1, SAMPLES_PER_FRAME*2, NULL, 0, PJ_TRUE);
32 assert(pos == ref);
33
34 /* Case 2: contiguous buffer, non-contiguous frame */
35 RESET();
36 ref = buf1 + 17;
37 *ref = ON;
38 *(ref+FRM_PART_LEN) = ON;
39 frm1[0] = ON;
40 frm2[0] = ON;
41
42 /* Noise */
43 buf1[0] = ON;
44
45 pos = pjmedia_wsola_find_pitch(frm1, FRM_PART_LEN, frm2, SAMPLES_PER_FRAME - FRM_PART_LEN,
46 buf1, SAMPLES_PER_FRAME*2, NULL, 0, PJ_TRUE);
47 assert(pos == ref);
48
49 /* Case 3: non-contiguous buffer, contiguous frame, found in buf1 */
50 RESET();
51 ref = buf1 + 17;
52 *ref = ON;
53 buf2[17] = ON;
54 frm1[0] = ON;
55 frm1[FRM_PART_LEN] = ON;
56
57 /* Noise */
58 buf1[0] = ON;
59
60 pos = pjmedia_wsola_find_pitch(frm1, SAMPLES_PER_FRAME, NULL, 0,
61 buf1, FRM_PART_LEN,
62 buf2, SAMPLES_PER_FRAME,
63 PJ_TRUE);
64
65 assert(pos == ref);
66}
67#endif
68
69int expand(pj_pool_t *pool, const char *filein, const char *fileout,
70 int expansion_rate100, int lost_rate10, int lost_burst)
71{
72 enum { LOST_RATE = 10 };
73 FILE *in, *out;
74 short frame[SAMPLES_PER_FRAME];
75 pjmedia_wsola *wsola;
76 pj_timestamp elapsed, zero;
77 unsigned samples;
78 int last_lost = 0;
79
80 /* Lost burst must be > 0 */
81 assert(lost_rate10==0 || lost_burst > 0);
82
83 in = fopen(filein, "rb");
84 if (!in) return 1;
85 out = fopen(fileout, "wb");
86 if (!out) return 1;
87
Benny Prijono98b6df82008-03-04 15:37:45 +000088 pjmedia_wsola_create(pool, CLOCK_RATE, SAMPLES_PER_FRAME, 1, 0, &wsola);
Benny Prijono5887d022008-02-29 12:05:33 +000089
90 samples = 0;
91 elapsed.u64 = 0;
92
93 while (fread(frame, SAMPLES_PER_FRAME*2, 1, in) == 1) {
94 pj_timestamp t1, t2;
95
96 if (lost_rate10 == 0) {
97
98 /* Expansion */
99 pj_get_timestamp(&t1);
100 pjmedia_wsola_save(wsola, frame, 0);
101 pj_get_timestamp(&t2);
102
103 pj_sub_timestamp(&t2, &t1);
104 pj_add_timestamp(&elapsed, &t2);
105
106 fwrite(frame, SAMPLES_PER_FRAME*2, 1, out);
107
108 samples += SAMPLES_PER_FRAME;
109
110 if ((rand() % 100) < expansion_rate100) {
111
112 pj_get_timestamp(&t1);
113 pjmedia_wsola_generate(wsola, frame);
114 pj_get_timestamp(&t2);
115
116 pj_sub_timestamp(&t2, &t1);
117 pj_add_timestamp(&elapsed, &t2);
118
119 samples += SAMPLES_PER_FRAME;
120
121 fwrite(frame, SAMPLES_PER_FRAME*2, 1, out);
122 }
123
124 } else {
125 /* Lost */
126
127 if ((rand() % 10) < lost_rate10) {
128 int burst;
129
130 for (burst=0; burst<lost_burst; ++burst) {
131 pj_get_timestamp(&t1);
132 pjmedia_wsola_generate(wsola, frame);
133 pj_get_timestamp(&t2);
134
135 pj_sub_timestamp(&t2, &t1);
136 pj_add_timestamp(&elapsed, &t2);
137
138 samples += SAMPLES_PER_FRAME;
139
140 fwrite(frame, SAMPLES_PER_FRAME*2, 1, out);
141 }
142 last_lost = 1;
143 } else {
144 pj_get_timestamp(&t1);
145 pjmedia_wsola_save(wsola, frame, last_lost);
146 pj_get_timestamp(&t2);
147
148 pj_sub_timestamp(&t2, &t1);
149 pj_add_timestamp(&elapsed, &t2);
150
151 samples += SAMPLES_PER_FRAME;
152
153 fwrite(frame, SAMPLES_PER_FRAME*2, 1, out);
154 last_lost = 0;
155 }
156
157 }
158
159 }
160
161 zero.u64 = 0;
162 zero.u64 = pj_elapsed_usec(&zero, &elapsed);
163
164 zero.u64 = samples * PJ_INT64(1000000) / zero.u64;
165 assert(zero.u32.hi == 0);
166
167 PJ_LOG(3,("test.c", "Processing: %f Msamples per second",
168 zero.u32.lo/1000000.0));
169 PJ_LOG(3,("test.c", "CPU load for current settings: %f%%",
170 CLOCK_RATE * 100.0 / zero.u32.lo));
171
172 pjmedia_wsola_destroy(wsola);
173 fclose(in);
174 fclose(out);
175
176 return 0;
177}
178
179static void save_file(const char *file,
180 short frame[], unsigned count)
181{
182 FILE *f = fopen(file, "wb");
183 fwrite(frame, count, 2, f);
184 fclose(f);
185}
186
187int compress(pj_pool_t *pool,
188 const char *filein, const char *fileout,
189 int rate10)
190{
191 enum { BUF_CNT = SAMPLES_PER_FRAME * 10 };
192 FILE *in, *out;
193 pjmedia_wsola *wsola;
194 short buf[BUF_CNT];
195 pj_timestamp elapsed, zero;
196 unsigned samples = 0;
197
198 in = fopen(filein, "rb");
199 if (!in) return 1;
200 out = fopen(fileout, "wb");
201 if (!out) return 1;
202
Benny Prijono98b6df82008-03-04 15:37:45 +0000203 pjmedia_wsola_create(pool, CLOCK_RATE, SAMPLES_PER_FRAME, 1, 0, &wsola);
Benny Prijono5887d022008-02-29 12:05:33 +0000204
205 elapsed.u64 = 0;
206
207 for (;;) {
208 unsigned size_del, count;
209 pj_timestamp t1, t2;
210 int i;
211
212 if (fread(buf, sizeof(buf), 1, in) != 1)
213 break;
214
215 count = BUF_CNT;
216 size_del = 0;
217 pj_get_timestamp(&t1);
218
219 for (i=0; i<rate10; ++i) {
220 unsigned to_del = SAMPLES_PER_FRAME;
221#if 0
222 /* Method 1: buf1 contiguous */
223 pjmedia_wsola_discard(wsola, buf, count, NULL, 0, &to_del);
224#elif 0
225 /* Method 2: split, majority in buf1 */
226 assert(count > SAMPLES_PER_FRAME);
227 pjmedia_wsola_discard(wsola, buf, count-SAMPLES_PER_FRAME,
228 buf+count-SAMPLES_PER_FRAME, SAMPLES_PER_FRAME,
229 &to_del);
230#elif 0
231 /* Method 3: split, majority in buf2 */
232 assert(count > SAMPLES_PER_FRAME);
233 pjmedia_wsola_discard(wsola, buf, SAMPLES_PER_FRAME,
234 buf+SAMPLES_PER_FRAME, count-SAMPLES_PER_FRAME,
235 &to_del);
236#elif 1
237 /* Method 4: split, each with small length */
238 enum { TOT_LEN = 3 * SAMPLES_PER_FRAME };
239 unsigned buf1_len = (rand() % TOT_LEN);
240 short *ptr = buf + count - TOT_LEN;
241 assert(count > TOT_LEN);
242 if (buf1_len==0) buf1_len=SAMPLES_PER_FRAME*2;
243 pjmedia_wsola_discard(wsola, ptr, buf1_len,
244 ptr+buf1_len, TOT_LEN-buf1_len,
245 &to_del);
246#endif
247 count -= to_del;
248 size_del += to_del;
249 }
250 pj_get_timestamp(&t2);
251
252 samples += BUF_CNT;
253
254 pj_sub_timestamp(&t2, &t1);
255 pj_add_timestamp(&elapsed, &t2);
256
257 assert(size_del >= SAMPLES_PER_FRAME);
258
259 fwrite(buf, count, 2, out);
260 }
261
262 pjmedia_wsola_destroy(wsola);
263 fclose(in);
264 fclose(out);
265
266 zero.u64 = 0;
267 zero.u64 = pj_elapsed_usec(&zero, &elapsed);
268
269 zero.u64 = samples * PJ_INT64(1000000) / zero.u64;
270 assert(zero.u32.hi == 0);
271
272 PJ_LOG(3,("test.c", "Processing: %f Msamples per second",
273 zero.u32.lo/1000000.0));
274 PJ_LOG(3,("test.c", "CPU load for current settings: %f%%",
275 CLOCK_RATE * 100.0 / zero.u32.lo));
276
277 return 0;
278}
279
280
281static void mem_test(pj_pool_t *pool)
282{
283 char unused[1024];
284 short *frame = pj_pool_alloc(pool, 240+4*160);
285 pj_timestamp elapsed, zero, t1, t2;
286 unsigned samples = 0;
287
288 elapsed.u64 = 0;
289 while (samples < 50000000) {
290
291 pj_get_timestamp(&t1);
292 pjmedia_move_samples(frame, frame+160, 240+2*160);
293 pj_get_timestamp(&t2);
294 pj_sub_timestamp(&t2, &t1);
295
296 elapsed.u64 += t2.u64;
297
298 memset(unused, 0, sizeof(unused));
299 samples += 160;
300 }
301
302
303
304
305 zero.u64 = 0;
306 zero.u64 = pj_elapsed_usec(&zero, &elapsed);
307
308 zero.u64 = samples * PJ_INT64(1000000) / zero.u64;
309 assert(zero.u32.hi == 0);
310
311 PJ_LOG(3,("test.c", "Processing: %f Msamples per second",
312 zero.u32.lo/1000000.0));
313 PJ_LOG(3,("test.c", "CPU load for current settings: %f%%",
314 CLOCK_RATE * 100.0 / zero.u32.lo));
315
316}
317
318int main()
319{
320 pj_caching_pool cp;
321 pj_pool_t *pool;
Benny Prijono98b6df82008-03-04 15:37:45 +0000322 int i, rc;
Benny Prijono5887d022008-02-29 12:05:33 +0000323
324 //test_find_pitch();
325
326 pj_init();
327 pj_caching_pool_init(&cp, NULL, 0);
328 pool = pj_pool_create(&cp.factory, "", 1000, 1000, NULL);
329
Benny Prijono5887d022008-02-29 12:05:33 +0000330 srand(2);
331
Benny Prijono98b6df82008-03-04 15:37:45 +0000332 rc = expand(pool, "galileo16.pcm", "temp1.pcm", 20, 0, 0);
333 rc = compress(pool, "temp1.pcm", "output.pcm", 1);
334
335 for (i=0; i<2; ++i) {
336 rc = expand(pool, "output.pcm", "temp1.pcm", 20, 0, 0);
337 rc = compress(pool, "temp1.pcm", "output.pcm", 1);
338 }
Benny Prijono5887d022008-02-29 12:05:33 +0000339
340 if (rc != 0) {
341 puts("Error");
342 return 1;
343 }
344
345#if 0
346 {
347 char s[10];
348 puts("Press ENTER to quit");
349 fgets(s, sizeof(s), stdin);
350 }
351#endif
352
353 return 0;
354}