2 This file is part of PulseAudio.
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.
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.
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
28 #include <pulse/pulseaudio.h>
30 #include <pulse/rtclock.h>
31 #include <pulse/sample.h>
32 #include <pulse/volume.h>
34 #include <pulsecore/i18n.h>
35 #include <pulsecore/resampler.h>
36 #include <pulsecore/macro.h>
37 #include <pulsecore/endianmacros.h>
38 #include <pulsecore/memblock.h>
39 #include <pulsecore/sample-util.h>
40 #include <pulsecore/core-util.h>
42 static void dump_block(const pa_sample_spec
*ss
, const pa_memchunk
*chunk
) {
46 d
= pa_memblock_acquire(chunk
->memblock
);
52 case PA_SAMPLE_ALAW
: {
55 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++)
56 printf(" 0x%02x ", *(u
++));
62 case PA_SAMPLE_S16RE
: {
65 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++)
66 printf(" 0x%04x ", *(u
++));
72 case PA_SAMPLE_S32RE
: {
75 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++)
76 printf("0x%08x ", *(u
++));
81 case PA_SAMPLE_S24_32NE
:
82 case PA_SAMPLE_S24_32RE
: {
85 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++)
86 printf("0x%08x ", *(u
++));
91 case PA_SAMPLE_FLOAT32NE
:
92 case PA_SAMPLE_FLOAT32RE
: {
95 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++) {
96 printf("%4.3g ", ss
->format
== PA_SAMPLE_FLOAT32NE
? *u
: PA_FLOAT32_SWAP(*u
));
103 case PA_SAMPLE_S24LE
:
104 case PA_SAMPLE_S24BE
: {
107 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++) {
108 printf(" 0x%06x ", PA_READ24NE(u
));
109 u
+= pa_frame_size(ss
);
116 pa_assert_not_reached();
121 pa_memblock_release(chunk
->memblock
);
124 static pa_memblock
* generate_block(pa_mempool
*pool
, const pa_sample_spec
*ss
) {
129 pa_assert_se(r
= pa_memblock_new(pool
, pa_frame_size(ss
) * 10));
130 d
= pa_memblock_acquire(r
);
132 switch (ss
->format
) {
136 case PA_SAMPLE_ALAW
: {
152 case PA_SAMPLE_S16NE
:
153 case PA_SAMPLE_S16RE
: {
169 case PA_SAMPLE_S32NE
:
170 case PA_SAMPLE_S32RE
: {
186 case PA_SAMPLE_S24_32NE
:
187 case PA_SAMPLE_S24_32RE
: {
203 case PA_SAMPLE_FLOAT32NE
:
204 case PA_SAMPLE_FLOAT32RE
: {
218 if (ss
->format
== PA_SAMPLE_FLOAT32RE
)
219 for (i
= 0; i
< 10; i
++)
220 u
[i
] = PA_FLOAT32_SWAP(u
[i
]);
225 case PA_SAMPLE_S24NE
:
226 case PA_SAMPLE_S24RE
: {
229 PA_WRITE24NE(u
, 0x000001);
230 PA_WRITE24NE(u
+3, 0xFF0002);
231 PA_WRITE24NE(u
+6, 0x7F0003);
232 PA_WRITE24NE(u
+9, 0x800004);
233 PA_WRITE24NE(u
+12, 0x9f0005);
234 PA_WRITE24NE(u
+15, 0x3f0006);
235 PA_WRITE24NE(u
+18, 0x107);
236 PA_WRITE24NE(u
+21, 0xF00008);
237 PA_WRITE24NE(u
+24, 0x2009);
238 PA_WRITE24NE(u
+27, 0x210A);
243 pa_assert_not_reached();
246 pa_memblock_release(r
);
251 static void help(const char *argv0
) {
252 printf(_("%s [options]\n\n"
253 "-h, --help Show this help\n"
254 "-v, --verbose Print debug messages\n"
255 " --from-rate=SAMPLERATE From sample rate in Hz (defaults to 44100)\n"
256 " --from-format=SAMPLEFORMAT From sample type (defaults to s16le)\n"
257 " --from-channels=CHANNELS From number of channels (defaults to 1)\n"
258 " --to-rate=SAMPLERATE To sample rate in Hz (defaults to 44100)\n"
259 " --to-format=SAMPLEFORMAT To sample type (defaults to s16le)\n"
260 " --to-channels=CHANNELS To number of channels (defaults to 1)\n"
261 " --resample-method=METHOD Resample method (defaults to auto)\n"
262 " --seconds=SECONDS From stream duration (defaults to 60)\n"
264 "If the formats are not specified, the test performs all formats combinations,\n"
267 "Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, alaw,\n"
268 "32le, s32be (defaults to s16ne)\n"
270 "See --dump-resample-methods for possible values of resample methods.\n"),
277 ARG_FROM_SAMPLEFORMAT
,
284 ARG_DUMP_RESAMPLE_METHODS
287 static void dump_resample_methods(void) {
290 for (i
= 0; i
< PA_RESAMPLER_MAX
; i
++)
291 if (pa_resample_method_supported(i
))
292 printf("%s\n", pa_resample_method_to_string(i
));
296 int main(int argc
, char *argv
[]) {
297 pa_mempool
*pool
= NULL
;
300 int ret
= 1, verbose
= 0, c
;
301 pa_bool_t all_formats
= TRUE
;
302 pa_resample_method_t method
;
305 static const struct option long_options
[] = {
306 {"help", 0, NULL
, 'h'},
307 {"verbose", 0, NULL
, 'v'},
308 {"version", 0, NULL
, ARG_VERSION
},
309 {"from-rate", 1, NULL
, ARG_FROM_SAMPLERATE
},
310 {"from-format", 1, NULL
, ARG_FROM_SAMPLEFORMAT
},
311 {"from-channels", 1, NULL
, ARG_FROM_CHANNELS
},
312 {"to-rate", 1, NULL
, ARG_TO_SAMPLERATE
},
313 {"to-format", 1, NULL
, ARG_TO_SAMPLEFORMAT
},
314 {"to-channels", 1, NULL
, ARG_TO_CHANNELS
},
315 {"seconds", 1, NULL
, ARG_SECONDS
},
316 {"resample-method", 1, NULL
, ARG_RESAMPLE_METHOD
},
317 {"dump-resample-methods", 0, NULL
, ARG_DUMP_RESAMPLE_METHODS
},
321 setlocale(LC_ALL
, "");
322 bindtextdomain(GETTEXT_PACKAGE
, PULSE_LOCALEDIR
);
324 pa_log_set_level(PA_LOG_DEBUG
);
326 pa_assert_se(pool
= pa_mempool_new(FALSE
, 0));
328 a
.channels
= b
.channels
= 1;
329 a
.rate
= b
.rate
= 44100;
330 a
.format
= b
.format
= PA_SAMPLE_S16LE
;
331 v
.channels
= a
.channels
;
332 v
.values
[0] = pa_sw_volume_from_linear(0.5);
334 method
= PA_RESAMPLER_AUTO
;
337 while ((c
= getopt_long(argc
, argv
, "hv", long_options
, NULL
)) != -1) {
346 pa_log_set_level(PA_LOG_DEBUG
);
351 printf(_("%s %s\n"), argv
[0], PACKAGE_VERSION
);
355 case ARG_DUMP_RESAMPLE_METHODS
:
356 dump_resample_methods();
360 case ARG_FROM_CHANNELS
:
361 a
.channels
= (uint8_t) atoi(optarg
);
364 case ARG_FROM_SAMPLEFORMAT
:
365 a
.format
= pa_parse_sample_format(optarg
);
369 case ARG_FROM_SAMPLERATE
:
370 a
.rate
= (uint32_t) atoi(optarg
);
373 case ARG_TO_CHANNELS
:
374 b
.channels
= (uint8_t) atoi(optarg
);
377 case ARG_TO_SAMPLEFORMAT
:
378 b
.format
= pa_parse_sample_format(optarg
);
382 case ARG_TO_SAMPLERATE
:
383 b
.rate
= (uint32_t) atoi(optarg
);
387 seconds
= atoi(optarg
);
390 case ARG_RESAMPLE_METHOD
:
391 if (*optarg
== '\0' || pa_streq(optarg
, "help")) {
392 dump_resample_methods();
396 method
= pa_parse_resample_method(optarg
);
405 pa_assert_se(pool
= pa_mempool_new(FALSE
, 0));
409 pa_resampler
*resampler
;
414 printf(_("Compilation CFLAGS: %s\n"), PA_CFLAGS
);
415 printf(_("=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)\n"), seconds
,
416 a
.rate
, a
.channels
, pa_sample_format_to_string(a
.format
),
417 b
.rate
, b
.channels
, pa_sample_format_to_string(b
.format
));
420 ts
= pa_rtclock_now();
421 pa_assert_se(resampler
= pa_resampler_new(pool
, &a
, NULL
, &b
, NULL
, method
, 0));
422 printf("init: %llu\n", (long long unsigned)(pa_rtclock_now() - ts
));
424 i
.memblock
= pa_memblock_new(pool
, pa_usec_to_bytes(1*PA_USEC_PER_SEC
, &a
) / pa_frame_size(&a
));
426 ts
= pa_rtclock_now();
427 i
.length
= pa_memblock_get_length(i
.memblock
);
430 pa_resampler_run(resampler
, &i
, &j
);
431 pa_memblock_unref(j
.memblock
);
433 printf("resampling: %llu\n", (long long unsigned)(pa_rtclock_now() - ts
));
434 pa_memblock_unref(i
.memblock
);
436 pa_resampler_free(resampler
);
441 for (a
.format
= 0; a
.format
< PA_SAMPLE_MAX
; a
.format
++) {
442 for (b
.format
= 0; b
.format
< PA_SAMPLE_MAX
; b
.format
++) {
443 pa_resampler
*forth
, *back
;
447 printf("=== %s -> %s -> %s -> /2\n",
448 pa_sample_format_to_string(a
.format
),
449 pa_sample_format_to_string(b
.format
),
450 pa_sample_format_to_string(a
.format
));
452 pa_assert_se(forth
= pa_resampler_new(pool
, &a
, NULL
, &b
, NULL
, method
, 0));
453 pa_assert_se(back
= pa_resampler_new(pool
, &b
, NULL
, &a
, NULL
, method
, 0));
455 i
.memblock
= generate_block(pool
, &a
);
456 i
.length
= pa_memblock_get_length(i
.memblock
);
458 pa_resampler_run(forth
, &i
, &j
);
459 pa_resampler_run(back
, &j
, &k
);
468 pa_memblock_unref(j
.memblock
);
469 pa_memblock_unref(k
.memblock
);
471 pa_volume_memchunk(&i
, &a
, &v
);
475 pa_memblock_unref(i
.memblock
);
477 pa_resampler_free(forth
);
478 pa_resampler_free(back
);
484 pa_mempool_free(pool
);