1/*	$NetBSD: audio-pcm.c,v 1.5 2020/05/25 20:47:37 christos Exp $	*/
2
3/*
4 * audio-pcm.c - Scope out the PCM audio stuff
5 */
6#ifdef HAVE_CONFIG_H
7# include <config.h>
8#endif
9
10#if defined(HAVE_MACHINE_SOUNDCARD_H) || defined(HAVE_SYS_SOUNDCARD_H)
11
12#include "audio.h"
13#include "ntp_stdlib.h"
14#include "ntp_syslog.h"
15#ifdef HAVE_UNISTD_H
16# include <unistd.h>
17#endif
18#include <stdio.h>
19#include "ntp_string.h"
20
21#ifdef HAVE_SYS_IOCTL_H
22#include <sys/ioctl.h>
23#endif /* HAVE_SYS_IOCTL_H */
24
25#include <fcntl.h>
26
27#ifdef HAVE_MACHINE_SOUNDCARD_H
28# include <machine/soundcard.h>
29# define PCM_STYLE_SOUND
30#else
31# ifdef HAVE_SYS_SOUNDCARD_H
32#  include <sys/soundcard.h>
33#  define PCM_STYLE_SOUND
34# endif
35#endif
36
37/*
38 * Global variables
39 */
40static int ctl_fd;		/* audio control file descriptor */
41
42const char *m_names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES ;
43
44void
45d_fmt(
46      unsigned int format
47      )
48{
49
50  if (format & AFMT_MU_LAW)	printf("MU_LAW ");
51  if (format & AFMT_A_LAW)	printf("A_LAW ");
52  if (format & AFMT_IMA_ADPCM)	printf("IMA_ADPCM ");
53  if (format & AFMT_U8)		printf("U8 ");
54  if (format & AFMT_S16_LE)	printf("S16_LE ");
55  if (format & AFMT_S16_BE)	printf("S16_BE ");
56  if (format & AFMT_S8)		printf("S8 ");
57  if (format & AFMT_U16_LE)	printf("U16_LE ");
58  if (format & AFMT_U16_BE)	printf("U16_BE ");
59  if (format & AFMT_MPEG)	printf("MPEG ");
60  if (format & AFMT_AC3)	printf("AC3 ");
61  printf("\n");
62}
63
64void
65d_mixer(
66	unsigned int mixer
67	)
68{
69  int i;
70  int n = 0;
71
72  for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
73    if ((1 << i) & mixer) {
74      if (n)
75	printf(", ");
76      printf("%s", m_names[i]);
77      n = 1;
78    }
79  printf("\n");
80}
81
82int
83main( )
84{
85	int	unit = 0;	/* device unit (0-3) */
86# define AI_DEV		"/dev/audio%d"
87# define AC_DEV		"/dev/mixer%d"
88	char ai_dev[30];
89	char ac_dev[30];
90	struct snd_size s_size;
91	snd_chan_param s_c_p;
92	snd_capabilities s_c;
93	int fd;
94	int rval;
95	char *dname = ai_dev;		/* device name */
96	char *actl = ac_dev;
97	int devmask = 0, recmask = 0, recsrc = 0;
98
99	snprintf(ai_dev, sizeof(ai_dev), AI_DEV, unit);
100	snprintf(ac_dev, sizeof(ac_dev), AC_DEV, unit);
101
102	/*
103	 * Open audio device. Do not complain if not there.
104	 */
105	fd = open(dname, O_RDWR | O_NONBLOCK, 0777);
106	if (fd < 0)
107		return (fd);
108
109	/*
110	 * Open audio control device.
111	 */
112	ctl_fd = open(actl, O_RDWR);
113	if (ctl_fd < 0) {
114		fprintf(stderr, "invalid control device <%s>\n", actl);
115		close(fd);
116		return(ctl_fd);
117	}
118
119	printf("input:   <%s> %d\n", dname, fd);
120	printf("control: <%s> %d\n", actl, ctl_fd);
121
122	if (ioctl(ctl_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
123	    printf("SOUND_MIXER_READ_DEVMASK: %s\n", strerror(errno));
124	if (ioctl(ctl_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
125	    printf("SOUND_MIXER_READ_RECMASK: %s\n", strerror(errno));
126	if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
127	    printf("SOUND_MIXER_READ_RECSRC: %s\n", strerror(errno));
128
129	printf("devmask: %#x recmask: %#x recsrc: %#x\n",
130		devmask, recmask, recsrc);
131	printf("Devmask: "); d_mixer(devmask);
132	printf("Recmask: "); d_mixer(recmask);
133	printf("RecSrc:  "); d_mixer(recsrc);
134
135	/*
136	 * Set audio device parameters.
137	 */
138	rval = fd;
139
140	if (ioctl(fd, AIOGSIZE, &s_size) == -1)
141	    printf("AIOGSIZE: %s\n", strerror(errno));
142	else
143	    printf("play_size %d, rec_size %d\n",
144		s_size.play_size, s_size.rec_size);
145
146	if (ioctl(fd, AIOGFMT, &s_c_p) == -1)
147	    printf("AIOGFMT: %s\n", strerror(errno));
148	else {
149	  printf("play_rate %lu, rec_rate %lu, play_format %#lx, rec_format %#lx\n",
150		 s_c_p.play_rate, s_c_p.rec_rate, s_c_p.play_format, s_c_p.rec_format);
151	  printf("Play format: "); d_fmt(s_c_p.play_format);
152	  printf("Rec format:  "); d_fmt(s_c_p.rec_format);
153	}
154
155}
156#endif /* HAVE_{MACHINE_SOUNDCARD,SYS_SOUNDCARD}_H */
157