Home | History | Annotate | Line # | Download | only in audiocfg
main.c revision 1.8.2.3
      1 /* $NetBSD: main.c,v 1.8.2.3 2019/09/29 07:34:09 martin Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2010 Jared D. McNeill <jmcneill (at) invisible.ca>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <assert.h>
     30 #include <err.h>
     31 #include <errno.h>
     32 #include <fcntl.h>
     33 #include <limits.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <unistd.h>
     37 
     38 #include "audiodev.h"
     39 #include "drvctl.h"
     40 
     41 __dead static void
     42 usage(void)
     43 {
     44 	const char *p = getprogname();
     45 
     46 	fprintf(stderr, "usage: %s list [<index>]\n", p);
     47 	fprintf(stderr, "       %s default <index>\n", p);
     48 	fprintf(stderr, "       %s set  <index> [p|r] <enc> <prec> <ch> <freq>\n",
     49 	    p);
     50 	fprintf(stderr, "       %s test <index>\n", p);
     51 	exit(EXIT_FAILURE);
     52 }
     53 
     54 const char *encoding_names[] = {
     55 	"none",
     56 	AudioEmulaw,
     57 	AudioEalaw,
     58 	"pcm16",
     59 	"pcm8",
     60 	AudioEadpcm,
     61 	AudioEslinear_le,
     62 	AudioEslinear_be,
     63 	AudioEulinear_le,
     64 	AudioEulinear_be,
     65 	AudioEslinear,
     66 	AudioEulinear,
     67 	AudioEmpeg_l1_stream,
     68 	AudioEmpeg_l1_packets,
     69 	AudioEmpeg_l1_system,
     70 	AudioEmpeg_l2_stream,
     71 	AudioEmpeg_l2_packets,
     72 	AudioEmpeg_l2_system,
     73 	AudioEac3,
     74 };
     75 u_int encoding_max = __arraycount(encoding_names);
     76 
     77 static void
     78 print_audiodev(struct audiodev *adev, int i)
     79 {
     80 	struct audiofmt *f;
     81 	int j;
     82 
     83 	assert(adev != NULL);
     84 
     85 	printf("%u: [%c] %s @ %s: ",
     86 	    i, adev->defaultdev ? '*' : ' ',
     87 	    adev->xname, adev->pxname);
     88 	printf("%s", adev->audio_device.name);
     89 	if (strlen(adev->audio_device.version) > 0)
     90 		printf(" %s", adev->audio_device.version);
     91 	printf("\n");
     92 	printf("       playback: ");
     93 	if ((adev->hwinfo.mode & AUMODE_PLAY)) {
     94 		printf("%uch, %uHz\n",
     95 		    adev->hwinfo.play.channels,
     96 		    adev->hwinfo.play.sample_rate);
     97 	} else {
     98 		printf("unavailable\n");
     99 	}
    100 	printf("       record:   ");
    101 	if ((adev->hwinfo.mode & AUMODE_RECORD)) {
    102 		printf("%uch, %uHz\n",
    103 		    adev->hwinfo.record.channels,
    104 		    adev->hwinfo.record.sample_rate);
    105 	} else {
    106 		printf("unavailable\n");
    107 	}
    108 
    109 	TAILQ_FOREACH(f, &adev->formats, next) {
    110 		printf("       ");
    111 		if (f->fmt.priority < 0)
    112 			printf("(  ) ");
    113 		else if ((f->fmt.mode & (AUMODE_PLAY | AUMODE_RECORD))
    114 		    == (AUMODE_PLAY | AUMODE_RECORD))
    115 			printf("(PR) ");
    116 		else if ((f->fmt.mode & AUMODE_PLAY))
    117 			printf("(P-) ");
    118 		else if ((f->fmt.mode & AUMODE_RECORD))
    119 			printf("(-R) ");
    120 
    121 		if (f->fmt.encoding < encoding_max)
    122 			printf("%s", encoding_names[f->fmt.encoding]);
    123 		else
    124 			printf("unknown_encoding_%d", f->fmt.encoding);
    125 		printf(" %d/%d, %dch, ",
    126 		    f->fmt.validbits,
    127 		    f->fmt.precision,
    128 		    f->fmt.channels);
    129 		if (f->fmt.frequency_type == 0) {
    130 			printf("%d-%dHz",
    131 			    f->fmt.frequency[0],
    132 			    f->fmt.frequency[1]);
    133 		} else {
    134 			for (j = 0; j < (int)f->fmt.frequency_type; j++) {
    135 				printf("%s%d",
    136 				    (j == 0) ? "{ " : ", ",
    137 				    f->fmt.frequency[j]);
    138 			}
    139 			printf(" }");
    140 		}
    141 		printf("\n");
    142 	}
    143 }
    144 
    145 int
    146 main(int argc, char *argv[])
    147 {
    148 	struct audiodev *adev;
    149 	unsigned int n, i;
    150 	unsigned int j;
    151 	const char *enc;
    152 	unsigned int prec;
    153 	unsigned int ch;
    154 	unsigned int freq;
    155 	int mode;
    156 
    157 	if (audiodev_refresh() == -1)
    158 		return EXIT_FAILURE;
    159 
    160 	if (argc < 2)
    161 		usage();
    162 		/* NOTREACHED */
    163 
    164 	if (strcmp(argv[1], "list") == 0 && argc == 2) {
    165 		n = audiodev_count();
    166 		for (i = 0; i < n; i++)
    167 			print_audiodev(audiodev_get(i), i);
    168 	} else if (strcmp(argv[1], "list") == 0 && argc == 3) {
    169 		errno = 0;
    170 		i = strtoul(argv[2], NULL, 10);
    171 		if (errno)
    172 			usage();
    173 			/* NOTREACHED */
    174 		adev = audiodev_get(i);
    175 		if (adev == NULL) {
    176 			errx(EXIT_FAILURE, "no such device");
    177 		}
    178 		print_audiodev(adev, i);
    179 	} else if (strcmp(argv[1], "default") == 0 && argc == 3) {
    180 		if (*argv[2] < '0' || *argv[2] > '9')
    181 			usage();
    182 			/* NOTREACHED */
    183 		errno = 0;
    184 		i = strtoul(argv[2], NULL, 10);
    185 		if (errno)
    186 			usage();
    187 			/* NOTREACHED */
    188 		adev = audiodev_get(i);
    189 		if (adev == NULL) {
    190 			errx(EXIT_FAILURE, "no such device");
    191 		}
    192 		printf("setting default audio device to %s\n", adev->xname);
    193 		if (audiodev_set_default(adev) == -1) {
    194 			errx(EXIT_FAILURE, "couldn't set default device");
    195 		}
    196 	} else if (strcmp(argv[1], "set") == 0 && argc == 8) {
    197 		/* XXX bad commandline... */
    198 		/* audiocfg set <index> [p|r] <enc> <prec> <ch> <freq> */
    199 		if (*argv[2] < '0' || *argv[2] > '9')
    200 			usage();
    201 			/* NOTREACHED */
    202 		errno = 0;
    203 		i = strtoul(argv[2], NULL, 10);
    204 		if (errno)
    205 			usage();
    206 			/* NOTREACHED */
    207 		adev = audiodev_get(i);
    208 		if (adev == NULL) {
    209 			errx(EXIT_FAILURE, "no such device");
    210 		}
    211 
    212 		mode = 0;
    213 		for (j = 0; j < strlen(argv[3]); j++) {
    214 			if (argv[3][j] == 'p')
    215 				mode |= AUMODE_PLAY;
    216 			else if (argv[3][j] == 'r')
    217 				mode |= AUMODE_RECORD;
    218 			else
    219 				usage();
    220 		}
    221 		enc = argv[4];
    222 		prec = strtoul(argv[5], NULL, 10);
    223 		if (errno)
    224 			usage();
    225 		errno = 0;
    226 		ch = strtoul(argv[6], NULL, 10);
    227 		if (errno)
    228 			usage();
    229 			/* NOTREACHED */
    230 		errno = 0;
    231 		freq = strtoul(argv[7], NULL, 10);
    232 		if (errno)
    233 			usage();
    234 			/* NOTREACHED */
    235 
    236 		if (audiodev_set_param(adev, mode, enc, prec, ch, freq) == -1) {
    237 			errx(EXIT_FAILURE, "couldn't set parameter");
    238 		}
    239 	} else if (strcmp(argv[1], "test") == 0 && argc == 3) {
    240 		if (*argv[2] < '0' || *argv[2] > '9')
    241 			usage();
    242 			/* NOTREACHED */
    243 		errno = 0;
    244 		i = strtoul(argv[2], NULL, 10);
    245 		if (errno)
    246 			usage();
    247 			/* NOTREACHED */
    248 		adev = audiodev_get(i);
    249 		if (adev == NULL) {
    250 			errx(EXIT_FAILURE, "no such device");
    251 		}
    252 		print_audiodev(adev, i);
    253 		if (audiodev_test(adev) == -1)
    254 			return EXIT_FAILURE;
    255 	} else
    256 		usage();
    257 		/* NOTREACHED */
    258 
    259 	return EXIT_SUCCESS;
    260 }
    261