bluetooth: Remove commented out code.
[profile/ivi/pulseaudio-panda.git] / src / tests / resampler-test.c
1 /***
2   This file is part of PulseAudio.
3
4   PulseAudio is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as published
6   by the Free Software Foundation; either version 2.1 of the License,
7   or (at your option) any later version.
8
9   PulseAudio is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with PulseAudio; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA.
18 ***/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #include <getopt.h>
26 #include <locale.h>
27
28 #include <pulse/pulseaudio.h>
29
30 #include <pulse/rtclock.h>
31 #include <pulse/sample.h>
32 #include <pulse/volume.h>
33
34 #include <pulsecore/i18n.h>
35 #include <pulsecore/log.h>
36 #include <pulsecore/resampler.h>
37 #include <pulsecore/macro.h>
38 #include <pulsecore/endianmacros.h>
39 #include <pulsecore/memblock.h>
40 #include <pulsecore/sample-util.h>
41 #include <pulsecore/core-util.h>
42
43 static void dump_block(const char *label, const pa_sample_spec *ss, const pa_memchunk *chunk) {
44     void *d;
45     unsigned i;
46
47     if (getenv("MAKE_CHECK"))
48         return;
49     printf("%s:  \t", label);
50
51     d = pa_memblock_acquire(chunk->memblock);
52
53     switch (ss->format) {
54
55         case PA_SAMPLE_U8:
56         case PA_SAMPLE_ULAW:
57         case PA_SAMPLE_ALAW: {
58             uint8_t *u = d;
59
60             for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
61                 printf("      0x%02x ", *(u++));
62
63             break;
64         }
65
66         case PA_SAMPLE_S16NE:
67         case PA_SAMPLE_S16RE: {
68             uint16_t *u = d;
69
70             for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
71                 printf("    0x%04x ", *(u++));
72
73             break;
74         }
75
76         case PA_SAMPLE_S32NE:
77         case PA_SAMPLE_S32RE: {
78             uint32_t *u = d;
79
80             for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
81                 printf("0x%08x ", *(u++));
82
83             break;
84         }
85
86         case PA_SAMPLE_S24_32NE:
87         case PA_SAMPLE_S24_32RE: {
88             uint32_t *u = d;
89
90             for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
91                 printf("0x%08x ", *(u++));
92
93             break;
94         }
95
96         case PA_SAMPLE_FLOAT32NE:
97         case PA_SAMPLE_FLOAT32RE: {
98             float *u = d;
99
100             for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
101                 printf("%4.3g ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_FLOAT32_SWAP(*u));
102                 u++;
103             }
104
105             break;
106         }
107
108         case PA_SAMPLE_S24LE:
109         case PA_SAMPLE_S24BE: {
110             uint8_t *u = d;
111
112             for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
113                 printf("  0x%06x ", PA_READ24NE(u));
114                 u += pa_frame_size(ss);
115             }
116
117             break;
118         }
119
120         default:
121             pa_assert_not_reached();
122     }
123
124     printf("\n");
125
126     pa_memblock_release(chunk->memblock);
127 }
128
129 static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
130     pa_memblock *r;
131     void *d;
132     unsigned i;
133
134     pa_assert_se(r = pa_memblock_new(pool, pa_frame_size(ss) * 10));
135     d = pa_memblock_acquire(r);
136
137     switch (ss->format) {
138
139         case PA_SAMPLE_U8:
140         case PA_SAMPLE_ULAW:
141         case PA_SAMPLE_ALAW: {
142             uint8_t *u = d;
143
144             u[0] = 0x00;
145             u[1] = 0xFF;
146             u[2] = 0x7F;
147             u[3] = 0x80;
148             u[4] = 0x9f;
149             u[5] = 0x3f;
150             u[6] = 0x1;
151             u[7] = 0xF0;
152             u[8] = 0x20;
153             u[9] = 0x21;
154             break;
155         }
156
157         case PA_SAMPLE_S16NE:
158         case PA_SAMPLE_S16RE: {
159             uint16_t *u = d;
160
161             u[0] = 0x0000;
162             u[1] = 0xFFFF;
163             u[2] = 0x7FFF;
164             u[3] = 0x8000;
165             u[4] = 0x9fff;
166             u[5] = 0x3fff;
167             u[6] = 0x1;
168             u[7] = 0xF000;
169             u[8] = 0x20;
170             u[9] = 0x21;
171             break;
172         }
173
174         case PA_SAMPLE_S32NE:
175         case PA_SAMPLE_S32RE: {
176             uint32_t *u = d;
177
178             u[0] = 0x00000001;
179             u[1] = 0xFFFF0002;
180             u[2] = 0x7FFF0003;
181             u[3] = 0x80000004;
182             u[4] = 0x9fff0005;
183             u[5] = 0x3fff0006;
184             u[6] =    0x10007;
185             u[7] = 0xF0000008;
186             u[8] =   0x200009;
187             u[9] =   0x21000A;
188             break;
189         }
190
191         case PA_SAMPLE_S24_32NE:
192         case PA_SAMPLE_S24_32RE: {
193             uint32_t *u = d;
194
195             u[0] = 0x000001;
196             u[1] = 0xFF0002;
197             u[2] = 0x7F0003;
198             u[3] = 0x800004;
199             u[4] = 0x9f0005;
200             u[5] = 0x3f0006;
201             u[6] =    0x107;
202             u[7] = 0xF00008;
203             u[8] =   0x2009;
204             u[9] =   0x210A;
205             break;
206         }
207
208         case PA_SAMPLE_FLOAT32NE:
209         case PA_SAMPLE_FLOAT32RE: {
210             float *u = d;
211
212             u[0] = 0.0f;
213             u[1] = -1.0f;
214             u[2] = 1.0f;
215             u[3] = 4711.0f;
216             u[4] = 0.222f;
217             u[5] = 0.33f;
218             u[6] = -.3f;
219             u[7] = 99.0f;
220             u[8] = -0.555f;
221             u[9] = -.123f;
222
223             if (ss->format == PA_SAMPLE_FLOAT32RE)
224                 for (i = 0; i < 10; i++)
225                     u[i] = PA_FLOAT32_SWAP(u[i]);
226
227             break;
228         }
229
230         case PA_SAMPLE_S24NE:
231         case PA_SAMPLE_S24RE: {
232             uint8_t *u = d;
233
234             PA_WRITE24NE(u,    0x000001);
235             PA_WRITE24NE(u+3,  0xFF0002);
236             PA_WRITE24NE(u+6,  0x7F0003);
237             PA_WRITE24NE(u+9,  0x800004);
238             PA_WRITE24NE(u+12, 0x9f0005);
239             PA_WRITE24NE(u+15, 0x3f0006);
240             PA_WRITE24NE(u+18,    0x107);
241             PA_WRITE24NE(u+21, 0xF00008);
242             PA_WRITE24NE(u+24,   0x2009);
243             PA_WRITE24NE(u+27,   0x210A);
244             break;
245         }
246
247         default:
248             pa_assert_not_reached();
249     }
250
251     pa_memblock_release(r);
252
253     return r;
254 }
255
256 static void help(const char *argv0) {
257     printf(_("%s [options]\n\n"
258              "-h, --help                            Show this help\n"
259              "-v, --verbose                         Print debug messages\n"
260              "      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to 44100)\n"
261              "      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
262              "      --from-channels=CHANNELS        From number of channels (defaults to 1)\n"
263              "      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to 44100)\n"
264              "      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
265              "      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
266              "      --resample-method=METHOD        Resample method (defaults to auto)\n"
267              "      --seconds=SECONDS               From stream duration (defaults to 60)\n"
268              "\n"
269              "If the formats are not specified, the test performs all formats combinations,\n"
270              "back and forth.\n"
271              "\n"
272              "Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, alaw,\n"
273              "32le, s32be (defaults to s16ne)\n"
274              "\n"
275              "See --dump-resample-methods for possible values of resample methods.\n"),
276              argv0);
277 }
278
279 enum {
280     ARG_VERSION = 256,
281     ARG_FROM_SAMPLERATE,
282     ARG_FROM_SAMPLEFORMAT,
283     ARG_FROM_CHANNELS,
284     ARG_TO_SAMPLERATE,
285     ARG_TO_SAMPLEFORMAT,
286     ARG_TO_CHANNELS,
287     ARG_SECONDS,
288     ARG_RESAMPLE_METHOD,
289     ARG_DUMP_RESAMPLE_METHODS
290 };
291
292 static void dump_resample_methods(void) {
293     int i;
294
295     for (i = 0; i < PA_RESAMPLER_MAX; i++)
296         if (pa_resample_method_supported(i))
297             printf("%s\n", pa_resample_method_to_string(i));
298
299 }
300
301 int main(int argc, char *argv[]) {
302     pa_mempool *pool = NULL;
303     pa_sample_spec a, b;
304     int ret = 1, c;
305     pa_bool_t all_formats = TRUE;
306     pa_resample_method_t method;
307     int seconds;
308
309     static const struct option long_options[] = {
310         {"help",                  0, NULL, 'h'},
311         {"verbose",               0, NULL, 'v'},
312         {"version",               0, NULL, ARG_VERSION},
313         {"from-rate",             1, NULL, ARG_FROM_SAMPLERATE},
314         {"from-format",           1, NULL, ARG_FROM_SAMPLEFORMAT},
315         {"from-channels",         1, NULL, ARG_FROM_CHANNELS},
316         {"to-rate",               1, NULL, ARG_TO_SAMPLERATE},
317         {"to-format",             1, NULL, ARG_TO_SAMPLEFORMAT},
318         {"to-channels",           1, NULL, ARG_TO_CHANNELS},
319         {"seconds",               1, NULL, ARG_SECONDS},
320         {"resample-method",       1, NULL, ARG_RESAMPLE_METHOD},
321         {"dump-resample-methods", 0, NULL, ARG_DUMP_RESAMPLE_METHODS},
322         {NULL,                    0, NULL, 0}
323     };
324
325     setlocale(LC_ALL, "");
326 #ifdef ENABLE_NLS
327     bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
328 #endif
329
330     pa_log_set_level(PA_LOG_WARN);
331     if (!getenv("MAKE_CHECK"))
332         pa_log_set_level(PA_LOG_INFO);
333
334     pa_assert_se(pool = pa_mempool_new(FALSE, 0));
335
336     a.channels = b.channels = 1;
337     a.rate = b.rate = 44100;
338     a.format = b.format = PA_SAMPLE_S16LE;
339
340     method = PA_RESAMPLER_AUTO;
341     seconds = 60;
342
343     while ((c = getopt_long(argc, argv, "hv", long_options, NULL)) != -1) {
344
345         switch (c) {
346             case 'h' :
347                 help(argv[0]);
348                 ret = 0;
349                 goto quit;
350
351             case 'v':
352                 pa_log_set_level(PA_LOG_DEBUG);
353                 break;
354
355             case ARG_VERSION:
356                 printf(_("%s %s\n"), argv[0], PACKAGE_VERSION);
357                 ret = 0;
358                 goto quit;
359
360             case ARG_DUMP_RESAMPLE_METHODS:
361                 dump_resample_methods();
362                 ret = 0;
363                 goto quit;
364
365             case ARG_FROM_CHANNELS:
366                 a.channels = (uint8_t) atoi(optarg);
367                 break;
368
369             case ARG_FROM_SAMPLEFORMAT:
370                 a.format = pa_parse_sample_format(optarg);
371                 all_formats = FALSE;
372                 break;
373
374             case ARG_FROM_SAMPLERATE:
375                 a.rate = (uint32_t) atoi(optarg);
376                 break;
377
378             case ARG_TO_CHANNELS:
379                 b.channels = (uint8_t) atoi(optarg);
380                 break;
381
382             case ARG_TO_SAMPLEFORMAT:
383                 b.format = pa_parse_sample_format(optarg);
384                 all_formats = FALSE;
385                 break;
386
387             case ARG_TO_SAMPLERATE:
388                 b.rate = (uint32_t) atoi(optarg);
389                 break;
390
391             case ARG_SECONDS:
392                 seconds = atoi(optarg);
393                 break;
394
395             case ARG_RESAMPLE_METHOD:
396                 if (*optarg == '\0' || pa_streq(optarg, "help")) {
397                     dump_resample_methods();
398                     ret = 0;
399                     goto quit;
400                 }
401                 method = pa_parse_resample_method(optarg);
402                 break;
403
404             default:
405                 goto quit;
406         }
407     }
408
409     ret = 0;
410     pa_assert_se(pool = pa_mempool_new(FALSE, 0));
411
412     if (!all_formats) {
413
414         pa_resampler *resampler;
415         pa_memchunk i, j;
416         pa_usec_t ts;
417
418         pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
419         pa_log_debug(_("=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"), seconds,
420                    a.rate, a.channels, pa_sample_format_to_string(a.format),
421                    b.rate, b.channels, pa_sample_format_to_string(b.format));
422
423         ts = pa_rtclock_now();
424         pa_assert_se(resampler = pa_resampler_new(pool, &a, NULL, &b, NULL, method, 0));
425         pa_log_info("init: %llu", (long long unsigned)(pa_rtclock_now() - ts));
426
427         i.memblock = pa_memblock_new(pool, pa_usec_to_bytes(1*PA_USEC_PER_SEC, &a));
428
429         ts = pa_rtclock_now();
430         i.length = pa_memblock_get_length(i.memblock);
431         i.index = 0;
432         while (seconds--) {
433             pa_resampler_run(resampler, &i, &j);
434             pa_memblock_unref(j.memblock);
435         }
436         pa_log_info("resampling: %llu", (long long unsigned)(pa_rtclock_now() - ts));
437         pa_memblock_unref(i.memblock);
438
439         pa_resampler_free(resampler);
440
441         goto quit;
442     }
443
444     for (a.format = 0; a.format < PA_SAMPLE_MAX; a.format ++) {
445         for (b.format = 0; b.format < PA_SAMPLE_MAX; b.format ++) {
446             pa_resampler *forth, *back;
447             pa_memchunk i, j, k;
448
449             pa_log_debug("=== %s -> %s -> %s -> /2",
450                        pa_sample_format_to_string(a.format),
451                        pa_sample_format_to_string(b.format),
452                        pa_sample_format_to_string(a.format));
453
454             pa_assert_se(forth = pa_resampler_new(pool, &a, NULL, &b, NULL, method, 0));
455             pa_assert_se(back = pa_resampler_new(pool, &b, NULL, &a, NULL, method, 0));
456
457             i.memblock = generate_block(pool, &a);
458             i.length = pa_memblock_get_length(i.memblock);
459             i.index = 0;
460             pa_resampler_run(forth, &i, &j);
461             pa_resampler_run(back, &j, &k);
462
463             dump_block("before", &a, &i);
464             dump_block("after", &b, &j);
465             dump_block("reverse", &a, &k);
466
467             pa_memblock_unref(i.memblock);
468             pa_memblock_unref(j.memblock);
469             pa_memblock_unref(k.memblock);
470
471             pa_resampler_free(forth);
472             pa_resampler_free(back);
473         }
474     }
475
476  quit:
477     if (pool)
478         pa_mempool_free(pool);
479
480     return ret;
481 }