Home | History | Annotate | Line # | Download | only in audiocfg
main.c revision 1.8.2.1
      1 /* $NetBSD: main.c,v 1.8.2.1 2019/09/28 07:25:53 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 <errno.h>
     31 #include <fcntl.h>
     32 #include <limits.h>
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 #include <unistd.h>
     36 
     37 #include "audiodev.h"
     38 #include "drvctl.h"
     39 
     40 __dead static void
     41 usage(const char *p)
     42 {
     43 	fprintf(stderr, "usage: %s list [<index>]\n", p);
     44 	fprintf(stderr, "       %s default <index>\n", p);
     45 	fprintf(stderr, "       %s set  <index> [p|r] <enc> <prec> <ch> <freq>\n",
     46 	    p);
     47 	fprintf(stderr, "       %s test <index>\n", p);
     48 	exit(EXIT_FAILURE);
     49 }
     50 
     51 const char *encoding_names[] = {
     52 	"none",
     53 	AudioEmulaw,
     54 	AudioEalaw,
     55 	"pcm16",
     56 	"pcm8",
     57 	AudioEadpcm,
     58 	AudioEslinear_le,
     59 	AudioEslinear_be,
     60 	AudioEulinear_le,
     61 	AudioEulinear_be,
     62 	AudioEslinear,
     63 	AudioEulinear,
     64 	AudioEmpeg_l1_stream,
     65 	AudioEmpeg_l1_packets,
     66 	AudioEmpeg_l1_system,
     67 	AudioEmpeg_l2_stream,
     68 	AudioEmpeg_l2_packets,
     69 	AudioEmpeg_l2_system,
     70 	AudioEac3,
     71 };
     72 u_int encoding_max = __arraycount(encoding_names);
     73 
     74 static void
     75 print_audiodev(struct audiodev *adev, int i)
     76 {
     77 	struct audiofmt *f;
     78 	int j;
     79 
     80 	assert(adev != NULL);
     81 
     82 	printf("%u: [%c] %s @ %s: ",
     83 	    i, adev->defaultdev ? '*' : ' ',
     84 	    adev->xname, adev->pxname);
     85 	printf("%s", adev->audio_device.name);
     86 	if (strlen(adev->audio_device.version) > 0)
     87 		printf(" %s", adev->audio_device.version);
     88 	printf("\n");
     89 	printf("       playback: ");
     90 	if ((adev->info.mode & AUMODE_PLAY))
     91 		printf("%uch, %uHz\n",
     92 		    adev->info.play.channels, adev->info.play.sample_rate);
     93 	else
     94 		printf("unavailable\n");
     95 	printf("       record:   ");
     96 	if ((adev->info.mode & AUMODE_RECORD))
     97 		printf("%uch, %uHz\n",
     98 		    adev->info.record.channels, adev->info.record.sample_rate);
     99 	else
    100 		printf("unavailable\n");
    101 
    102 	TAILQ_FOREACH(f, &adev->formats, next) {
    103 		printf("       ");
    104 		if (f->fmt.priority < 0)
    105 			printf("(  ) ");
    106 		else if ((f->fmt.mode & (AUMODE_PLAY | AUMODE_RECORD))
    107 		    == (AUMODE_PLAY | AUMODE_RECORD))
    108 			printf("(PR) ");
    109 		else if ((f->fmt.mode & AUMODE_PLAY))
    110 			printf("(P-) ");
    111 		else if ((f->fmt.mode & AUMODE_RECORD))
    112 			printf("(-R) ");
    113 
    114 		if (f->fmt.encoding < encoding_max)
    115 			printf("%s", encoding_names[f->fmt.encoding]);
    116 		else
    117 			printf("unknown_encoding_%d", f->fmt.encoding);
    118 		printf(" %d/%d, %dch, ",
    119 		    f->fmt.validbits,
    120 		    f->fmt.precision,
    121 		    f->fmt.channels);
    122 		if (f->fmt.frequency_type == 0) {
    123 			printf("%d-%dHz",
    124 			    f->fmt.frequency[0],
    125 			    f->fmt.frequency[1]);
    126 		} else {
    127 			for (j = 0; j < (int)f->fmt.frequency_type; j++) {
    128 				printf("%s%d",
    129 				    (j == 0) ? "{ " : ", ",
    130 				    f->fmt.frequency[j]);
    131 			}
    132 			printf(" }");
    133 		}
    134 		printf("\n");
    135 	}
    136 }
    137 
    138 int
    139 main(int argc, char *argv[])
    140 {
    141 	struct audiodev *adev;
    142 	unsigned int n, i;
    143 	unsigned int j;
    144 	const char *enc;
    145 	unsigned int prec;
    146 	unsigned int ch;
    147 	unsigned int freq;
    148 	int mode;
    149 
    150 	if (audiodev_refresh() == -1)
    151 		return EXIT_FAILURE;
    152 
    153 	if (argc < 2)
    154 		usage(argv[0]);
    155 		/* NOTREACHED */
    156 
    157 	if (strcmp(argv[1], "list") == 0 && argc == 2) {
    158 		n = audiodev_count();
    159 		for (i = 0; i < n; i++)
    160 			print_audiodev(audiodev_get(i), i);
    161 	} else if (strcmp(argv[1], "list") == 0 && argc == 3) {
    162 		errno = 0;
    163 		i = strtoul(argv[2], NULL, 10);
    164 		if (errno)
    165 			usage(argv[0]);
    166 			/* NOTREACHED */
    167 		adev = audiodev_get(i);
    168 		if (adev == NULL) {
    169 			fprintf(stderr, "no such device\n");
    170 			return EXIT_FAILURE;
    171 		}
    172 		print_audiodev(adev, i);
    173 	} else if (strcmp(argv[1], "default") == 0 && argc == 3) {
    174 		if (*argv[2] < '0' || *argv[2] > '9')
    175 			usage(argv[0]);
    176 			/* NOTREACHED */
    177 		errno = 0;
    178 		i = strtoul(argv[2], NULL, 10);
    179 		if (errno)
    180 			usage(argv[0]);
    181 			/* NOTREACHED */
    182 		adev = audiodev_get(i);
    183 		if (adev == NULL) {
    184 			fprintf(stderr, "no such device\n");
    185 			return EXIT_FAILURE;
    186 		}
    187 		printf("setting default audio device to %s\n", adev->xname);
    188 		if (audiodev_set_default(adev) == -1) {
    189 			perror("couldn't set default device");
    190 			return EXIT_FAILURE;
    191 		}
    192 	} else if (strcmp(argv[1], "set") == 0 && argc == 8) {
    193 		/* XXX bad commandline... */
    194 		/* audiocfg set <index> [p|r] <enc> <prec> <ch> <freq> */
    195 		if (*argv[2] < '0' || *argv[2] > '9')
    196 			usage(argv[0]);
    197 			/* NOTREACHED */
    198 		errno = 0;
    199 		i = strtoul(argv[2], NULL, 10);
    200 		if (errno)
    201 			usage(argv[0]);
    202 			/* NOTREACHED */
    203 		adev = audiodev_get(i);
    204 		if (adev == NULL) {
    205 			fprintf(stderr, "no such device\n");
    206 			return EXIT_FAILURE;
    207 		}
    208 
    209 		mode = 0;
    210 		for (j = 0; j < strlen(argv[3]); j++) {
    211 			if (argv[3][j] == 'p')
    212 				mode |= AUMODE_PLAY;
    213 			else if (argv[3][j] == 'r')
    214 				mode |= AUMODE_RECORD;
    215 			else
    216 				usage(argv[0]);
    217 		}
    218 		enc = argv[4];
    219 		prec = strtoul(argv[5], NULL, 10);
    220 		if (errno)
    221 			usage(argv[0]);
    222 		errno = 0;
    223 		ch = strtoul(argv[6], NULL, 10);
    224 		if (errno)
    225 			usage(argv[0]);
    226 			/* NOTREACHED */
    227 		errno = 0;
    228 		freq = strtoul(argv[7], NULL, 10);
    229 		if (errno)
    230 			usage(argv[0]);
    231 			/* NOTREACHED */
    232 
    233 		if (audiodev_set_param(adev, mode, enc, prec, ch, freq) == -1) {
    234 			perror("couldn't set parameter");
    235 			return EXIT_FAILURE;
    236 		}
    237 	} else if (strcmp(argv[1], "test") == 0 && argc == 3) {
    238 		if (*argv[2] < '0' || *argv[2] > '9')
    239 			usage(argv[0]);
    240 			/* NOTREACHED */
    241 		errno = 0;
    242 		i = strtoul(argv[2], NULL, 10);
    243 		if (errno)
    244 			usage(argv[0]);
    245 			/* NOTREACHED */
    246 		adev = audiodev_get(i);
    247 		if (adev == NULL) {
    248 			fprintf(stderr, "no such device\n");
    249 			return EXIT_FAILURE;
    250 		}
    251 		print_audiodev(adev, i);
    252 		for (i = 0; i < adev->info.play.channels; i++) {
    253 			printf("  testing channel %d...", i);
    254 			fflush(stdout);
    255 			if (audiodev_test(adev, 1 << i) == -1)
    256 				return EXIT_FAILURE;
    257 			printf(" done\n");
    258 		}
    259 	} else
    260 		usage(argv[0]);
    261 		/* NOTREACHED */
    262 
    263 	return EXIT_SUCCESS;
    264 }
    265