"Fossies" - the Fresh Open Source Software Archive

Member "alsa-oss-1.1.8/test/osstest.c" (7 Jan 2019, 9436 Bytes) of package /linux/misc/alsa-oss-1.1.8.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.

    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <unistd.h>
    4 #include <fcntl.h>
    5 #include <string.h>
    6 #include <getopt.h>
    7 #include <sys/types.h>
    8 #include <sys/mman.h>
    9 #include <sys/soundcard.h>
   10 #include <sys/time.h>
   11 #include <sys/poll.h>
   12 #include <oss-redir.h>
   13 
   14 //static char data[500000];
   15 static int verbose;
   16 static char *device = "/dev/dsp";
   17 static int format = AFMT_S16_LE;
   18 static int rate = 48000;
   19 static int channels = 2;
   20 static int omode = O_RDWR;
   21 static int frag = 0xffff000c;   /* Max # periods of 2^13=8k bytes */
   22 static int fd;
   23 static audio_buf_info ospace;
   24 static audio_buf_info ispace;
   25 static int bufsize;
   26 static int fragsize;
   27 static char *wbuf = NULL, *rbuf = NULL;
   28 static int loop = 40;
   29 
   30 static void help(void)
   31 {
   32     printf(
   33 "Usage: mmap_test [OPTION]...\n"
   34 "-h,--help      help\n"
   35 "-D,--device    playback device\n"
   36 "-r,--rate      stream rate in Hz\n"
   37 "-c,--channels  count of channels in stream\n"
   38 //"-f,--frequency   sine wave frequency in Hz\n"
   39 "-F,--frag      OSS fragment settings (SNDCTL_DSP_SETFRAGMENT)\n"
   40 "-M,--omode     open mode (read/write/duplex)\n"
   41 "-m,--method    transfer method (rw, mmap_and_select, mmap_and_poll)\n"
   42 "-L,--loop      set loop count\n"
   43 "-v,--verbose   show more info\n"
   44 "\n");
   45 }
   46 
   47 static void set_params(int do_mmap)
   48 {
   49     int caps;
   50 
   51     if (oss_pcm_ioctl(fd, SNDCTL_DSP_SETFMT, &format) < 0) {
   52         perror("SNDCTL_DSP_SETFMT\n");
   53         exit(EXIT_FAILURE);
   54     }
   55     printf("Format set to %d\n", format);
   56 
   57     if (oss_pcm_ioctl(fd, SNDCTL_DSP_SPEED, &rate) < 0) {
   58         perror("SNDCTL_DSP_SPEED\n");
   59         exit(EXIT_FAILURE);
   60     }
   61     printf("Rate set to %d\n", rate);
   62 
   63     if (oss_pcm_ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) < 0) {
   64         perror("SNDCTL_DSP_CHANNELS\n");
   65         exit(EXIT_FAILURE);
   66     }
   67     printf("Channels set to %d\n", channels);
   68 
   69     if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) < 0) {
   70         perror("/dev/dsp");
   71         fprintf(stderr, "Sorry but your sound driver is too old\n");
   72         exit(EXIT_FAILURE);
   73     }
   74     if (do_mmap &&
   75             (!(caps & DSP_CAP_TRIGGER) ||
   76          !(caps & DSP_CAP_MMAP)))
   77     {
   78         fprintf(stderr, "Sorry but your soundcard can't do this\n");
   79         exit(EXIT_FAILURE);
   80     }
   81     if (oss_pcm_ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag) < 0)
   82         perror("SNDCTL_DSP_SETFRAGMENT");
   83     bufsize = fragsize = -1;
   84     if (omode == O_RDWR || omode == O_WRONLY) {
   85         if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETOSPACE, &ospace) < 0) {
   86             perror("SNDCTL_DSP_GETOSPACE");
   87             exit(EXIT_FAILURE);
   88         }
   89         bufsize = ospace.fragstotal * ospace.fragsize;
   90         fragsize = ospace.fragsize;
   91         printf("ospace.fragstotal = %i\n", ospace.fragstotal);
   92         printf("ospace.fragsize = %i\n", ospace.fragsize);
   93         printf("ospace.periods = %i\n", ospace.fragments);
   94         printf("ospace.bytes = %i\n", ospace.bytes);
   95         if (do_mmap) {
   96             if ((wbuf=mmap(NULL, bufsize, PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0))==MAP_FAILED) {
   97                 perror("mmap (write)");
   98                 exit(-1);
   99             }
  100             printf("mmap (out) returned %p\n", wbuf);
  101         }
  102     }
  103     if (omode == O_RDWR || omode == O_RDONLY) {
  104         if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETISPACE, &ispace) < 0) {
  105             perror("SNDCTL_DSP_GETISPACE");
  106             if (omode == O_RDWR) {
  107                 omode = O_WRONLY;
  108                 fprintf(stderr, "Falling to write only mode\n");
  109             } else {
  110                 exit(EXIT_FAILURE);
  111             }
  112         }
  113         if (omode != O_WRONLY) {
  114             if (bufsize < 0) {
  115                 bufsize = ispace.fragstotal * ispace.fragsize;
  116                 fragsize = ispace.fragsize;
  117             }
  118             printf("ispace.fragstotal = %i\n", ispace.fragstotal);
  119             printf("ispace.fragsize = %i\n", ispace.fragsize);
  120             printf("ispace.periods = %i\n", ispace.fragments);
  121             printf("ispace.bytes = %i\n", ispace.bytes);
  122             if (do_mmap) {
  123                 if ((rbuf=mmap(NULL, bufsize, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0))==MAP_FAILED) {
  124                     perror("mmap (read)");
  125                     exit(-1);
  126                 }
  127                 printf("mmap (in) returned %p\n", rbuf);
  128             }
  129         }
  130     }
  131 }
  132 
  133 static void set_trigger(void)
  134 {
  135     int tmp;
  136 
  137     tmp = 0;
  138     if (oss_pcm_ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp) < 0) {
  139         perror("SNDCTL_DSP_SETTRIGGER");
  140         exit(EXIT_FAILURE);
  141     }
  142     printf("Trigger set to %08x\n", tmp);
  143 
  144     if (omode == O_RDWR)
  145         tmp = PCM_ENABLE_OUTPUT|PCM_ENABLE_INPUT;
  146     else if (omode == O_RDONLY)
  147         tmp = PCM_ENABLE_INPUT;
  148     else if (omode == O_WRONLY)
  149         tmp = PCM_ENABLE_OUTPUT;
  150     if (oss_pcm_ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp) < 0) {
  151         perror("SNDCTL_DSP_SETTRIGGER");
  152         exit(EXIT_FAILURE);
  153     }
  154     printf("Trigger set to %08x\n", tmp);
  155 }
  156 
  157 static void rw_loop(void)
  158 {
  159     int idx, first = 1;
  160 
  161     for (idx=0; idx<loop; idx++) {
  162         char buf[1000];
  163         if (omode != O_RDONLY) {
  164             ssize_t res;
  165             if (first) {
  166                 res = oss_pcm_write(fd, buf, sizeof(buf));
  167                 if (verbose)
  168                     printf("write: (%i) -> %i\n", sizeof(buf), (int)res);
  169             }
  170             res = oss_pcm_write(fd, buf, sizeof(buf));
  171             if (verbose)
  172                 printf("write: (%i) -> %i\n", sizeof(buf), (int)res);
  173             first = 0;
  174         }
  175         if (omode != O_WRONLY) {
  176             ssize_t res = oss_pcm_read(fd, buf, sizeof(buf));
  177             if (verbose)
  178                 printf("read: (%i) -> %i\n", sizeof(buf), (int)res);
  179         }
  180     }
  181 }
  182 
  183 static void rw_and_select_loop(void)
  184 {
  185 }
  186 
  187 static void rw_and_poll_loop(void)
  188 {
  189 }
  190 
  191 static void mmap_loop(void)
  192 {
  193 }
  194 
  195 static void mmap_and_select_loop(void)
  196 {
  197     int nfrag_in = 0, nfrag_out = 0, idx;
  198     struct timeval tim;
  199     fd_set writeset, readset;
  200 
  201     for (idx=0; idx<loop; idx++) {
  202         struct count_info count_in, count_out;
  203         int res, maxfd;
  204 
  205         FD_ZERO(&writeset);
  206         FD_ZERO(&readset);
  207         maxfd = oss_pcm_select_prepare(fd, omode, &readset, &writeset, NULL);
  208 
  209         tim.tv_sec = 10;
  210         tim.tv_usec = 0;
  211 
  212         res = select(maxfd + 1, &readset, &writeset, NULL, &tim);
  213         if (res < 0)
  214             perror("select\n");
  215         if (verbose) {
  216             printf("Select returned: %03d\n", res);
  217             fflush(stdout);
  218         }
  219         if (omode != O_WRONLY) {
  220             if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETIPTR, &count_in) < 0) {
  221                 perror("GETOPTR");
  222                 exit(EXIT_FAILURE);
  223             }
  224             nfrag_in += count_in.blocks;
  225             if (verbose) {
  226                 printf("GETIPTR: Total: %09d, Period: %03d, Ptr: %06d\n", count_in.bytes, nfrag_in, count_in.ptr);
  227                 fflush(stdout);
  228             }
  229         }
  230         if (omode != O_RDONLY) {
  231             if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETOPTR, &count_out) < 0) {
  232                 perror("GETOPTR");
  233                 exit(EXIT_FAILURE);
  234             }
  235             nfrag_out += count_out.blocks;
  236             if (verbose) {
  237                 printf("GETOPTR: Total: %09d, Period: %03d, Ptr: %06d\n", count_out.bytes, nfrag_out, count_out.ptr);
  238                 fflush(stdout);
  239             }
  240         }
  241     }
  242 }
  243 
  244 static void mmap_and_poll_loop(void)
  245 {
  246     int nfrag_in = 0, nfrag_out = 0, idx;
  247     int fd_count;
  248     
  249     fd_count = oss_pcm_poll_fds(fd);
  250 
  251     for (idx=0; idx<loop; idx++) {
  252         struct pollfd ufds[fd_count];
  253         struct count_info count_in, count_out;
  254         int res;
  255 
  256         oss_pcm_poll_prepare(fd, omode, ufds);
  257 
  258         res = poll(ufds, fd_count, 10000);
  259         if (res < 0)
  260             perror("poll\n");
  261         if (verbose) {
  262             printf("Poll returned: %03d\n", res);
  263             fflush(stdout);
  264         }
  265         if (omode != O_WRONLY) {
  266             if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETIPTR, &count_in) < 0) {
  267                 perror("GETOPTR");
  268                 exit(EXIT_FAILURE);
  269             }
  270             nfrag_in += count_in.blocks;
  271             if (verbose) {
  272                 printf("GETIPTR: Total: %09d, Period: %03d, Ptr: %06d\n", count_in.bytes, nfrag_in, count_in.ptr);
  273                 fflush(stdout);
  274             }
  275         }
  276         if (omode != O_RDONLY) {
  277             if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETOPTR, &count_out) < 0) {
  278                 perror("GETOPTR");
  279                 exit(EXIT_FAILURE);
  280             }
  281             nfrag_out += count_out.blocks;
  282             if (verbose) {
  283                 printf("GETOPTR: Total: %09d, Period: %03d, Ptr: %06d\n", count_out.bytes, nfrag_out, count_out.ptr);
  284                 fflush(stdout);
  285             }
  286         }
  287     }
  288 }
  289 
  290 struct transfer_method {
  291     const char *name;
  292     int do_mmap;
  293     void (*transfer_loop)(void);
  294 };
  295 
  296 static struct transfer_method transfer_methods[] = {
  297     { "rw", 0, rw_loop },
  298     { "rw_and_select", 0, rw_and_select_loop },
  299     { "rw_and_poll", 0, rw_and_poll_loop },
  300     { "mmap", 1, mmap_loop },
  301     { "mmap_and_select", 1, mmap_and_select_loop },
  302     { "mmap_and_poll", 1, mmap_and_poll_loop },
  303     { NULL, 0, NULL }
  304 };
  305 
  306 int main(int argc, char *argv[])
  307 {
  308     int morehelp = 0;
  309     int method = 0;
  310         struct option long_option[] =
  311         {
  312         {"help", 0, NULL, 'h'},
  313         {"device", 1, NULL, 'D'},
  314                 {"verbose", 1, NULL, 'v'},
  315         {"omode", 1, NULL, 'M'},
  316         {"mode", 1, NULL, 'm'},
  317         {"rate", 1, NULL, 'r'},
  318         {"channels", 1, NULL, 'c'},
  319         {"frag", 1, NULL, 'F'},
  320         {"loop", 1, NULL, 'L'},
  321                 {NULL, 0, NULL, 0},
  322         };
  323 
  324         morehelp = 0;
  325     while (1) {
  326         int c;
  327         if ((c = getopt_long(argc, argv, "hD:M:m:r:c:F:L:v", long_option, NULL)) < 0)
  328             break;
  329         switch (c) {
  330         case 'h':
  331             morehelp++;
  332             break;
  333         case 'D':
  334             device = strdup(optarg);
  335             break;
  336         case 'M':
  337             if (!strcmp(optarg, "read"))
  338                 omode = O_RDONLY;
  339             else if (!strcmp(optarg, "write"))
  340                 omode = O_WRONLY;
  341             else
  342                 omode = O_RDWR;
  343             break;
  344         case 'm':
  345             for (method = 0; transfer_methods[method].name; method++)
  346                 if (!strcasecmp(transfer_methods[method].name, optarg))
  347                     break;
  348             if (transfer_methods[method].name == NULL)
  349                 method = 0;
  350             break;
  351         case 'r':
  352             rate = atoi(optarg);
  353             break;
  354         case 'c':
  355             channels = atoi(optarg);
  356             break;
  357         case 'F':
  358             frag = atoi(optarg);
  359             break;
  360         case 'L':
  361             loop = atoi(optarg);
  362             break;
  363         case 'v':
  364             verbose = 1;
  365             break;
  366         }
  367     }
  368 
  369         if (morehelp) {
  370                 help();
  371                 return 0;
  372         }
  373 
  374     printf("Using transfer method %s\n", transfer_methods[method].name);
  375 
  376     if ((fd=oss_pcm_open(device, O_RDWR, 0))==-1) {
  377         perror(device);
  378         exit(-1);
  379     }
  380 
  381     printf("Device %s opened sucessfully\n", device);
  382 
  383     set_params(transfer_methods[method].do_mmap);
  384     if (transfer_methods[method].do_mmap)
  385         set_trigger();
  386 
  387     transfer_methods[method].transfer_loop();
  388 
  389     close(fd);
  390 
  391     exit(0);
  392 }