mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-12-22 18:16:31 +01:00
axfer: add unit test for container interface
In former commits, container module gets supports of parser/builder for several types of file format. This commit adds a unit test for them. This includes positive test cases only. The test cases actually generate I/O to file systems for many test cases. It takes a long time to finish. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
96110793b3
commit
b878df1ff0
6 changed files with 625 additions and 2 deletions
|
@ -6,7 +6,8 @@ AM_CPPFLAGS = \
|
|||
-I$(top_srcdir)/include
|
||||
|
||||
# Unit tests.
|
||||
SUBDIRS =
|
||||
SUBDIRS = \
|
||||
test
|
||||
|
||||
LIBRT = @LIBRT@
|
||||
LDADD = \
|
||||
|
|
15
axfer/test/Makefile.am
Normal file
15
axfer/test/Makefile.am
Normal file
|
@ -0,0 +1,15 @@
|
|||
TESTS = \
|
||||
container-test
|
||||
|
||||
check_PROGRAMS = \
|
||||
container-test
|
||||
|
||||
container_test_SOURCES = \
|
||||
../container.h \
|
||||
../container.c \
|
||||
../container-riff-wave.c \
|
||||
../container-au.c \
|
||||
../container-voc.c \
|
||||
../container-raw.c \
|
||||
generator.c \
|
||||
container-test.c
|
299
axfer/test/container-test.c
Normal file
299
axfer/test/container-test.c
Normal file
|
@ -0,0 +1,299 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// container-io.c - a unit test for parser/builder of supported containers.
|
||||
//
|
||||
// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
//
|
||||
// Licensed under the terms of the GNU General Public License, version 2.
|
||||
|
||||
#include "../container.h"
|
||||
#include "../misc.h"
|
||||
|
||||
#include "generator.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
struct container_trial {
|
||||
enum container_format format;
|
||||
|
||||
struct container_context cntr;
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
static void test_builder(struct container_context *cntr,
|
||||
enum container_format format, const char *const name,
|
||||
snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame,
|
||||
unsigned int frames_per_second,
|
||||
void *frame_buffer, unsigned int frame_count,
|
||||
bool verbose)
|
||||
{
|
||||
snd_pcm_format_t sample;
|
||||
unsigned int channels;
|
||||
unsigned int rate;
|
||||
uint64_t max_frame_count;
|
||||
unsigned int handled_frame_count;
|
||||
uint64_t total_frame_count;
|
||||
int err;
|
||||
|
||||
err = container_builder_init(cntr, name, format, verbose);
|
||||
assert(err == 0);
|
||||
|
||||
sample = sample_format;
|
||||
channels = samples_per_frame;
|
||||
rate = frames_per_second;
|
||||
max_frame_count = 0;
|
||||
err = container_context_pre_process(cntr, &sample, &channels, &rate,
|
||||
&max_frame_count);
|
||||
assert(err == 0);
|
||||
assert(sample == sample_format);
|
||||
assert(channels == samples_per_frame);
|
||||
assert(rate == frames_per_second);
|
||||
assert(max_frame_count > 0);
|
||||
|
||||
handled_frame_count = frame_count;
|
||||
err = container_context_process_frames(cntr, frame_buffer,
|
||||
&handled_frame_count);
|
||||
assert(err == 0);
|
||||
assert(handled_frame_count > 0);
|
||||
assert(handled_frame_count <= frame_count);
|
||||
|
||||
total_frame_count = 0;
|
||||
err = container_context_post_process(cntr, &total_frame_count);
|
||||
assert(err == 0);
|
||||
assert(total_frame_count == frame_count);
|
||||
|
||||
container_context_destroy(cntr);
|
||||
}
|
||||
|
||||
static void test_parser(struct container_context *cntr,
|
||||
enum container_format format, const char *const name,
|
||||
snd_pcm_access_t access, snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame,
|
||||
unsigned int frames_per_second,
|
||||
void *frame_buffer, unsigned int frame_count,
|
||||
bool verbose)
|
||||
{
|
||||
snd_pcm_format_t sample;
|
||||
unsigned int channels;
|
||||
unsigned int rate;
|
||||
uint64_t total_frame_count;
|
||||
unsigned int handled_frame_count;
|
||||
int err;
|
||||
|
||||
err = container_parser_init(cntr, name, verbose);
|
||||
assert(err == 0);
|
||||
|
||||
sample = sample_format;
|
||||
channels = samples_per_frame;
|
||||
rate = frames_per_second;
|
||||
total_frame_count = 0;
|
||||
err = container_context_pre_process(cntr, &sample, &channels, &rate,
|
||||
&total_frame_count);
|
||||
assert(err == 0);
|
||||
assert(sample == sample_format);
|
||||
assert(channels == samples_per_frame);
|
||||
assert(rate == frames_per_second);
|
||||
assert(total_frame_count == frame_count);
|
||||
|
||||
handled_frame_count = total_frame_count;
|
||||
err = container_context_process_frames(cntr, frame_buffer,
|
||||
&handled_frame_count);
|
||||
assert(err == 0);
|
||||
assert(handled_frame_count == frame_count);
|
||||
|
||||
total_frame_count = 0;
|
||||
err = container_context_post_process(cntr, &total_frame_count);
|
||||
assert(err == 0);
|
||||
assert(total_frame_count == handled_frame_count);
|
||||
|
||||
container_context_destroy(cntr);
|
||||
}
|
||||
|
||||
static int callback(struct test_generator *gen, snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame, void *frame_buffer,
|
||||
unsigned int frame_count)
|
||||
{
|
||||
static const unsigned int entries[] = {
|
||||
[0] = 44100,
|
||||
[1] = 48000,
|
||||
[2] = 88200,
|
||||
[3] = 96000,
|
||||
[4] = 176400,
|
||||
[5] = 192000,
|
||||
};
|
||||
struct container_trial *trial = gen->private_data;
|
||||
unsigned int frames_per_second;
|
||||
const char *const name = "hoge";
|
||||
unsigned int size;
|
||||
void *buf;
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
size = frame_count * samples_per_frame *
|
||||
snd_pcm_format_physical_width(sample_format) / 8;
|
||||
buf = malloc(size);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
// Remove a result of a previous trial.
|
||||
unlink(name);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(entries); ++i) {
|
||||
frames_per_second = entries[i];
|
||||
|
||||
test_builder(&trial->cntr, trial->format, name, access,
|
||||
sample_format, samples_per_frame,
|
||||
frames_per_second, frame_buffer, frame_count,
|
||||
trial->verbose);
|
||||
|
||||
test_parser(&trial->cntr, trial->format, name, access,
|
||||
sample_format, samples_per_frame, frames_per_second,
|
||||
buf, frame_count, trial->verbose);
|
||||
|
||||
err = memcmp(buf, frame_buffer, size);
|
||||
assert(err == 0);
|
||||
|
||||
unlink(name);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
static const uint64_t sample_format_masks[] = {
|
||||
[CONTAINER_FORMAT_RIFF_WAVE] =
|
||||
(1ul << SND_PCM_FORMAT_U8) |
|
||||
(1ul << SND_PCM_FORMAT_S16_LE) |
|
||||
(1ul << SND_PCM_FORMAT_S16_BE) |
|
||||
(1ul << SND_PCM_FORMAT_S24_LE) |
|
||||
(1ul << SND_PCM_FORMAT_S24_BE) |
|
||||
(1ul << SND_PCM_FORMAT_S32_LE) |
|
||||
(1ul << SND_PCM_FORMAT_S32_BE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT_LE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT_BE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT64_LE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT64_BE) |
|
||||
(1ul << SND_PCM_FORMAT_MU_LAW) |
|
||||
(1ul << SND_PCM_FORMAT_A_LAW) |
|
||||
(1ul << SND_PCM_FORMAT_S24_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_S24_3BE) |
|
||||
(1ul << SND_PCM_FORMAT_S20_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_S20_3BE) |
|
||||
(1ul << SND_PCM_FORMAT_S18_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_S18_3BE),
|
||||
[CONTAINER_FORMAT_AU] =
|
||||
(1ul << SND_PCM_FORMAT_S8) |
|
||||
(1ul << SND_PCM_FORMAT_S16_BE) |
|
||||
(1ul << SND_PCM_FORMAT_S32_BE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT_BE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT64_BE) |
|
||||
(1ul << SND_PCM_FORMAT_MU_LAW) |
|
||||
(1ul << SND_PCM_FORMAT_A_LAW),
|
||||
[CONTAINER_FORMAT_VOC] =
|
||||
(1ul << SND_PCM_FORMAT_U8) |
|
||||
(1ul << SND_PCM_FORMAT_S16_LE) |
|
||||
(1ul << SND_PCM_FORMAT_MU_LAW) |
|
||||
(1ul << SND_PCM_FORMAT_A_LAW),
|
||||
[CONTAINER_FORMAT_RAW] =
|
||||
(1ul << SND_PCM_FORMAT_S8) |
|
||||
(1ul << SND_PCM_FORMAT_U8) |
|
||||
(1ul << SND_PCM_FORMAT_S16_LE) |
|
||||
(1ul << SND_PCM_FORMAT_S16_BE) |
|
||||
(1ul << SND_PCM_FORMAT_U16_LE) |
|
||||
(1ul << SND_PCM_FORMAT_U16_BE) |
|
||||
(1ul << SND_PCM_FORMAT_S24_LE) |
|
||||
(1ul << SND_PCM_FORMAT_S24_BE) |
|
||||
(1ul << SND_PCM_FORMAT_U24_LE) |
|
||||
(1ul << SND_PCM_FORMAT_U24_BE) |
|
||||
(1ul << SND_PCM_FORMAT_S32_LE) |
|
||||
(1ul << SND_PCM_FORMAT_S32_BE) |
|
||||
(1ul << SND_PCM_FORMAT_U32_LE) |
|
||||
(1ul << SND_PCM_FORMAT_U32_BE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT_LE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT_BE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT64_LE) |
|
||||
(1ul << SND_PCM_FORMAT_FLOAT64_BE) |
|
||||
(1ul << SND_PCM_FORMAT_IEC958_SUBFRAME_LE) |
|
||||
(1ul << SND_PCM_FORMAT_IEC958_SUBFRAME_BE) |
|
||||
(1ul << SND_PCM_FORMAT_MU_LAW) |
|
||||
(1ul << SND_PCM_FORMAT_A_LAW) |
|
||||
(1ul << SND_PCM_FORMAT_S24_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_S24_3BE) |
|
||||
(1ul << SND_PCM_FORMAT_U24_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_U24_3BE) |
|
||||
(1ul << SND_PCM_FORMAT_S20_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_S20_3BE) |
|
||||
(1ul << SND_PCM_FORMAT_U20_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_U20_3BE) |
|
||||
(1ul << SND_PCM_FORMAT_S18_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_S18_3BE) |
|
||||
(1ul << SND_PCM_FORMAT_U18_3LE) |
|
||||
(1ul << SND_PCM_FORMAT_U18_3BE) |
|
||||
(1ul << SND_PCM_FORMAT_DSD_U8) |
|
||||
(1ul << SND_PCM_FORMAT_DSD_U16_LE) |
|
||||
(1ul << SND_PCM_FORMAT_DSD_U32_LE) |
|
||||
(1ul << SND_PCM_FORMAT_DSD_U16_BE) |
|
||||
(1ul << SND_PCM_FORMAT_DSD_U32_BE),
|
||||
};
|
||||
static const uint64_t access_mask =
|
||||
(1ul << SND_PCM_ACCESS_MMAP_INTERLEAVED) |
|
||||
(1ul << SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
struct test_generator gen = {0};
|
||||
struct container_trial *trial;
|
||||
int i;
|
||||
int begin;
|
||||
int end;
|
||||
bool verbose;
|
||||
int err;
|
||||
|
||||
if (argc > 1) {
|
||||
char *term;
|
||||
begin = strtol(argv[1], &term, 10);
|
||||
if (errno || *term != '\0')
|
||||
return EXIT_FAILURE;
|
||||
if (begin < CONTAINER_FORMAT_RIFF_WAVE &&
|
||||
begin > CONTAINER_FORMAT_RAW)
|
||||
return -EXIT_FAILURE;
|
||||
end = begin + 1;
|
||||
verbose = true;
|
||||
} else {
|
||||
begin = CONTAINER_FORMAT_RIFF_WAVE;
|
||||
end = CONTAINER_FORMAT_RAW + 1;
|
||||
verbose = false;
|
||||
}
|
||||
|
||||
for (i = begin; i < end; ++i) {
|
||||
err = generator_context_init(&gen, access_mask,
|
||||
sample_format_masks[i],
|
||||
1, 128, 23, 4500, 1024,
|
||||
sizeof(struct container_trial));
|
||||
if (err >= 0) {
|
||||
trial = gen.private_data;
|
||||
trial->format = i;
|
||||
trial->verbose = verbose;
|
||||
err = generator_context_run(&gen, callback);
|
||||
}
|
||||
|
||||
generator_context_destroy(&gen);
|
||||
|
||||
if (err < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
printf("%s\n", strerror(-err));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
260
axfer/test/generator.c
Normal file
260
axfer/test/generator.c
Normal file
|
@ -0,0 +1,260 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// allocator.h - a header of a generator for test with buffers of PCM frames.
|
||||
//
|
||||
// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
//
|
||||
// Licensed under the terms of the GNU General Public License, version 2.
|
||||
|
||||
#include "generator.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
int generator_context_init(struct test_generator *gen,
|
||||
uint64_t access_mask, uint64_t sample_format_mask,
|
||||
unsigned int min_samples_per_frame,
|
||||
unsigned int max_samples_per_frame,
|
||||
unsigned int min_frame_count,
|
||||
unsigned int max_frame_count,
|
||||
unsigned int step_frame_count,
|
||||
unsigned int private_size)
|
||||
{
|
||||
gen->fd = open("/dev/urandom", O_RDONLY);
|
||||
if (gen->fd < 0)
|
||||
return -errno;
|
||||
|
||||
gen->private_data = malloc(private_size);
|
||||
if (gen->private_data == NULL)
|
||||
return -ENOMEM;
|
||||
memset(gen->private_data, 0, private_size);
|
||||
|
||||
gen->access_mask = access_mask;
|
||||
gen->sample_format_mask = sample_format_mask;
|
||||
gen->min_samples_per_frame = min_samples_per_frame;
|
||||
gen->max_samples_per_frame = max_samples_per_frame;
|
||||
gen->min_frame_count = min_frame_count;
|
||||
gen->max_frame_count = max_frame_count;
|
||||
gen->step_frame_count = step_frame_count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *allocate_buf(snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame,
|
||||
unsigned int frame_count)
|
||||
{
|
||||
unsigned int bytes_per_sample;
|
||||
|
||||
bytes_per_sample = snd_pcm_format_physical_width(sample_format) / 8;
|
||||
|
||||
return calloc(samples_per_frame * frame_count, bytes_per_sample);
|
||||
}
|
||||
|
||||
static void *allocate_vector(snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame,
|
||||
unsigned int frame_count)
|
||||
{
|
||||
unsigned int bytes_per_sample;
|
||||
char **bufs;
|
||||
int i;
|
||||
|
||||
bytes_per_sample = snd_pcm_format_physical_width(sample_format) / 8;
|
||||
|
||||
bufs = calloc(samples_per_frame, sizeof(char *));
|
||||
if (bufs == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < samples_per_frame; ++i) {
|
||||
bufs[i] = calloc(frame_count, bytes_per_sample);
|
||||
if (bufs[i] == NULL) {
|
||||
for (; i >= 0; --i)
|
||||
free(bufs[i]);
|
||||
free(bufs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return bufs;
|
||||
}
|
||||
|
||||
static int fill_buf(int fd, void *frame_buffer, snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame, unsigned int frame_count)
|
||||
{
|
||||
unsigned int size;
|
||||
int len;
|
||||
|
||||
size = snd_pcm_format_physical_width(sample_format) / 8 *
|
||||
samples_per_frame * frame_count;
|
||||
while (size > 0) {
|
||||
len = read(fd, frame_buffer, size);
|
||||
if (len < 0)
|
||||
return len;
|
||||
size -= len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_vector(int fd, void *frame_buffer, snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame, unsigned int frame_count)
|
||||
{
|
||||
char **bufs = frame_buffer;
|
||||
unsigned int size;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < samples_per_frame; ++i) {
|
||||
size = frame_count *
|
||||
snd_pcm_format_physical_width(sample_format) / 8;
|
||||
|
||||
while (size > 0) {
|
||||
len = read(fd, bufs[i], size);
|
||||
if (len < 0)
|
||||
return len;
|
||||
size -= len;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void deallocate_buf(void *frame_buffer, unsigned int samples_per_frame)
|
||||
{
|
||||
free(frame_buffer);
|
||||
}
|
||||
|
||||
static void deallocate_vector(void *frame_buffer,
|
||||
unsigned int samples_per_frame)
|
||||
{
|
||||
char **bufs = frame_buffer;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < samples_per_frame; ++i)
|
||||
free(bufs[i]);
|
||||
|
||||
free(bufs);
|
||||
}
|
||||
|
||||
static int test_frame_count(struct test_generator *gen,
|
||||
snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame)
|
||||
{
|
||||
void *(*allocator)(snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame,
|
||||
unsigned int frame_count);
|
||||
int (*fill)(int fd, void *frame_buffer, snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame, unsigned int frame_count);
|
||||
void (*deallocator)(void *frame_buffer, unsigned int samples_per_frame);
|
||||
void *frame_buffer;
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
if (access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
|
||||
allocator = allocate_buf;
|
||||
fill = fill_buf;
|
||||
deallocator = deallocate_buf;
|
||||
} else {
|
||||
allocator = allocate_vector;
|
||||
fill = fill_vector;
|
||||
deallocator = deallocate_vector;
|
||||
}
|
||||
|
||||
frame_buffer = allocator(access, sample_format, samples_per_frame,
|
||||
gen->max_frame_count);
|
||||
if (frame_buffer == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
err = fill(gen->fd, frame_buffer, access, sample_format,
|
||||
samples_per_frame, gen->max_frame_count);
|
||||
if (err < 0)
|
||||
goto end;
|
||||
|
||||
|
||||
for (i = gen->min_frame_count;
|
||||
i <= gen->max_frame_count; i += gen->step_frame_count) {
|
||||
err = gen->cb(gen, access ,sample_format, samples_per_frame,
|
||||
frame_buffer, i);
|
||||
if (err < 0)
|
||||
break;
|
||||
}
|
||||
end:
|
||||
deallocator(frame_buffer, samples_per_frame);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int test_samples_per_frame(struct test_generator *gen,
|
||||
snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format)
|
||||
{
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
for (i = gen->min_samples_per_frame;
|
||||
i <= gen->max_samples_per_frame; ++i) {
|
||||
err = test_frame_count(gen, access, sample_format, i);
|
||||
if (err < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int test_sample_format(struct test_generator *gen,
|
||||
snd_pcm_access_t access)
|
||||
{
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
for (i = 0; i <= SND_PCM_FORMAT_LAST; ++i) {
|
||||
if (!((1ul << i) & gen->sample_format_mask))
|
||||
continue;
|
||||
|
||||
err = test_samples_per_frame(gen, access, i);
|
||||
if (err < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int test_access(struct test_generator *gen)
|
||||
{
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
for (i = 0; i <= SND_PCM_ACCESS_LAST; ++i) {
|
||||
if (!((1ul << i) & gen->access_mask))
|
||||
continue;
|
||||
|
||||
err = test_sample_format(gen, i);
|
||||
if (err < 0)
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int generator_context_run(struct test_generator *gen, generator_cb_t cb)
|
||||
{
|
||||
gen->cb = cb;
|
||||
return test_access(gen);
|
||||
}
|
||||
|
||||
void generator_context_destroy(struct test_generator *gen)
|
||||
{
|
||||
free(gen->private_data);
|
||||
close(gen->fd);
|
||||
}
|
47
axfer/test/generator.h
Normal file
47
axfer/test/generator.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// generator.c - a generator for test with buffers of PCM frames.
|
||||
//
|
||||
// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
//
|
||||
// Licensed under the terms of the GNU General Public License, version 2.
|
||||
|
||||
#ifndef __ALSA_UTILS_AXFER_TEST_GENERATOR__H_
|
||||
#define __ALSA_UTILS_AXFER_TEST_GENERATOR__H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
struct test_generator;
|
||||
typedef int (*generator_cb_t)(struct test_generator *gen,
|
||||
snd_pcm_access_t access,
|
||||
snd_pcm_format_t sample_format,
|
||||
unsigned int samples_per_frame,
|
||||
void *frame_buffer, unsigned int frame_count);
|
||||
|
||||
struct test_generator {
|
||||
int fd;
|
||||
uint64_t access_mask;
|
||||
uint64_t sample_format_mask;
|
||||
unsigned int min_samples_per_frame;
|
||||
unsigned int max_samples_per_frame;
|
||||
unsigned int min_frame_count;
|
||||
unsigned int max_frame_count;
|
||||
unsigned int step_frame_count;
|
||||
|
||||
generator_cb_t cb;
|
||||
void *private_data;
|
||||
};
|
||||
|
||||
int generator_context_init(struct test_generator *gen,
|
||||
uint64_t access_mask, uint64_t sample_format_mask,
|
||||
unsigned int min_samples_per_frame,
|
||||
unsigned int max_samples_per_frame,
|
||||
unsigned int min_frame_count,
|
||||
unsigned int max_frame_count,
|
||||
unsigned int step_frame_count,
|
||||
unsigned int private_size);
|
||||
int generator_context_run(struct test_generator *gen, generator_cb_t cb);
|
||||
void generator_context_destroy(struct test_generator *gen);
|
||||
|
||||
#endif
|
|
@ -430,4 +430,5 @@ AC_OUTPUT(Makefile alsactl/Makefile alsactl/init/Makefile \
|
|||
utils/alsa-utils.spec seq/Makefile seq/aconnect/Makefile \
|
||||
seq/aplaymidi/Makefile seq/aseqdump/Makefile seq/aseqnet/Makefile \
|
||||
speaker-test/Makefile speaker-test/samples/Makefile \
|
||||
alsaloop/Makefile alsa-info/Makefile axfer/Makefile)
|
||||
alsaloop/Makefile alsa-info/Makefile \
|
||||
axfer/Makefile axfer/test/Makefile)
|
||||
|
|
Loading…
Reference in a new issue