190075Sobrien/*
2169689Skan * audio-pcm.c - Scope out the PCM audio stuff
390075Sobrien */
490075Sobrien#ifdef HAVE_CONFIG_H
5132718Skan# include <config.h>
690075Sobrien#endif
7132718Skan
890075Sobrien#if defined(HAVE_MACHINE_SOUNDCARD_H) || defined(HAVE_SYS_SOUNDCARD_H)
990075Sobrien
1090075Sobrien#include "audio.h"
1190075Sobrien#include "ntp_stdlib.h"
12132718Skan#include "ntp_syslog.h"
1390075Sobrien#ifdef HAVE_UNISTD_H
1490075Sobrien# include <unistd.h>
1590075Sobrien#endif
1690075Sobrien#include <stdio.h>
1790075Sobrien#include "ntp_string.h"
18132718Skan
19169689Skan#ifdef HAVE_SYS_IOCTL_H
20169689Skan#include <sys/ioctl.h>
2190075Sobrien#endif /* HAVE_SYS_IOCTL_H */
2290075Sobrien
2390075Sobrien#include <fcntl.h>
2490075Sobrien
25169689Skan#ifdef HAVE_MACHINE_SOUNDCARD_H
26169689Skan# include <machine/soundcard.h>
27169689Skan# define PCM_STYLE_SOUND
28169689Skan#else
29169689Skan# ifdef HAVE_SYS_SOUNDCARD_H
30169689Skan#  include <sys/soundcard.h>
31169689Skan#  define PCM_STYLE_SOUND
32169689Skan# endif
33169689Skan#endif
34169689Skan
35169689Skan/*
36169689Skan * Global variables
37169689Skan */
38169689Skanstatic int ctl_fd;		/* audio control file descriptor */
39169689Skan
40169689Skanconst char *m_names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES ;
41169689Skan
42169689Skanvoid
43169689Skand_fmt(
44169689Skan      unsigned int format
45169689Skan      )
46169689Skan{
47169689Skan
48169689Skan  if (format & AFMT_MU_LAW)	printf("MU_LAW ");
49169689Skan  if (format & AFMT_A_LAW)	printf("A_LAW ");
50169689Skan  if (format & AFMT_IMA_ADPCM)	printf("IMA_ADPCM ");
51169689Skan  if (format & AFMT_U8)		printf("U8 ");
52169689Skan  if (format & AFMT_S16_LE)	printf("S16_LE ");
53169689Skan  if (format & AFMT_S16_BE)	printf("S16_BE ");
54169689Skan  if (format & AFMT_S8)		printf("S8 ");
55169689Skan  if (format & AFMT_U16_LE)	printf("U16_LE ");
56169689Skan  if (format & AFMT_U16_BE)	printf("U16_BE ");
57169689Skan  if (format & AFMT_MPEG)	printf("MPEG ");
58169689Skan  if (format & AFMT_AC3)	printf("AC3 ");
59169689Skan  printf("\n");
60169689Skan}
61169689Skan
62169689Skanvoid
63169689Skand_mixer(
64169689Skan	unsigned int mixer
65169689Skan	)
66169689Skan{
67169689Skan  int i;
68169689Skan  int n = 0;
69169689Skan
70169689Skan  for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
71169689Skan    if ((1 << i) & mixer) {
72169689Skan      if (n)
73169689Skan	printf(", ");
74169689Skan      printf("%s", m_names[i]);
75169689Skan      n = 1;
76169689Skan    }
77169689Skan  printf("\n");
78169689Skan}
79169689Skan
80169689Skanint
81169689Skanmain( )
82169689Skan{
83169689Skan	int	unit = 0;	/* device unit (0-3) */
84169689Skan# define AI_DEV		"/dev/audio%d"
85169689Skan# define AC_DEV		"/dev/mixer%d"
86169689Skan	char ai_dev[30];
87169689Skan	char ac_dev[30];
88169689Skan	struct snd_size s_size;
89169689Skan	snd_chan_param s_c_p;
90169689Skan	snd_capabilities s_c;
91169689Skan	int fd;
92169689Skan	int rval;
9390075Sobrien	char *dname = ai_dev;		/* device name */
9490075Sobrien	char *actl = ac_dev;
95169689Skan	int devmask = 0, recmask = 0, recsrc = 0;
96169689Skan
97169689Skan	snprintf(ai_dev, sizeof(ai_dev), AI_DEV, unit);
98132718Skan	snprintf(ac_dev, sizeof(ac_dev), AC_DEV, unit);
99132718Skan
100169689Skan	/*
101169689Skan	 * Open audio device. Do not complain if not there.
102169689Skan	 */
103169689Skan	fd = open(dname, O_RDWR | O_NONBLOCK, 0777);
104169689Skan	if (fd < 0)
105169689Skan		return (fd);
106169689Skan
107169689Skan	/*
108169689Skan	 * Open audio control device.
10990075Sobrien	 */
110169689Skan	ctl_fd = open(actl, O_RDWR);
111169689Skan	if (ctl_fd < 0) {
112169689Skan		fprintf(stderr, "invalid control device <%s>\n", actl);
11390075Sobrien		close(fd);
114117395Skan		return(ctl_fd);
115117395Skan	}
11690075Sobrien
11790075Sobrien	printf("input:   <%s> %d\n", dname, fd);
11890075Sobrien	printf("control: <%s> %d\n", actl, ctl_fd);
11990075Sobrien
12090075Sobrien	if (ioctl(ctl_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
121	    printf("SOUND_MIXER_READ_DEVMASK: %s\n", strerror(errno));
122	if (ioctl(ctl_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
123	    printf("SOUND_MIXER_READ_RECMASK: %s\n", strerror(errno));
124	if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
125	    printf("SOUND_MIXER_READ_RECSRC: %s\n", strerror(errno));
126
127	printf("devmask: %#x recmask: %#x recsrc: %#x\n",
128		devmask, recmask, recsrc);
129	printf("Devmask: "); d_mixer(devmask);
130	printf("Recmask: "); d_mixer(recmask);
131	printf("RecSrc:  "); d_mixer(recsrc);
132
133	/*
134	 * Set audio device parameters.
135	 */
136	rval = fd;
137
138	if (ioctl(fd, AIOGSIZE, &s_size) == -1)
139	    printf("AIOGSIZE: %s\n", strerror(errno));
140	else
141	    printf("play_size %d, rec_size %d\n",
142		s_size.play_size, s_size.rec_size);
143
144	if (ioctl(fd, AIOGFMT, &s_c_p) == -1)
145	    printf("AIOGFMT: %s\n", strerror(errno));
146	else {
147	  printf("play_rate %lu, rec_rate %lu, play_format %#lx, rec_format %#lx\n",
148		 s_c_p.play_rate, s_c_p.rec_rate, s_c_p.play_format, s_c_p.rec_format);
149	  printf("Play format: "); d_fmt(s_c_p.play_format);
150	  printf("Rec format:  "); d_fmt(s_c_p.rec_format);
151	}
152
153}
154#endif /* HAVE_{MACHINE_SOUNDCARD,SYS_SOUNDCARD}_H */
155