"Fossies" - the Fresh Open Source Software Archive

Member "alsa-utils-1.1.9/axfer/test/mapper-test.c" (10 May 2019, 13021 Bytes) of package /linux/misc/alsa-utils-1.1.9.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "mapper-test.c": 1.1.8_vs_1.1.9.

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