Home | History | Annotate | Line # | Download | only in audiocfg
      1 /* $NetBSD: main.c,v 1.17 2023/04/01 12:41:02 mlelstv 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("%u, %uch, %uHz\n",
     95 		    adev->hwinfo.play.precision,
     96 		    adev->hwinfo.play.channels,
     97 		    adev->hwinfo.play.sample_rate);
     98 	} else {
     99 		printf("unavailable\n");
    100 	}
    101 	printf("       record:   ");
    102 	if ((adev->hwinfo.mode & AUMODE_RECORD)) {
    103 		printf("%u, %uch, %uHz\n",
    104 		    adev->hwinfo.record.precision,
    105 		    adev->hwinfo.record.channels,
    106 		    adev->hwinfo.record.sample_rate);
    107 	} else {
    108 		printf("unavailable\n");
    109 	}
    110 
    111 	TAILQ_FOREACH(f, &adev->formats, next) {
    112 		printf("       ");
    113 		if (f->fmt.priority < 0)
    114 			printf("(  ) ");
    115 		else if ((f->fmt.mode & (AUMODE_PLAY | AUMODE_RECORD))
    116 		    == (AUMODE_PLAY | AUMODE_RECORD))
    117 			printf("(PR) ");
    118 		else if ((f->fmt.mode & AUMODE_PLAY))
    119 			printf("(P-) ");
    120 		else if ((f->fmt.mode & AUMODE_RECORD))
    121 			printf("(-R) ");
    122 
    123 		if (f->fmt.encoding < encoding_max)
    124 			printf("%s", encoding_names[f->fmt.encoding]);
    125 		else
    126 			printf("unknown_encoding_%d", f->fmt.encoding);
    127 		printf(" %d/%d, %dch, ",
    128 		    f->fmt.validbits,
    129 		    f->fmt.precision,
    130 		    f->fmt.channels);
    131 		if (f->fmt.frequency_type == 0) {
    132 			printf("%d-%dHz",
    133 			    f->fmt.frequency[0],
    134 			    f->fmt.frequency[1]);
    135 		} else {
    136 			for (j = 0; j < (int)f->fmt.frequency_type; j++) {
    137 				printf("%s%d",
    138 				    (j == 0) ? "{ " : ", ",
    139 				    f->fmt.frequency[j]);
    140 			}
    141 			printf(" }");
    142 		}
    143 		printf("\n");
    144 	}
    145 }
    146 
    147 int
    148 main(int argc, char *argv[])
    149 {
    150 	struct audiodev *adev;
    151 	unsigned int n, i;
    152 	unsigned int j;
    153 	const char *enc;
    154 	unsigned int prec;
    155 	unsigned int ch;
    156 	unsigned int freq;
    157 	int mode;
    158 
    159 	if (audiodev_refresh() == -1)
    160 		return EXIT_FAILURE;
    161 
    162 	if (argc < 2)
    163 		usage();
    164 		/* NOTREACHED */
    165 
    166 	if (strcmp(argv[1], "list") == 0 && argc == 2) {
    167 		n = audiodev_count();
    168 		for (i = 0; i < n; i++)
    169 			print_audiodev(audiodev_get(i), i);
    170 	} else if (strcmp(argv[1], "list") == 0 && argc == 3) {
    171 		if (*argv[2] < '0' || *argv[2] > '9')
    172 			usage();
    173 			/* NOTREACHED */
    174 		errno = 0;
    175 		i = strtoul(argv[2], NULL, 10);
    176 		if (errno)
    177 			usage();
    178 			/* NOTREACHED */
    179 		adev = audiodev_get(i);
    180 		if (adev == NULL) {
    181 			errx(EXIT_FAILURE, "no such device");
    182 		}
    183 		print_audiodev(adev, i);
    184 	} else if (strcmp(argv[1], "default") == 0 && argc == 3) {
    185 		if (*argv[2] < '0' || *argv[2] > '9')
    186 			usage();
    187 			/* NOTREACHED */
    188 		errno = 0;
    189 		i = strtoul(argv[2], NULL, 10);
    190 		if (errno)
    191 			usage();
    192 			/* NOTREACHED */
    193 		adev = audiodev_get(i);
    194 		if (adev == NULL) {
    195 			errx(EXIT_FAILURE, "no such device");
    196 		}
    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 		if (*argv[2] < '0' || *argv[2] > '9')
    205 			usage();
    206 			/* NOTREACHED */
    207 		errno = 0;
    208 		i = strtoul(argv[2], NULL, 10);
    209 		if (errno)
    210 			usage();
    211 			/* NOTREACHED */
    212 		adev = audiodev_get(i);
    213 		if (adev == NULL) {
    214 			errx(EXIT_FAILURE, "no such device");
    215 		}
    216 
    217 		mode = 0;
    218 		for (j = 0; j < strlen(argv[3]); j++) {
    219 			if (argv[3][j] == 'p')
    220 				mode |= AUMODE_PLAY;
    221 			else if (argv[3][j] == 'r')
    222 				mode |= AUMODE_RECORD;
    223 			else
    224 				usage();
    225 		}
    226 		if (mode == 0)
    227 			usage();
    228 			/* NOTREACHED */
    229 		enc = argv[4];
    230 		prec = strtoul(argv[5], NULL, 10);
    231 		if (errno)
    232 			usage();
    233 		errno = 0;
    234 		ch = strtoul(argv[6], NULL, 10);
    235 		if (errno)
    236 			usage();
    237 			/* NOTREACHED */
    238 		errno = 0;
    239 		freq = strtoul(argv[7], NULL, 10);
    240 		if (errno)
    241 			usage();
    242 			/* NOTREACHED */
    243 
    244 		if (audiodev_set_param(adev, mode, enc, prec, ch, freq) == -1) {
    245 			errx(EXIT_FAILURE, "couldn't set parameter");
    246 		}
    247 	} else if (strcmp(argv[1], "test") == 0 && argc == 3) {
    248 		if (*argv[2] < '0' || *argv[2] > '9')
    249 			usage();
    250 			/* NOTREACHED */
    251 		errno = 0;
    252 		i = strtoul(argv[2], NULL, 10);
    253 		if (errno)
    254 			usage();
    255 			/* NOTREACHED */
    256 		adev = audiodev_get(i);
    257 		if (adev == NULL) {
    258 			errx(EXIT_FAILURE, "no such device");
    259 		}
    260 		print_audiodev(adev, i);
    261 		if (audiodev_test(adev) == -1)
    262 			return EXIT_FAILURE;
    263 	} else
    264 		usage();
    265 		/* NOTREACHED */
    266 
    267 	return EXIT_SUCCESS;
    268 }
    269