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/i18n.h>
29 #include <pulse/pulseaudio.h>
31 #include <pulse/rtclock.h>
32 #include <pulse/sample.h>
33 #include <pulse/volume.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-rtclock.h>
41 #include <pulsecore/core-util.h>
43 static void dump_block(const pa_sample_spec
*ss
, const pa_memchunk
*chunk
) {
47 d
= pa_memblock_acquire(chunk
->memblock
);
53 case PA_SAMPLE_ALAW
: {
56 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++)
57 printf(" 0x%02x ", *(u
++));
63 case PA_SAMPLE_S16RE
: {
66 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++)
67 printf(" 0x%04x ", *(u
++));
73 case PA_SAMPLE_S32RE
: {
76 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++)
77 printf("0x%08x ", *(u
++));
82 case PA_SAMPLE_S24_32NE
:
83 case PA_SAMPLE_S24_32RE
: {
86 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++)
87 printf("0x%08x ", *(u
++));
92 case PA_SAMPLE_FLOAT32NE
:
93 case PA_SAMPLE_FLOAT32RE
: {
96 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++) {
97 printf("%4.3g ", ss
->format
== PA_SAMPLE_FLOAT32NE
? *u
: PA_FLOAT32_SWAP(*u
));
104 case PA_SAMPLE_S24LE
:
105 case PA_SAMPLE_S24BE
: {
108 for (i
= 0; i
< chunk
->length
/ pa_frame_size(ss
); i
++) {
109 printf(" 0x%06x ", PA_READ24NE(u
));
110 u
+= pa_frame_size(ss
);
117 pa_assert_not_reached();
122 pa_memblock_release(chunk
->memblock
);
125 static pa_memblock
* generate_block(pa_mempool
*pool
, const pa_sample_spec
*ss
) {
130 pa_assert_se(r
= pa_memblock_new(pool
, pa_frame_size(ss
) * 10));
131 d
= pa_memblock_acquire(r
);
133 switch (ss
->format
) {
137 case PA_SAMPLE_ALAW
: {
153 case PA_SAMPLE_S16NE
:
154 case PA_SAMPLE_S16RE
: {
170 case PA_SAMPLE_S32NE
:
171 case PA_SAMPLE_S32RE
: {
187 case PA_SAMPLE_S24_32NE
:
188 case PA_SAMPLE_S24_32RE
: {
204 case PA_SAMPLE_FLOAT32NE
:
205 case PA_SAMPLE_FLOAT32RE
: {
219 if (ss
->format
== PA_SAMPLE_FLOAT32RE
)
220 for (i
= 0; i
< 10; i
++)
221 u
[i
] = PA_FLOAT32_SWAP(u
[i
]);
226 case PA_SAMPLE_S24NE
:
227 case PA_SAMPLE_S24RE
: {
230 PA_WRITE24NE(u
, 0x000001);
231 PA_WRITE24NE(u
+3, 0xFF0002);
232 PA_WRITE24NE(u
+6, 0x7F0003);
233 PA_WRITE24NE(u
+9, 0x800004);
234 PA_WRITE24NE(u
+12, 0x9f0005);
235 PA_WRITE24NE(u
+15, 0x3f0006);
236 PA_WRITE24NE(u
+18, 0x107);
237 PA_WRITE24NE(u
+21, 0xF00008);
238 PA_WRITE24NE(u
+24, 0x2009);
239 PA_WRITE24NE(u
+27, 0x210A);
244 pa_assert_not_reached();
247 pa_memblock_release(r
);
252 static void help(const char *argv0
) {
253 printf(_("%s [options]\n\n"
254 "-h, --help Show this help\n"
255 "-v, --verbose Print debug messages\n"
256 " --from-rate=SAMPLERATE From sample rate in Hz (defaults to 44100)\n"
257 " --from-format=SAMPLEFORMAT From sample type (defaults to s16le)\n"
258 " --from-channels=CHANNELS From number of channels (defaults to 1)\n"
259 " --to-rate=SAMPLERATE To sample rate in Hz (defaults to 44100)\n"
260 " --to-format=SAMPLEFORMAT To sample type (defaults to s16le)\n"
261 " --to-channels=CHANNELS To number of channels (defaults to 1)\n"
262 " --resample-method=METHOD Resample method (defaults to auto)\n"
263 " --seconds=SECONDS From stream duration (defaults to 60)\n"
265 "If the formats are not specified, the test performs all formats combinations,\n"
268 "Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, alaw,\n"
269 "32le, s32be (defaults to s16ne)\n"
271 "See --dump-resample-methods for possible values of resample methods.\n"),
278 ARG_FROM_SAMPLEFORMAT
,
285 ARG_DUMP_RESAMPLE_METHODS
288 static void dump_resample_methods(void) {
291 for (i
= 0; i
< PA_RESAMPLER_MAX
; i
++)
292 if (pa_resample_method_supported(i
))
293 printf("%s\n", pa_resample_method_to_string(i
));
297 int main(int argc
, char *argv
[]) {
298 pa_mempool
*pool
= NULL
;
301 int ret
= 1, verbose
= 0, c
;
302 pa_bool_t all_formats
= TRUE
;
303 pa_resample_method_t method
;
306 static const struct option long_options
[] = {
307 {"help", 0, NULL
, 'h'},
308 {"verbose", 0, NULL
, 'v'},
309 {"version", 0, NULL
, ARG_VERSION
},
310 {"from-rate", 1, NULL
, ARG_FROM_SAMPLERATE
},
311 {"from-format", 1, NULL
, ARG_FROM_SAMPLEFORMAT
},
312 {"from-channels", 1, NULL
, ARG_FROM_CHANNELS
},
313 {"to-rate", 1, NULL
, ARG_TO_SAMPLERATE
},
314 {"to-format", 1, NULL
, ARG_TO_SAMPLEFORMAT
},
315 {"to-channels", 1, NULL
, ARG_TO_CHANNELS
},
316 {"seconds", 1, NULL
, ARG_SECONDS
},
317 {"resample-method", 1, NULL
, ARG_RESAMPLE_METHOD
},
318 {"dump-resample-methods", 0, NULL
, ARG_DUMP_RESAMPLE_METHODS
},
322 setlocale(LC_ALL
, "");
323 bindtextdomain(GETTEXT_PACKAGE
, PULSE_LOCALEDIR
);
325 pa_log_set_level(PA_LOG_DEBUG
);
327 pa_assert_se(pool
= pa_mempool_new(FALSE
, 0));
329 a
.channels
= b
.channels
= 1;
330 a
.rate
= b
.rate
= 44100;
331 a
.format
= b
.format
= PA_SAMPLE_S16LE
;
332 v
.channels
= a
.channels
;
333 v
.values
[0] = pa_sw_volume_from_linear(0.5);
335 method
= PA_RESAMPLER_AUTO
;
338 while ((c
= getopt_long(argc
, argv
, "hv", long_options
, NULL
)) != -1) {
347 pa_log_set_level(PA_LOG_DEBUG
);
352 printf(_("%s %s\n"), argv
[0], PACKAGE_VERSION
);
356 case ARG_DUMP_RESAMPLE_METHODS
:
357 dump_resample_methods();
361 case ARG_FROM_CHANNELS
:
362 a
.channels
= (uint8_t) atoi(optarg
);
365 case ARG_FROM_SAMPLEFORMAT
:
366 a
.format
= pa_parse_sample_format(optarg
);
370 case ARG_FROM_SAMPLERATE
:
371 a
.rate
= (uint32_t) atoi(optarg
);
374 case ARG_TO_CHANNELS
:
375 b
.channels
= (uint8_t) atoi(optarg
);
378 case ARG_TO_SAMPLEFORMAT
:
379 b
.format
= pa_parse_sample_format(optarg
);
383 case ARG_TO_SAMPLERATE
:
384 b
.rate
= (uint32_t) atoi(optarg
);
388 seconds
= atoi(optarg
);
391 case ARG_RESAMPLE_METHOD
:
392 if (*optarg
== '\0' || pa_streq(optarg
, "help")) {
393 dump_resample_methods();
397 method
= pa_parse_resample_method(optarg
);
406 pa_assert_se(pool
= pa_mempool_new(FALSE
, 0));
410 pa_resampler
*resampler
;
415 printf(_("Compilation CFLAGS: %s\n"), PA_CFLAGS
);
416 printf(_("=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)\n"), seconds
,
417 a
.rate
, a
.channels
, pa_sample_format_to_string(a
.format
),
418 b
.rate
, b
.channels
, pa_sample_format_to_string(b
.format
));
421 ts
= pa_rtclock_now();
422 pa_assert_se(resampler
= pa_resampler_new(pool
, &a
, NULL
, &b
, NULL
, method
, 0));
423 printf("init: %llu\n", (long long unsigned)(pa_rtclock_now() - ts
));
425 i
.memblock
= pa_memblock_new(pool
, pa_usec_to_bytes(1*PA_USEC_PER_SEC
, &a
) / pa_frame_size(&a
));
427 ts
= pa_rtclock_now();
428 i
.length
= pa_memblock_get_length(i
.memblock
);
431 pa_resampler_run(resampler
, &i
, &j
);
432 pa_memblock_unref(j
.memblock
);
434 printf("resampling: %llu\n", (long long unsigned)(pa_rtclock_now() - ts
));
435 pa_memblock_unref(i
.memblock
);
437 pa_resampler_free(resampler
);
442 for (a
.format
= 0; a
.format
< PA_SAMPLE_MAX
; a
.format
++) {
443 for (b
.format
= 0; b
.format
< PA_SAMPLE_MAX
; b
.format
++) {
444 pa_resampler
*forth
, *back
;
448 printf("=== %s -> %s -> %s -> /2\n",
449 pa_sample_format_to_string(a
.format
),
450 pa_sample_format_to_string(b
.format
),
451 pa_sample_format_to_string(a
.format
));
453 pa_assert_se(forth
= pa_resampler_new(pool
, &a
, NULL
, &b
, NULL
, method
, 0));
454 pa_assert_se(back
= pa_resampler_new(pool
, &b
, NULL
, &a
, NULL
, method
, 0));
456 i
.memblock
= generate_block(pool
, &a
);
457 i
.length
= pa_memblock_get_length(i
.memblock
);
459 pa_resampler_run(forth
, &i
, &j
);
460 pa_resampler_run(back
, &j
, &k
);
469 pa_memblock_unref(j
.memblock
);
470 pa_memblock_unref(k
.memblock
);
472 pa_volume_memchunk(&i
, &a
, &v
);
476 pa_memblock_unref(i
.memblock
);
478 pa_resampler_free(forth
);
479 pa_resampler_free(back
);
485 pa_mempool_free(pool
);