Home | History | Annotate | Line # | Download | only in audiocfg
main.c revision 1.15
      1 /* $NetBSD: main.c,v 1.15 2019/08/24 06:11:10 isaki 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)
     79 {
     80 	struct audiofmt *f;
     81 	int j;
     82 
     83 	assert(adev != NULL);
     84 
     85 	printf("[%c] %s @ %s: ",
     86 	    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 /* Always return non-null adev, or exit */
    146 static struct audiodev *
    147 getadev_fromstr(const char *str)
    148 {
    149 	struct audiodev *adev;
    150 	unsigned int i;
    151 
    152 	if (*str < '0' || *str > '9')
    153 		usage();
    154 		/* NOTREACHED */
    155 	errno = 0;
    156 	i = strtoul(str, NULL, 10);
    157 	if (errno)
    158 		usage();
    159 		/* NOTREACHED */
    160 	adev = audiodev_get(i);
    161 	if (adev == NULL) {
    162 		errx(EXIT_FAILURE, "no such device");
    163 	}
    164 	return adev;
    165 }
    166 
    167 int
    168 main(int argc, char *argv[])
    169 {
    170 	struct audiodev *adev;
    171 	unsigned int n, i;
    172 	unsigned int j;
    173 	const char *enc;
    174 	unsigned int prec;
    175 	unsigned int ch;
    176 	unsigned int freq;
    177 	int mode;
    178 
    179 	if (audiodev_refresh() == -1)
    180 		return EXIT_FAILURE;
    181 
    182 	if (argc < 2)
    183 		usage();
    184 		/* NOTREACHED */
    185 
    186 	if (strcmp(argv[1], "list") == 0 && argc == 2) {
    187 		n = audiodev_maxunit();
    188 		for (i = 0; i <= n; i++) {
    189 			adev = audiodev_get(i);
    190 			if (adev)
    191 				print_audiodev(adev);
    192 		}
    193 	} else if (strcmp(argv[1], "list") == 0 && argc == 3) {
    194 		print_audiodev(getadev_fromstr(argv[2]));
    195 	} else if (strcmp(argv[1], "default") == 0 && argc == 3) {
    196 		adev = getadev_fromstr(argv[2]);
    197 		printf("setting default audio device to %s\n", adev->xname);
    198 		if (audiodev_set_default(adev) == -1) {
    199 			errx(EXIT_FAILURE, "couldn't set default device");
    200 		}
    201 	} else if (strcmp(argv[1], "set") == 0 && argc == 8) {
    202 		/* XXX bad commandline... */
    203 		/* audiocfg set <index> [p|r] <enc> <prec> <ch> <freq> */
    204 		adev = getadev_fromstr(argv[2]);
    205 		mode = 0;
    206 		for (j = 0; j < strlen(argv[3]); j++) {
    207 			if (argv[3][j] == 'p')
    208 				mode |= AUMODE_PLAY;
    209 			else if (argv[3][j] == 'r')
    210 				mode |= AUMODE_RECORD;
    211 			else
    212 				usage();
    213 		}
    214 		if (mode == 0)
    215 			usage();
    216 			/* NOTREACHED */
    217 		enc = argv[4];
    218 		prec = strtoul(argv[5], NULL, 10);
    219 		if (errno)
    220 			usage();
    221 		errno = 0;
    222 		ch = strtoul(argv[6], NULL, 10);
    223 		if (errno)
    224 			usage();
    225 			/* NOTREACHED */
    226 		errno = 0;
    227 		freq = strtoul(argv[7], NULL, 10);
    228 		if (errno)
    229 			usage();
    230 			/* NOTREACHED */
    231 
    232 		if (audiodev_set_param(adev, mode, enc, prec, ch, freq) == -1) {
    233 			errx(EXIT_FAILURE, "couldn't set parameter");
    234 		}
    235 	} else if (strcmp(argv[1], "test") == 0 && argc == 3) {
    236 		adev = getadev_fromstr(argv[2]);
    237 		print_audiodev(adev);
    238 		if (audiodev_test(adev) == -1)
    239 			return EXIT_FAILURE;
    240 	} else
    241 		usage();
    242 		/* NOTREACHED */
    243 
    244 	return EXIT_SUCCESS;
    245 }
    246