Blame axfer/test/container-test.c

Packit Service a9274b
// SPDX-License-Identifier: GPL-2.0
Packit Service a9274b
//
Packit Service a9274b
// container-io.c - a unit test for parser/builder of supported containers.
Packit Service a9274b
//
Packit Service a9274b
// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
Packit Service a9274b
//
Packit Service a9274b
// Licensed under the terms of the GNU General Public License, version 2.
Packit Service a9274b
Packit Service a9274b
#include "../container.h"
Packit Service a9274b
#include "../misc.h"
Packit Service a9274b
Packit Service a9274b
#include "generator.h"
Packit Service a9274b
Packit Service a9274b
#include <stdlib.h>
Packit Service a9274b
#include <unistd.h>
Packit Service a9274b
#include <stdbool.h>
Packit Service a9274b
Packit Service a9274b
#include <assert.h>
Packit Service a9274b
Packit Service a9274b
struct container_trial {
Packit Service a9274b
	enum container_format format;
Packit Service a9274b
Packit Service a9274b
	struct container_context cntr;
Packit Service a9274b
	bool verbose;
Packit Service a9274b
};
Packit Service a9274b
Packit Service a9274b
static void test_builder(struct container_context *cntr,
Packit Service a9274b
			 enum container_format format, const char *const name,
Packit Service a9274b
			 snd_pcm_access_t access,
Packit Service a9274b
			 snd_pcm_format_t sample_format,
Packit Service a9274b
			 unsigned int samples_per_frame,
Packit Service a9274b
			 unsigned int frames_per_second,
Packit Service a9274b
			 void *frame_buffer, unsigned int frame_count,
Packit Service a9274b
			 bool verbose)
Packit Service a9274b
{
Packit Service a9274b
	snd_pcm_format_t sample;
Packit Service a9274b
	unsigned int channels;
Packit Service a9274b
	unsigned int rate;
Packit Service a9274b
	uint64_t max_frame_count;
Packit Service a9274b
	unsigned int handled_frame_count;
Packit Service a9274b
	uint64_t total_frame_count;
Packit Service a9274b
	int err;
Packit Service a9274b
Packit Service a9274b
	err = container_builder_init(cntr, name, format, verbose);
Packit Service a9274b
	assert(err == 0);
Packit Service a9274b
Packit Service a9274b
	sample = sample_format;
Packit Service a9274b
	channels = samples_per_frame;
Packit Service a9274b
	rate = frames_per_second;
Packit Service a9274b
	max_frame_count = 0;
Packit Service a9274b
	err = container_context_pre_process(cntr, &sample, &channels, &rate,
Packit Service a9274b
					    &max_frame_count);
Packit Service a9274b
	assert(err == 0);
Packit Service a9274b
	assert(sample == sample_format);
Packit Service a9274b
	assert(channels == samples_per_frame);
Packit Service a9274b
	assert(rate == frames_per_second);
Packit Service a9274b
	assert(max_frame_count > 0);
Packit Service a9274b
Packit Service a9274b
	handled_frame_count = frame_count;
Packit Service a9274b
	err = container_context_process_frames(cntr, frame_buffer,
Packit Service a9274b
					       &handled_frame_count);
Packit Service a9274b
	assert(err == 0);
Packit Service a9274b
	assert(handled_frame_count > 0);
Packit Service a9274b
	assert(handled_frame_count <= frame_count);
Packit Service a9274b
Packit Service a9274b
	total_frame_count = 0;
Packit Service a9274b
	err = container_context_post_process(cntr, &total_frame_count);
Packit Service a9274b
	assert(err == 0);
Packit Service a9274b
	assert(total_frame_count == frame_count);
Packit Service a9274b
Packit Service a9274b
	container_context_destroy(cntr);
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
static void test_parser(struct container_context *cntr,
Packit Service a9274b
		        enum container_format format, const char *const name,
Packit Service a9274b
		        snd_pcm_access_t access, snd_pcm_format_t sample_format,
Packit Service a9274b
		        unsigned int samples_per_frame,
Packit Service a9274b
		        unsigned int frames_per_second,
Packit Service a9274b
		        void *frame_buffer, unsigned int frame_count,
Packit Service a9274b
			bool verbose)
Packit Service a9274b
{
Packit Service a9274b
	snd_pcm_format_t sample;
Packit Service a9274b
	unsigned int channels;
Packit Service a9274b
	unsigned int rate;
Packit Service a9274b
	uint64_t total_frame_count;
Packit Service a9274b
	unsigned int handled_frame_count;
Packit Service a9274b
	int err;
Packit Service a9274b
Packit Service a9274b
	err = container_parser_init(cntr, name, verbose);
Packit Service a9274b
	assert(err == 0);
Packit Service a9274b
Packit Service a9274b
	sample = sample_format;
Packit Service a9274b
	channels = samples_per_frame;
Packit Service a9274b
	rate = frames_per_second;
Packit Service a9274b
	total_frame_count = 0;
Packit Service a9274b
	err = container_context_pre_process(cntr, &sample, &channels, &rate,
Packit Service a9274b
					    &total_frame_count);
Packit Service a9274b
	assert(err == 0);
Packit Service a9274b
	assert(sample == sample_format);
Packit Service a9274b
	assert(channels == samples_per_frame);
Packit Service a9274b
	assert(rate == frames_per_second);
Packit Service a9274b
	assert(total_frame_count == frame_count);
Packit Service a9274b
Packit Service a9274b
	handled_frame_count = total_frame_count;
Packit Service a9274b
	err = container_context_process_frames(cntr, frame_buffer,
Packit Service a9274b
					       &handled_frame_count);
Packit Service a9274b
	assert(err == 0);
Packit Service a9274b
	assert(handled_frame_count == frame_count);
Packit Service a9274b
Packit Service a9274b
	total_frame_count = 0;
Packit Service a9274b
	err = container_context_post_process(cntr, &total_frame_count);
Packit Service a9274b
	assert(err == 0);
Packit Service a9274b
	assert(total_frame_count == handled_frame_count);
Packit Service a9274b
Packit Service a9274b
	container_context_destroy(cntr);
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
static int callback(struct test_generator *gen, snd_pcm_access_t access,
Packit Service a9274b
		    snd_pcm_format_t sample_format,
Packit Service a9274b
		    unsigned int samples_per_frame, void *frame_buffer,
Packit Service a9274b
		    unsigned int frame_count)
Packit Service a9274b
{
Packit Service a9274b
	static const unsigned int entries[] = {
Packit Service a9274b
		[0] = 44100,
Packit Service a9274b
		[1] = 48000,
Packit Service a9274b
		[2] = 88200,
Packit Service a9274b
		[3] = 96000,
Packit Service a9274b
		[4] = 176400,
Packit Service a9274b
		[5] = 192000,
Packit Service a9274b
	};
Packit Service a9274b
	struct container_trial *trial = gen->private_data;
Packit Service a9274b
	unsigned int frames_per_second;
Packit Service a9274b
	const char *const name = "hoge";
Packit Service a9274b
	unsigned int size;
Packit Service a9274b
	void *buf;
Packit Service a9274b
	int i;
Packit Service a9274b
	int err = 0;
Packit Service a9274b
Packit Service a9274b
	size = frame_count * samples_per_frame *
Packit Service a9274b
			snd_pcm_format_physical_width(sample_format) / 8;
Packit Service a9274b
	buf = malloc(size);
Packit Service a9274b
	if (buf == NULL)
Packit Service a9274b
		return -ENOMEM;
Packit Service a9274b
Packit Service a9274b
	// Remove a result of a previous trial.
Packit Service a9274b
	unlink(name);
Packit Service a9274b
Packit Service a9274b
	for (i = 0; i < ARRAY_SIZE(entries); ++i) {
Packit Service a9274b
		frames_per_second = entries[i];
Packit Service a9274b
Packit Service a9274b
		test_builder(&trial->cntr, trial->format, name, access,
Packit Service a9274b
			     sample_format, samples_per_frame,
Packit Service a9274b
			     frames_per_second, frame_buffer, frame_count,
Packit Service a9274b
			     trial->verbose);
Packit Service a9274b
Packit Service a9274b
		test_parser(&trial->cntr, trial->format, name, access,
Packit Service a9274b
			    sample_format, samples_per_frame, frames_per_second,
Packit Service a9274b
			    buf, frame_count, trial->verbose);
Packit Service a9274b
Packit Service a9274b
		err = memcmp(buf, frame_buffer, size);
Packit Service a9274b
		assert(err == 0);
Packit Service a9274b
Packit Service a9274b
		unlink(name);
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	free(buf);
Packit Service a9274b
Packit Service a9274b
	return 0;
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
int main(int argc, const char *argv[])
Packit Service a9274b
{
Packit Service a9274b
	static const uint64_t sample_format_masks[] = {
Packit Service a9274b
		[CONTAINER_FORMAT_RIFF_WAVE] =
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U8) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S16_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S16_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S24_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S24_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S32_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S32_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT64_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT64_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_MU_LAW) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_A_LAW) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S24_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S24_3BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S20_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S20_3BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S18_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S18_3BE),
Packit Service a9274b
		[CONTAINER_FORMAT_AU] =
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S8) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S16_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S32_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT64_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_MU_LAW) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_A_LAW),
Packit Service a9274b
		[CONTAINER_FORMAT_VOC] =
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U8) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S16_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_MU_LAW) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_A_LAW),
Packit Service a9274b
		[CONTAINER_FORMAT_RAW] =
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S8) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U8) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S16_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S16_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U16_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U16_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S24_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S24_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U24_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U24_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S32_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S32_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U32_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U32_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT64_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_FLOAT64_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_IEC958_SUBFRAME_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_IEC958_SUBFRAME_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_MU_LAW) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_A_LAW) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S24_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S24_3BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U24_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U24_3BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S20_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S20_3BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U20_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U20_3BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S18_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_S18_3BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U18_3LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_U18_3BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_DSD_U8) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_DSD_U16_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_DSD_U32_LE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_DSD_U16_BE) |
Packit Service a9274b
			(1ull << SND_PCM_FORMAT_DSD_U32_BE),
Packit Service a9274b
	};
Packit Service a9274b
	static const uint64_t access_mask =
Packit Service a9274b
		(1ull << SND_PCM_ACCESS_MMAP_INTERLEAVED) |
Packit Service a9274b
		(1ull << SND_PCM_ACCESS_RW_INTERLEAVED);
Packit Service a9274b
	struct test_generator gen = {0};
Packit Service a9274b
	struct container_trial *trial;
Packit Service a9274b
	int i;
Packit Service a9274b
	int begin;
Packit Service a9274b
	int end;
Packit Service a9274b
	bool verbose;
Packit Service a9274b
	int err;
Packit Service a9274b
Packit Service a9274b
	if (argc > 1) {
Packit Service a9274b
		char *term;
Packit Service a9274b
		begin = strtol(argv[1], &term, 10);
Packit Service a9274b
		if (errno || *term != '\0')
Packit Service a9274b
			return EXIT_FAILURE;
Packit Service a9274b
		if (begin < CONTAINER_FORMAT_RIFF_WAVE &&
Packit Service a9274b
		    begin > CONTAINER_FORMAT_RAW)
Packit Service a9274b
			return -EXIT_FAILURE;
Packit Service a9274b
		end = begin + 1;
Packit Service a9274b
		verbose = true;
Packit Service a9274b
	} else {
Packit Service a9274b
		begin = CONTAINER_FORMAT_RIFF_WAVE;
Packit Service a9274b
		end = CONTAINER_FORMAT_RAW + 1;
Packit Service a9274b
		verbose = false;
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	for (i = begin; i < end; ++i) {
Packit Service a9274b
		err = generator_context_init(&gen, access_mask,
Packit Service a9274b
					     sample_format_masks[i],
Packit Service a9274b
					     1, 128, 23, 4500, 1024,
Packit Service a9274b
					     sizeof(struct container_trial));
Packit Service a9274b
		if (err >= 0) {
Packit Service a9274b
			trial = gen.private_data;
Packit Service a9274b
			trial->format = i;
Packit Service a9274b
			trial->verbose = verbose;
Packit Service a9274b
			err = generator_context_run(&gen, callback);
Packit Service a9274b
		}
Packit Service a9274b
Packit Service a9274b
		generator_context_destroy(&gen;;
Packit Service a9274b
Packit Service a9274b
		if (err < 0)
Packit Service a9274b
			break;
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	if (err < 0) {
Packit Service a9274b
		printf("%s\n", strerror(-err));
Packit Service a9274b
		return EXIT_FAILURE;
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	return EXIT_SUCCESS;
Packit Service a9274b
}