1c72fcc34Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 2c72fcc34Sopenharmony_ci// 3c72fcc34Sopenharmony_ci// mapper-io.c - a unit test for muxer/demuxer for PCM frames on buffer. 4c72fcc34Sopenharmony_ci// 5c72fcc34Sopenharmony_ci// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp> 6c72fcc34Sopenharmony_ci// 7c72fcc34Sopenharmony_ci// Licensed under the terms of the GNU General Public License, version 2. 8c72fcc34Sopenharmony_ci 9c72fcc34Sopenharmony_ci#include <aconfig.h> 10c72fcc34Sopenharmony_ci#ifdef HAVE_MEMFD_CREATE 11c72fcc34Sopenharmony_ci#define _GNU_SOURCE 12c72fcc34Sopenharmony_ci#endif 13c72fcc34Sopenharmony_ci 14c72fcc34Sopenharmony_ci#include "../mapper.h" 15c72fcc34Sopenharmony_ci#include "../misc.h" 16c72fcc34Sopenharmony_ci 17c72fcc34Sopenharmony_ci#include "generator.h" 18c72fcc34Sopenharmony_ci 19c72fcc34Sopenharmony_ci#ifdef HAVE_MEMFD_CREATE 20c72fcc34Sopenharmony_ci#include <sys/mman.h> 21c72fcc34Sopenharmony_ci#endif 22c72fcc34Sopenharmony_ci 23c72fcc34Sopenharmony_ci#include <stdlib.h> 24c72fcc34Sopenharmony_ci#include <unistd.h> 25c72fcc34Sopenharmony_ci#include <stdbool.h> 26c72fcc34Sopenharmony_ci 27c72fcc34Sopenharmony_ci#include <assert.h> 28c72fcc34Sopenharmony_ci 29c72fcc34Sopenharmony_cistruct mapper_trial { 30c72fcc34Sopenharmony_ci enum container_format cntr_format; 31c72fcc34Sopenharmony_ci struct container_context *cntrs; 32c72fcc34Sopenharmony_ci 33c72fcc34Sopenharmony_ci char **paths; 34c72fcc34Sopenharmony_ci 35c72fcc34Sopenharmony_ci struct mapper_context mapper; 36c72fcc34Sopenharmony_ci bool verbose; 37c72fcc34Sopenharmony_ci}; 38c72fcc34Sopenharmony_ci 39c72fcc34Sopenharmony_cistatic void test_demuxer(struct mapper_context *mapper, snd_pcm_access_t access, 40c72fcc34Sopenharmony_ci unsigned int bytes_per_sample, 41c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 42c72fcc34Sopenharmony_ci unsigned int frames_per_buffer, 43c72fcc34Sopenharmony_ci void *frame_buffer, unsigned int frame_count, 44c72fcc34Sopenharmony_ci struct container_context *cntrs, 45c72fcc34Sopenharmony_ci unsigned int cntr_count, bool verbose) 46c72fcc34Sopenharmony_ci{ 47c72fcc34Sopenharmony_ci unsigned int total_frame_count; 48c72fcc34Sopenharmony_ci int err; 49c72fcc34Sopenharmony_ci 50c72fcc34Sopenharmony_ci err = mapper_context_init(mapper, MAPPER_TYPE_DEMUXER, cntr_count, 51c72fcc34Sopenharmony_ci verbose); 52c72fcc34Sopenharmony_ci assert(err == 0); 53c72fcc34Sopenharmony_ci 54c72fcc34Sopenharmony_ci err = mapper_context_pre_process(mapper, access, bytes_per_sample, 55c72fcc34Sopenharmony_ci samples_per_frame, frames_per_buffer, 56c72fcc34Sopenharmony_ci cntrs); 57c72fcc34Sopenharmony_ci assert(err == 0); 58c72fcc34Sopenharmony_ci 59c72fcc34Sopenharmony_ci total_frame_count = frame_count; 60c72fcc34Sopenharmony_ci err = mapper_context_process_frames(mapper, frame_buffer, 61c72fcc34Sopenharmony_ci &total_frame_count, cntrs); 62c72fcc34Sopenharmony_ci assert(err == 0); 63c72fcc34Sopenharmony_ci assert(total_frame_count == frame_count); 64c72fcc34Sopenharmony_ci 65c72fcc34Sopenharmony_ci mapper_context_post_process(mapper); 66c72fcc34Sopenharmony_ci mapper_context_destroy(mapper); 67c72fcc34Sopenharmony_ci} 68c72fcc34Sopenharmony_ci 69c72fcc34Sopenharmony_cistatic int test_demux(struct mapper_trial *trial, snd_pcm_access_t access, 70c72fcc34Sopenharmony_ci snd_pcm_format_t sample_format, 71c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 72c72fcc34Sopenharmony_ci unsigned int frames_per_second, 73c72fcc34Sopenharmony_ci unsigned int frames_per_buffer, 74c72fcc34Sopenharmony_ci void *frame_buffer, unsigned int frame_count, 75c72fcc34Sopenharmony_ci int *cntr_fds, unsigned int cntr_count) 76c72fcc34Sopenharmony_ci{ 77c72fcc34Sopenharmony_ci struct container_context *cntrs = trial->cntrs; 78c72fcc34Sopenharmony_ci enum container_format cntr_format = trial->cntr_format; 79c72fcc34Sopenharmony_ci unsigned int bytes_per_sample; 80c72fcc34Sopenharmony_ci uint64_t total_frame_count; 81c72fcc34Sopenharmony_ci int i; 82c72fcc34Sopenharmony_ci int err = 0; 83c72fcc34Sopenharmony_ci 84c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 85c72fcc34Sopenharmony_ci snd_pcm_format_t format; 86c72fcc34Sopenharmony_ci unsigned int channels; 87c72fcc34Sopenharmony_ci unsigned int rate; 88c72fcc34Sopenharmony_ci 89c72fcc34Sopenharmony_ci err = container_builder_init(cntrs + i, cntr_fds[i], cntr_format, 0); 90c72fcc34Sopenharmony_ci if (err < 0) 91c72fcc34Sopenharmony_ci goto end; 92c72fcc34Sopenharmony_ci 93c72fcc34Sopenharmony_ci format = sample_format; 94c72fcc34Sopenharmony_ci rate = frames_per_second; 95c72fcc34Sopenharmony_ci total_frame_count = frame_count; 96c72fcc34Sopenharmony_ci if (cntr_count > 1) 97c72fcc34Sopenharmony_ci channels = 1; 98c72fcc34Sopenharmony_ci else 99c72fcc34Sopenharmony_ci channels = samples_per_frame; 100c72fcc34Sopenharmony_ci err = container_context_pre_process(cntrs + i, &format, 101c72fcc34Sopenharmony_ci &channels, &rate, 102c72fcc34Sopenharmony_ci &total_frame_count); 103c72fcc34Sopenharmony_ci if (err < 0) 104c72fcc34Sopenharmony_ci goto end; 105c72fcc34Sopenharmony_ci assert(format == sample_format); 106c72fcc34Sopenharmony_ci assert(rate == frames_per_second); 107c72fcc34Sopenharmony_ci assert(total_frame_count >= 0); 108c72fcc34Sopenharmony_ci if (cntr_count > 1) 109c72fcc34Sopenharmony_ci assert(channels == 1); 110c72fcc34Sopenharmony_ci else 111c72fcc34Sopenharmony_ci assert(channels == samples_per_frame); 112c72fcc34Sopenharmony_ci } 113c72fcc34Sopenharmony_ci 114c72fcc34Sopenharmony_ci bytes_per_sample = snd_pcm_format_physical_width(sample_format) / 8; 115c72fcc34Sopenharmony_ci test_demuxer(&trial->mapper, access, bytes_per_sample, 116c72fcc34Sopenharmony_ci samples_per_frame, frames_per_buffer, frame_buffer, 117c72fcc34Sopenharmony_ci frame_count, cntrs, cntr_count, trial->verbose); 118c72fcc34Sopenharmony_ci 119c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 120c72fcc34Sopenharmony_ci container_context_post_process(cntrs + i, &total_frame_count); 121c72fcc34Sopenharmony_ci assert(total_frame_count == frame_count); 122c72fcc34Sopenharmony_ci } 123c72fcc34Sopenharmony_ciend: 124c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) 125c72fcc34Sopenharmony_ci container_context_destroy(cntrs + i); 126c72fcc34Sopenharmony_ci 127c72fcc34Sopenharmony_ci return err; 128c72fcc34Sopenharmony_ci} 129c72fcc34Sopenharmony_ci 130c72fcc34Sopenharmony_cistatic void test_muxer(struct mapper_context *mapper, snd_pcm_access_t access, 131c72fcc34Sopenharmony_ci unsigned int bytes_per_sample, 132c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 133c72fcc34Sopenharmony_ci unsigned int frames_per_buffer, 134c72fcc34Sopenharmony_ci void *frame_buffer, unsigned int frame_count, 135c72fcc34Sopenharmony_ci struct container_context *cntrs, 136c72fcc34Sopenharmony_ci unsigned int cntr_count, bool verbose) 137c72fcc34Sopenharmony_ci{ 138c72fcc34Sopenharmony_ci unsigned int total_frame_count; 139c72fcc34Sopenharmony_ci int err; 140c72fcc34Sopenharmony_ci 141c72fcc34Sopenharmony_ci err = mapper_context_init(mapper, MAPPER_TYPE_MUXER, cntr_count, 142c72fcc34Sopenharmony_ci verbose); 143c72fcc34Sopenharmony_ci assert(err == 0); 144c72fcc34Sopenharmony_ci 145c72fcc34Sopenharmony_ci err = mapper_context_pre_process(mapper, access, bytes_per_sample, 146c72fcc34Sopenharmony_ci samples_per_frame, frames_per_buffer, 147c72fcc34Sopenharmony_ci cntrs); 148c72fcc34Sopenharmony_ci assert(err == 0); 149c72fcc34Sopenharmony_ci 150c72fcc34Sopenharmony_ci total_frame_count = frame_count; 151c72fcc34Sopenharmony_ci err = mapper_context_process_frames(mapper, frame_buffer, 152c72fcc34Sopenharmony_ci &total_frame_count, cntrs); 153c72fcc34Sopenharmony_ci assert(err == 0); 154c72fcc34Sopenharmony_ci assert(total_frame_count == frame_count); 155c72fcc34Sopenharmony_ci 156c72fcc34Sopenharmony_ci mapper_context_post_process(mapper); 157c72fcc34Sopenharmony_ci mapper_context_destroy(mapper); 158c72fcc34Sopenharmony_ci} 159c72fcc34Sopenharmony_ci 160c72fcc34Sopenharmony_cistatic int test_mux(struct mapper_trial *trial, snd_pcm_access_t access, 161c72fcc34Sopenharmony_ci snd_pcm_format_t sample_format, 162c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 163c72fcc34Sopenharmony_ci unsigned int frames_per_second, 164c72fcc34Sopenharmony_ci unsigned int frames_per_buffer, 165c72fcc34Sopenharmony_ci void *frame_buffer, unsigned int frame_count, 166c72fcc34Sopenharmony_ci int *cntr_fds, unsigned int cntr_count) 167c72fcc34Sopenharmony_ci{ 168c72fcc34Sopenharmony_ci struct container_context *cntrs = trial->cntrs; 169c72fcc34Sopenharmony_ci unsigned int bytes_per_sample; 170c72fcc34Sopenharmony_ci uint64_t total_frame_count; 171c72fcc34Sopenharmony_ci int i; 172c72fcc34Sopenharmony_ci int err = 0; 173c72fcc34Sopenharmony_ci 174c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 175c72fcc34Sopenharmony_ci snd_pcm_format_t format; 176c72fcc34Sopenharmony_ci unsigned int channels; 177c72fcc34Sopenharmony_ci unsigned int rate; 178c72fcc34Sopenharmony_ci 179c72fcc34Sopenharmony_ci err = container_parser_init(cntrs + i, cntr_fds[i], 0); 180c72fcc34Sopenharmony_ci if (err < 0) 181c72fcc34Sopenharmony_ci goto end; 182c72fcc34Sopenharmony_ci 183c72fcc34Sopenharmony_ci format = sample_format; 184c72fcc34Sopenharmony_ci rate = frames_per_second; 185c72fcc34Sopenharmony_ci if (cntr_count > 1) 186c72fcc34Sopenharmony_ci channels = 1; 187c72fcc34Sopenharmony_ci else 188c72fcc34Sopenharmony_ci channels = samples_per_frame; 189c72fcc34Sopenharmony_ci err = container_context_pre_process(cntrs + i, &format, 190c72fcc34Sopenharmony_ci &channels, &rate, 191c72fcc34Sopenharmony_ci &total_frame_count); 192c72fcc34Sopenharmony_ci if (err < 0) 193c72fcc34Sopenharmony_ci goto end; 194c72fcc34Sopenharmony_ci 195c72fcc34Sopenharmony_ci assert(format == sample_format); 196c72fcc34Sopenharmony_ci assert(rate == frames_per_second); 197c72fcc34Sopenharmony_ci assert(total_frame_count == frame_count); 198c72fcc34Sopenharmony_ci if (cntr_count > 1) 199c72fcc34Sopenharmony_ci assert(channels == 1); 200c72fcc34Sopenharmony_ci else 201c72fcc34Sopenharmony_ci assert(channels == samples_per_frame); 202c72fcc34Sopenharmony_ci } 203c72fcc34Sopenharmony_ci 204c72fcc34Sopenharmony_ci bytes_per_sample = snd_pcm_format_physical_width(sample_format) / 8; 205c72fcc34Sopenharmony_ci test_muxer(&trial->mapper, access, bytes_per_sample, samples_per_frame, 206c72fcc34Sopenharmony_ci frames_per_buffer, frame_buffer, frame_count, cntrs, 207c72fcc34Sopenharmony_ci cntr_count, trial->verbose); 208c72fcc34Sopenharmony_ci 209c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 210c72fcc34Sopenharmony_ci container_context_post_process(cntrs + i, &total_frame_count); 211c72fcc34Sopenharmony_ci assert(total_frame_count == frame_count); 212c72fcc34Sopenharmony_ci } 213c72fcc34Sopenharmony_ciend: 214c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) 215c72fcc34Sopenharmony_ci container_context_destroy(cntrs + i); 216c72fcc34Sopenharmony_ci 217c72fcc34Sopenharmony_ci return err; 218c72fcc34Sopenharmony_ci} 219c72fcc34Sopenharmony_ci 220c72fcc34Sopenharmony_cistatic int test_mapper(struct mapper_trial *trial, snd_pcm_access_t access, 221c72fcc34Sopenharmony_ci snd_pcm_format_t sample_format, 222c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 223c72fcc34Sopenharmony_ci unsigned int frames_per_second, void *frame_buffer, 224c72fcc34Sopenharmony_ci void *check_buffer, unsigned int frame_count, 225c72fcc34Sopenharmony_ci unsigned int cntr_count) 226c72fcc34Sopenharmony_ci{ 227c72fcc34Sopenharmony_ci int *cntr_fds; 228c72fcc34Sopenharmony_ci unsigned int frames_per_buffer; 229c72fcc34Sopenharmony_ci int i; 230c72fcc34Sopenharmony_ci int err; 231c72fcc34Sopenharmony_ci 232c72fcc34Sopenharmony_ci // Use a buffer aligned by typical size of page frame. 233c72fcc34Sopenharmony_ci frames_per_buffer = ((frame_count + 4096) / 4096) * 4096; 234c72fcc34Sopenharmony_ci 235c72fcc34Sopenharmony_ci cntr_fds = calloc(cntr_count, sizeof(*cntr_fds)); 236c72fcc34Sopenharmony_ci if (cntr_fds == NULL) 237c72fcc34Sopenharmony_ci return -ENOMEM; 238c72fcc34Sopenharmony_ci 239c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 240c72fcc34Sopenharmony_ci const char *path = trial->paths[i]; 241c72fcc34Sopenharmony_ci 242c72fcc34Sopenharmony_ci#ifdef HAVE_MEMFD_CREATE 243c72fcc34Sopenharmony_ci cntr_fds[i] = memfd_create(path, 0); 244c72fcc34Sopenharmony_ci#else 245c72fcc34Sopenharmony_ci cntr_fds[i] = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644); 246c72fcc34Sopenharmony_ci#endif 247c72fcc34Sopenharmony_ci if (cntr_fds[i] < 0) { 248c72fcc34Sopenharmony_ci err = -errno; 249c72fcc34Sopenharmony_ci goto end; 250c72fcc34Sopenharmony_ci } 251c72fcc34Sopenharmony_ci } 252c72fcc34Sopenharmony_ci 253c72fcc34Sopenharmony_ci err = test_demux(trial, access, sample_format, samples_per_frame, 254c72fcc34Sopenharmony_ci frames_per_second, frames_per_buffer, frame_buffer, 255c72fcc34Sopenharmony_ci frame_count, cntr_fds, cntr_count); 256c72fcc34Sopenharmony_ci if (err < 0) 257c72fcc34Sopenharmony_ci goto end; 258c72fcc34Sopenharmony_ci 259c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 260c72fcc34Sopenharmony_ci off_t pos = lseek(cntr_fds[i], 0, SEEK_SET); 261c72fcc34Sopenharmony_ci if (pos != 0) { 262c72fcc34Sopenharmony_ci err = -EIO; 263c72fcc34Sopenharmony_ci goto end; 264c72fcc34Sopenharmony_ci } 265c72fcc34Sopenharmony_ci } 266c72fcc34Sopenharmony_ci 267c72fcc34Sopenharmony_ci err = test_mux(trial, access, sample_format, samples_per_frame, 268c72fcc34Sopenharmony_ci frames_per_second, frames_per_buffer, check_buffer, 269c72fcc34Sopenharmony_ci frame_count, cntr_fds, cntr_count); 270c72fcc34Sopenharmony_ciend: 271c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) 272c72fcc34Sopenharmony_ci close(cntr_fds[i]); 273c72fcc34Sopenharmony_ci 274c72fcc34Sopenharmony_ci free(cntr_fds); 275c72fcc34Sopenharmony_ci 276c72fcc34Sopenharmony_ci return err; 277c72fcc34Sopenharmony_ci} 278c72fcc34Sopenharmony_ci 279c72fcc34Sopenharmony_cistatic int test_i_buf(struct mapper_trial *trial, snd_pcm_access_t access, 280c72fcc34Sopenharmony_ci snd_pcm_format_t sample_format, 281c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 282c72fcc34Sopenharmony_ci unsigned int frames_per_second, void *frame_buffer, 283c72fcc34Sopenharmony_ci unsigned int frame_count, unsigned int cntr_count) 284c72fcc34Sopenharmony_ci{ 285c72fcc34Sopenharmony_ci unsigned int size; 286c72fcc34Sopenharmony_ci char *buf; 287c72fcc34Sopenharmony_ci int err; 288c72fcc34Sopenharmony_ci 289c72fcc34Sopenharmony_ci size = frame_count * samples_per_frame * 290c72fcc34Sopenharmony_ci snd_pcm_format_physical_width(sample_format) / 8; 291c72fcc34Sopenharmony_ci buf = malloc(size); 292c72fcc34Sopenharmony_ci if (buf == 0) 293c72fcc34Sopenharmony_ci return -ENOMEM; 294c72fcc34Sopenharmony_ci memset(buf, 0, size); 295c72fcc34Sopenharmony_ci 296c72fcc34Sopenharmony_ci // Test multiple target. 297c72fcc34Sopenharmony_ci err = test_mapper(trial, access, sample_format, samples_per_frame, 298c72fcc34Sopenharmony_ci frames_per_second, frame_buffer, buf, 299c72fcc34Sopenharmony_ci frame_count, cntr_count); 300c72fcc34Sopenharmony_ci if (err < 0) 301c72fcc34Sopenharmony_ci goto end; 302c72fcc34Sopenharmony_ci err = memcmp(frame_buffer, buf, size); 303c72fcc34Sopenharmony_ci assert(err == 0); 304c72fcc34Sopenharmony_ci 305c72fcc34Sopenharmony_ci // Test single target. 306c72fcc34Sopenharmony_ci err = test_mapper(trial, access, sample_format, samples_per_frame, 307c72fcc34Sopenharmony_ci frames_per_second, frame_buffer, buf, 308c72fcc34Sopenharmony_ci frame_count, 1); 309c72fcc34Sopenharmony_ci if (err < 0) 310c72fcc34Sopenharmony_ci goto end; 311c72fcc34Sopenharmony_ci err = memcmp(frame_buffer, buf, size); 312c72fcc34Sopenharmony_ci assert(err == 0); 313c72fcc34Sopenharmony_ciend: 314c72fcc34Sopenharmony_ci free(buf); 315c72fcc34Sopenharmony_ci 316c72fcc34Sopenharmony_ci return err; 317c72fcc34Sopenharmony_ci} 318c72fcc34Sopenharmony_ci 319c72fcc34Sopenharmony_cistatic int test_vector(struct mapper_trial *trial, snd_pcm_access_t access, 320c72fcc34Sopenharmony_ci snd_pcm_format_t sample_format, 321c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 322c72fcc34Sopenharmony_ci unsigned int frames_per_second, void *frame_buffer, 323c72fcc34Sopenharmony_ci unsigned int frame_count, unsigned int cntr_count) 324c72fcc34Sopenharmony_ci{ 325c72fcc34Sopenharmony_ci unsigned int size; 326c72fcc34Sopenharmony_ci char **bufs; 327c72fcc34Sopenharmony_ci int i; 328c72fcc34Sopenharmony_ci int err; 329c72fcc34Sopenharmony_ci 330c72fcc34Sopenharmony_ci bufs = calloc(cntr_count, sizeof(*bufs)); 331c72fcc34Sopenharmony_ci if (bufs == NULL) 332c72fcc34Sopenharmony_ci return -ENOMEM; 333c72fcc34Sopenharmony_ci 334c72fcc34Sopenharmony_ci size = frame_count * snd_pcm_format_physical_width(sample_format) / 8; 335c72fcc34Sopenharmony_ci 336c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 337c72fcc34Sopenharmony_ci bufs[i] = malloc(size); 338c72fcc34Sopenharmony_ci if (bufs[i] == NULL) { 339c72fcc34Sopenharmony_ci err = -ENOMEM; 340c72fcc34Sopenharmony_ci goto end; 341c72fcc34Sopenharmony_ci } 342c72fcc34Sopenharmony_ci memset(bufs[i], 0, size); 343c72fcc34Sopenharmony_ci } 344c72fcc34Sopenharmony_ci 345c72fcc34Sopenharmony_ci // Test multiple target. 346c72fcc34Sopenharmony_ci err = test_mapper(trial, access, sample_format, samples_per_frame, 347c72fcc34Sopenharmony_ci frames_per_second, frame_buffer, bufs, 348c72fcc34Sopenharmony_ci frame_count, cntr_count); 349c72fcc34Sopenharmony_ci if (err < 0) 350c72fcc34Sopenharmony_ci goto end; 351c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 352c72fcc34Sopenharmony_ci char **target = frame_buffer; 353c72fcc34Sopenharmony_ci err = memcmp(target[i], bufs[i], size); 354c72fcc34Sopenharmony_ci assert(err == 0); 355c72fcc34Sopenharmony_ci } 356c72fcc34Sopenharmony_ci 357c72fcc34Sopenharmony_ci // Test single target. 358c72fcc34Sopenharmony_ci err = test_mapper(trial, access, sample_format, samples_per_frame, 359c72fcc34Sopenharmony_ci frames_per_second, frame_buffer, bufs, 360c72fcc34Sopenharmony_ci frame_count, 1); 361c72fcc34Sopenharmony_ci if (err < 0) 362c72fcc34Sopenharmony_ci goto end; 363c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 364c72fcc34Sopenharmony_ci char **target = frame_buffer; 365c72fcc34Sopenharmony_ci err = memcmp(target[i], bufs[i], size); 366c72fcc34Sopenharmony_ci assert(err == 0); 367c72fcc34Sopenharmony_ci } 368c72fcc34Sopenharmony_ciend: 369c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) { 370c72fcc34Sopenharmony_ci if (bufs[i]) 371c72fcc34Sopenharmony_ci free(bufs[i]); 372c72fcc34Sopenharmony_ci } 373c72fcc34Sopenharmony_ci free(bufs); 374c72fcc34Sopenharmony_ci 375c72fcc34Sopenharmony_ci return err; 376c72fcc34Sopenharmony_ci} 377c72fcc34Sopenharmony_ci 378c72fcc34Sopenharmony_cistatic int test_n_buf(struct mapper_trial *trial, snd_pcm_access_t access, 379c72fcc34Sopenharmony_ci snd_pcm_format_t sample_format, 380c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 381c72fcc34Sopenharmony_ci unsigned int frames_per_second, void *frame_buffer, 382c72fcc34Sopenharmony_ci unsigned int frame_count, unsigned int cntr_count) 383c72fcc34Sopenharmony_ci{ 384c72fcc34Sopenharmony_ci char *test_buf = frame_buffer; 385c72fcc34Sopenharmony_ci unsigned int size; 386c72fcc34Sopenharmony_ci char **test_vec; 387c72fcc34Sopenharmony_ci int i; 388c72fcc34Sopenharmony_ci int err; 389c72fcc34Sopenharmony_ci 390c72fcc34Sopenharmony_ci size = frame_count * snd_pcm_format_physical_width(sample_format) / 8; 391c72fcc34Sopenharmony_ci 392c72fcc34Sopenharmony_ci test_vec = calloc(cntr_count * 2, sizeof(*test_vec)); 393c72fcc34Sopenharmony_ci if (test_vec == NULL) 394c72fcc34Sopenharmony_ci return -ENOMEM; 395c72fcc34Sopenharmony_ci 396c72fcc34Sopenharmony_ci for (i = 0; i < cntr_count; ++i) 397c72fcc34Sopenharmony_ci test_vec[i] = test_buf + size * i; 398c72fcc34Sopenharmony_ci 399c72fcc34Sopenharmony_ci err = test_vector(trial, access, sample_format, samples_per_frame, 400c72fcc34Sopenharmony_ci frames_per_second, test_vec, frame_count, cntr_count); 401c72fcc34Sopenharmony_ci free(test_vec); 402c72fcc34Sopenharmony_ci 403c72fcc34Sopenharmony_ci return err; 404c72fcc34Sopenharmony_ci} 405c72fcc34Sopenharmony_ci 406c72fcc34Sopenharmony_cistatic int callback(struct test_generator *gen, snd_pcm_access_t access, 407c72fcc34Sopenharmony_ci snd_pcm_format_t sample_format, 408c72fcc34Sopenharmony_ci unsigned int samples_per_frame, void *frame_buffer, 409c72fcc34Sopenharmony_ci unsigned int frame_count) 410c72fcc34Sopenharmony_ci{ 411c72fcc34Sopenharmony_ci 412c72fcc34Sopenharmony_ci int (*handler)(struct mapper_trial *trial, snd_pcm_access_t access, 413c72fcc34Sopenharmony_ci snd_pcm_format_t sample_format, 414c72fcc34Sopenharmony_ci unsigned int samples_per_frame, 415c72fcc34Sopenharmony_ci unsigned int frames_per_second, void *frame_buffer, 416c72fcc34Sopenharmony_ci unsigned int frame_count, unsigned int cntr_count); 417c72fcc34Sopenharmony_ci struct mapper_trial *trial = gen->private_data; 418c72fcc34Sopenharmony_ci 419c72fcc34Sopenharmony_ci if (access == SND_PCM_ACCESS_RW_NONINTERLEAVED) 420c72fcc34Sopenharmony_ci handler = test_vector; 421c72fcc34Sopenharmony_ci else if (access == SND_PCM_ACCESS_MMAP_NONINTERLEAVED) 422c72fcc34Sopenharmony_ci handler = test_n_buf; 423c72fcc34Sopenharmony_ci else 424c72fcc34Sopenharmony_ci handler = test_i_buf; 425c72fcc34Sopenharmony_ci 426c72fcc34Sopenharmony_ci return handler(trial, access, sample_format, samples_per_frame, 48000, 427c72fcc34Sopenharmony_ci frame_buffer, frame_count, samples_per_frame); 428c72fcc34Sopenharmony_ci}; 429c72fcc34Sopenharmony_ci 430c72fcc34Sopenharmony_ciint main(int argc, const char *argv[]) 431c72fcc34Sopenharmony_ci{ 432c72fcc34Sopenharmony_ci // Test 8/16/18/20/24/32/64 bytes per sample. 433c72fcc34Sopenharmony_ci static const uint64_t sample_format_mask = 434c72fcc34Sopenharmony_ci (1ull << SND_PCM_FORMAT_U8) | 435c72fcc34Sopenharmony_ci (1ull << SND_PCM_FORMAT_S16_LE) | 436c72fcc34Sopenharmony_ci (1ull << SND_PCM_FORMAT_S18_3LE) | 437c72fcc34Sopenharmony_ci (1ull << SND_PCM_FORMAT_S20_3LE) | 438c72fcc34Sopenharmony_ci (1ull << SND_PCM_FORMAT_S24_LE) | 439c72fcc34Sopenharmony_ci (1ull << SND_PCM_FORMAT_S32_LE) | 440c72fcc34Sopenharmony_ci (1ull << SND_PCM_FORMAT_FLOAT64_LE); 441c72fcc34Sopenharmony_ci uint64_t access_mask; 442c72fcc34Sopenharmony_ci struct test_generator gen = {0}; 443c72fcc34Sopenharmony_ci struct mapper_trial *trial; 444c72fcc34Sopenharmony_ci struct container_context *cntrs; 445c72fcc34Sopenharmony_ci unsigned int samples_per_frame; 446c72fcc34Sopenharmony_ci char **paths = NULL; 447c72fcc34Sopenharmony_ci snd_pcm_access_t access; 448c72fcc34Sopenharmony_ci bool verbose; 449c72fcc34Sopenharmony_ci int i; 450c72fcc34Sopenharmony_ci int err; 451c72fcc34Sopenharmony_ci 452c72fcc34Sopenharmony_ci // Test up to 32 channels. 453c72fcc34Sopenharmony_ci samples_per_frame = 32; 454c72fcc34Sopenharmony_ci cntrs = calloc(samples_per_frame, sizeof(*cntrs)); 455c72fcc34Sopenharmony_ci if (cntrs == NULL) 456c72fcc34Sopenharmony_ci return -ENOMEM; 457c72fcc34Sopenharmony_ci 458c72fcc34Sopenharmony_ci paths = calloc(samples_per_frame, sizeof(*paths)); 459c72fcc34Sopenharmony_ci if (paths == NULL) { 460c72fcc34Sopenharmony_ci err = -ENOMEM; 461c72fcc34Sopenharmony_ci goto end; 462c72fcc34Sopenharmony_ci } 463c72fcc34Sopenharmony_ci for (i = 0; i < samples_per_frame; ++i) { 464c72fcc34Sopenharmony_ci paths[i] = malloc(8); 465c72fcc34Sopenharmony_ci if (paths[i] == NULL) { 466c72fcc34Sopenharmony_ci err = -ENOMEM; 467c72fcc34Sopenharmony_ci goto end; 468c72fcc34Sopenharmony_ci } 469c72fcc34Sopenharmony_ci snprintf(paths[i], 8, "hoge%d", i); 470c72fcc34Sopenharmony_ci } 471c72fcc34Sopenharmony_ci 472c72fcc34Sopenharmony_ci if (argc > 1) { 473c72fcc34Sopenharmony_ci char *term; 474c72fcc34Sopenharmony_ci access = strtol(argv[1], &term, 10); 475c72fcc34Sopenharmony_ci if (errno != 0 || *term != '\0') { 476c72fcc34Sopenharmony_ci err = -EINVAL;; 477c72fcc34Sopenharmony_ci goto end; 478c72fcc34Sopenharmony_ci } 479c72fcc34Sopenharmony_ci if (access < SND_PCM_ACCESS_MMAP_INTERLEAVED && 480c72fcc34Sopenharmony_ci access > SND_PCM_ACCESS_RW_NONINTERLEAVED) { 481c72fcc34Sopenharmony_ci err = -EINVAL; 482c72fcc34Sopenharmony_ci goto end; 483c72fcc34Sopenharmony_ci } 484c72fcc34Sopenharmony_ci if (access == SND_PCM_ACCESS_MMAP_COMPLEX) { 485c72fcc34Sopenharmony_ci err = -EINVAL; 486c72fcc34Sopenharmony_ci goto end; 487c72fcc34Sopenharmony_ci } 488c72fcc34Sopenharmony_ci 489c72fcc34Sopenharmony_ci access_mask = 1ull << access; 490c72fcc34Sopenharmony_ci verbose = true; 491c72fcc34Sopenharmony_ci } else { 492c72fcc34Sopenharmony_ci access_mask = (1ull << SND_PCM_ACCESS_MMAP_INTERLEAVED) | 493c72fcc34Sopenharmony_ci (1ull << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | 494c72fcc34Sopenharmony_ci (1ull << SND_PCM_ACCESS_RW_INTERLEAVED) | 495c72fcc34Sopenharmony_ci (1ull << SND_PCM_ACCESS_RW_NONINTERLEAVED); 496c72fcc34Sopenharmony_ci verbose = false; 497c72fcc34Sopenharmony_ci } 498c72fcc34Sopenharmony_ci 499c72fcc34Sopenharmony_ci err = generator_context_init(&gen, access_mask, sample_format_mask, 500c72fcc34Sopenharmony_ci 1, samples_per_frame, 501c72fcc34Sopenharmony_ci 23, 4500, 1024, 502c72fcc34Sopenharmony_ci sizeof(struct mapper_trial)); 503c72fcc34Sopenharmony_ci if (err < 0) 504c72fcc34Sopenharmony_ci goto end; 505c72fcc34Sopenharmony_ci 506c72fcc34Sopenharmony_ci trial = gen.private_data; 507c72fcc34Sopenharmony_ci trial->cntrs = cntrs; 508c72fcc34Sopenharmony_ci trial->cntr_format = CONTAINER_FORMAT_RIFF_WAVE; 509c72fcc34Sopenharmony_ci trial->paths = paths; 510c72fcc34Sopenharmony_ci trial->verbose = verbose; 511c72fcc34Sopenharmony_ci err = generator_context_run(&gen, callback); 512c72fcc34Sopenharmony_ci 513c72fcc34Sopenharmony_ci generator_context_destroy(&gen); 514c72fcc34Sopenharmony_ciend: 515c72fcc34Sopenharmony_ci if (paths) { 516c72fcc34Sopenharmony_ci for (i = 0; i < samples_per_frame; ++i) 517c72fcc34Sopenharmony_ci free(paths[i]); 518c72fcc34Sopenharmony_ci free(paths); 519c72fcc34Sopenharmony_ci } 520c72fcc34Sopenharmony_ci free(cntrs); 521c72fcc34Sopenharmony_ci 522c72fcc34Sopenharmony_ci if (err < 0) { 523c72fcc34Sopenharmony_ci printf("%s\n", strerror(-err)); 524c72fcc34Sopenharmony_ci return EXIT_FAILURE; 525c72fcc34Sopenharmony_ci } 526c72fcc34Sopenharmony_ci 527c72fcc34Sopenharmony_ci return EXIT_SUCCESS; 528c72fcc34Sopenharmony_ci} 529