Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
MIXER(3)	       FreeBSD Library Functions Manual		      MIXER(3)

     mixer_open, mixer_close, mixer_get_dev, mixer_get_dev_byname,
     mixer_add_ctl, mixer_add_ctl_s, mixer_remove_ctl, mixer_get_ctl,
     mixer_get_ctl_byname, mixer_set_vol, mixer_set_mute, mixer_mod_recsrc,
     mixer_get_dunit, mixer_set_dunit, mixer_get_mode, mixer_get_nmixers,
     MIX_VOLDENORM -- interface	to OSS mixers

     Mixer library (libmixer, -lmixer)

     #include <mixer.h>

     struct mixer *
     mixer_open(const char *name);

     mixer_close(struct	mixer *m);

     struct mix_dev *
     mixer_get_dev(struct mixer	*m, int	devno);

     struct mix_dev *
     mixer_get_dev_byname(struct mixer *m, name);

     mixer_add_ctl(struct mix_dev *parent, int id, const char *name,
	 int (*mod)(struct mix_dev *d, void *p),
	 int (*print)(struct mix_dev *d, void *p));

     mixer_add_ctl_s(mix_ctl_t *ctl);

     mixer_remove_ctl(mix_ctl_t	*ctl);

     mix_ctl_t *
     mixer_get_ctl(struct mix_dev *d, int id);

     mix_ctl_t *
     mixer_get_ctl_byname(struct mix_dev *d, const char	*name);

     mixer_set_vol(struct mixer	*m, mix_volume_t vol);

     mixer_set_mute(struct mixer *m, int opt);

     mixer_mod_recsrc(struct mixer *m, int opt);


     mixer_set_dunit(struct mixer *m, int unit);

     mixer_get_mode(int	unit);


     MIX_ISDEV(struct mixer *m,	int devno);

     MIX_ISMUTE(struct mixer *m, int devno);

     MIX_ISREC(struct mixer *m,	int devno);

     MIX_ISRECSRC(struct mixer *m, int devno);

     MIX_VOLNORM(int v);

     MIX_VOLDENORM(float v);

     The mixer library allows userspace	programs to access and manipulate OSS
     sound mixers in a simple way.

     A mixer is	described by the following structure:

     struct mixer {
	     TAILQ_HEAD(, mix_dev) devs;	     /*	device list */
	     struct mix_dev *dev;		     /*	selected device	*/
	     oss_mixerinfo mi;			     /*	mixer info */
	     oss_card_info ci;			     /*	audio card info	*/
	     char name[NAME_MAX];		     /*	mixer name (e.g	/dev/mixer0) */
	     int fd;				     /*	file descriptor	*/
	     int unit;				     /*	audio card unit	*/
	     int ndev;				     /*	number of devices */
	     int devmask;			     /*	supported devices */
     #define MIX_MUTE		     0x01
     #define MIX_UNMUTE		     0x02
     #define MIX_TOGGLEMUTE	     0x04
	     int mutemask;			     /*	muted devices */
	     int recmask;			     /*	recording devices */
     #define MIX_ADDRECSRC	     0x01
     #define MIX_REMOVERECSRC	     0x02
     #define MIX_SETRECSRC	     0x04
     #define MIX_TOGGLERECSRC	     0x08
	     int recsrc;			     /*	recording sources */
     #define MIX_MODE_MIXER	     0x01
     #define MIX_MODE_PLAY	     0x02
     #define MIX_MODE_REC	     0x04
	     int mode;				     /*	dev.pcm.X.mode sysctl */
	     int f_default;			     /*	default	mixer flag */

     The fields	are follows:

     devs	A tail queue structure containing all supported	mixer devices.

     dev	A pointer to the currently selected device.  The device	is one
		of the elements	in devs.

     mi		OSS information	about the mixer.  Look at the definition of
		the oss_mixerinfo structure in <sys/soundcard.h> to see	its

     ci		OSS audio card information.  This structure is also defined in

     name	Path to	the mixer (e.g /dev/mixer0).

     fd		File descriptor	returned when the mixer	is opened in

     unit	Audio card unit.  Since	each mixer device maps to a pcmX de-
		vice, unit is always equal to the number of that pcmX device.
		For example, if	the audio device's number is 0 (i.e pcm0),
		then unit is 0 as well.	 This number is	useful when checking
		if the mixer's audio card is the default one.

     ndev	Number of devices in devs.

     devmask	Bit mask containing all	supported devices for the mixer.  For
		example, if device 10 is supported, then the 10th bit in the
		mask will be set.  By default, mixer_open() stores only	the
		supported devices in devs, so it is very unlikely this mask
		will be	needed.

     mutemask	Bit mask containing all	muted devices.	The logic is the same
		as with	devmask.

     recmask	Bit mask containing all	recording devices.  Again, same	logic
		as with	the other masks.

     recsrc	Bit mask containing all	recording sources.  Yes, same logic

     mode	Bit mask containing the	supported modes	for this audio device.
		It holds the value of the dev.pcm.X.mode sysctl.

     f_default	Flag which tells whether the mixer's audio card	is the default

   Mixer device
     Each mixer	device stored in a mixer is described as follows:

     struct mix_dev {
	     struct mixer *parent_mixer;	     /*	parent mixer */
	     char name[NAME_MAX];		     /*	device name (e.g "vol")	*/
	     int devno;				     /*	device number */
	     struct mix_volume {
     #define MIX_VOLMIN		     0.0f
     #define MIX_VOLMAX		     1.0f
     #define MIX_VOLNORM(v)	     ((v) / 100.0f)
     #define MIX_VOLDENORM(v)	     ((int)((v)	* 100.0f + 0.5f))
		     float left;		     /*	left volume */
		     float right;		     /*	right volume */
	     } vol;
	     int nctl;				     /*	number of controls */
	     TAILQ_HEAD(, mix_ctl) ctls;	     /*	control	list */
	     TAILQ_ENTRY(mix_dev) devs;

     The fields	are follows:

     parent_mixer  Pointer to the mixer	the device is attached to.

     name	   Device name given by	the OSS	API.  Devices can have one of
		   the following names:

		   vol,	bass, treble, synth, pcm, speaker, line, mic, cd, mix,
		   pcm2, rec, igain, ogain, line1, line2, line3, dig1, dig2,
		   dig3, phin, phout, video, radio, and	monitor.

     devno	   Device's index in the SOUND_MIXER_NRDEVICES macro defined
		   in <sys/soundcard.h>.  This number is used to check against
		   the masks defined in	the mixer structure.

     left right	   Left	and right-ear volumes.	Although the OSS API stores
		   volumes in integers from 0-100, we normalize	them to	32-bit
		   floating point numbers.  However, the volumes can be	denor-
		   malized using the MIX_VOLDENORM macro if needed.

     nctl	   Number of user-defined mixer	controls associated with the

     ctls	   A tail queue	containing user-defined	mixer controls.

   User-defined	mixer controls
     Each mixer	device can have	user-defined controls.	The control structure
     is	defined	as follows:

     struct mix_ctl {
	     struct mix_dev *parent_dev;	     /*	parent device */
	     int id;				     /*	control	id */
	     char name[NAME_MAX];		     /*	control	name */
	     int (*mod)(struct mix_dev *, void *);   /*	modify control values */
	     int (*print)(struct mix_dev *, void *); /*	print control */
	     TAILQ_ENTRY(mix_ctl) ctls;

     The fields	are follows:

     parent_dev	 Pointer to the	device the control is attached to.

     id		 Control ID assigned by	the caller.  Even though the library
		 will report it, care has to be	taken to not give a control
		 the same ID in	case the caller	has to choose controls using
		 their ID.

     name	 Control name.	As with	id, the	caller has to make sure	the
		 same name is not used more than once.

     mod	 Function pointer to a control modification function.  As in
		 mixer(8), each	mixer control's	values can be modified.	 For
		 example, if we	have a volume control, the mod function	will
		 be responsible	for handling volume changes.

     print	 Function pointer to a control print function.

   Opening and closing the mixer
     The application must first	call the mixer_open() function to obtain a
     handle to the device, which is used as an argument	in most	other func-
     tions and macros.	The parameter name specifies the path to the mixer.
     OSS mixers	are stored under /dev/mixerN where N is	the number of the
     mixer device.  Each device	maps to	an actual pcm audio card, so
     /dev/mixer0 is the	mixer for pcm0,	and so on.  If name is NULL or
     /dev/mixer, mixer_open() opens the	default	mixer (hw.snd.default_unit).

     The mixer_close() function	frees resources	and closes the mixer device.
     It	is a good practice to always call it when the application is done us-
     ing the mixer.

   Manipulating	the mixer
     The mixer_get_dev() and mixer_get_dev_byname() functions select a mixer
     device, either by its number or by	its name respectively.	The mixer
     structure keeps a list of all the devices,	but only one can be manipu-
     lated at a	time.  Each time a new device is to be manipulated, one	of the
     two functions has to be called.

     The mixer_set_vol() function changes the volume of	the selected mixer de-
     vice.  The	vol parameter is a structure that stores the left and right
     volumes of	a given	device.	 The allowed volume values are between
     MIX_VOLMIN	(0.0) and MIX_VOLMAX (1.0).

     The mixer_set_mute() function modifies the	mute of	a selected device.
     The opt parameter has to be one of	the following options:

	   MIX_MUTE	   Mute	the device.

	   MIX_UNMUTE	   Unmute the device.

	   MIX_TOGGLEMUTE  Toggle the device's mute (e.g mute if unmuted and
			   unmute if muted).

     The mixer_mod_recsrc() function modifies a	recording device.  The se-
     lected device has to be a recording device, otherwise the function	will
     fail.  The	opt parameter has to be	one of the following options:

	   MIX_ADDRECSRC     Add device	to the recording sources.

	   MIX_REMOVERECSRC  Remove device from	the recording sources.

	   MIX_SETRECSRC     Set device	as the only recording source.

	   MIX_TOGGLERECSRC  Toggle device from	the recording sources.

     The mixer_get_dunit() and mixer_set_dunit() functions get and set the de-
     fault audio card in the system.  Although this is not really a mixer fea-
     ture, it is useful	to have	instead	of having to use the sysctl(3) con-

     The mixer_get_mode() function returns the playback/recording mode of the
     audio device the mixer belongs to.	 The available values are the follow-

	   MIX_STATUS_NONE		     Neither playback nor recording.

	   MIX_STATUS_PLAY		     Playback.

	   MIX_STATUS_REC		     Recording.

	   MIX_STATUS_PLAY | MIX_STATUS_REC  Playback and recording.

     The mixer_get_nmixers() function returns the total	number of mixer	de-
     vices in the system.

     The MIX_ISDEV() macro checks if a device is actually a valid device for a
     given mixer.  It is very unlikely that this macro will ever be needed
     since the library stores only valid devices by default.

     The MIX_ISMUTE() macro checks if a	device is muted.

     The MIX_ISREC() macro checks if a device is a recording device.

     The MIX_ISRECSRC()	macro checks if	a device is a recording	source.

     The MIX_VOLNORM() macro normalizes	a value	to 32-bit floating point num-
     ber.  It is used to normalize the volumes read from the OSS API.

     The MIX_VOLDENORM() macro denormalizes the	left and right volumes stores
     in	the mix_dev structure.

   Defining and	using mixer controls
     The mix_add_ctl() function	creates	a control and attaches it to the de-
     vice specified in the parent argument.

     The mix_add_ctl_s() function does the same	thing as with mix_add_ctl()
     but the caller passes a mix_ctl_t * structure instead of each field as a
     separate argument.

     The mixer_remove_ctl() functions removes a	control	from the device	its
     attached to.

     The mixer_get_ctl() function searches for a control in the	device speci-
     fied in the d argument and	returns	a pointer to it.  The search is	done
     using the control's ID.

     The mixer_get_ctl_byname()	function is the	same as	with mixer_get_ctl()
     but the search is done using the control's	name.

     The mixer_open() function returns the newly created handle	on success and
     NULL on failure.

     The mixer_close(),	mixer_set_vol(), mixer_set_mute(), mixer_mod_recsrc(),
     mixer_get_dunut(),	mixer_set_dunit() and mixer_get_nmixers() functions
     return 0 or positive values on success and	-1 on failure.

     The mixer_get_dev() and mixer_get_dev_byname() functions return the se-
     lected device on success and NULL on failure.

     All functions set the value of errno on failure.

   Change the volume of	a device
     struct mixer *m;
     mix_volume_t vol;
     char *mix_name, *dev_name;

     mix_name =	...;
     if	((m = mixer_open(mix_name)) == NULL)
	     err(1, "mixer_open: %s", mix_name);

     dev_name =	...;
     if	((m->dev = mixer_get_dev_byname(m, dev_name)) <	0)
	     err(1, "unknown device: %s", dev_name);

     vol.left =	...;
     vol.right = ....;
     if	(mixer_set_vol(m, vol) < 0)
	     warn("cannot change volume");


   Mute	all unmuted devices
     struct mixer *m;
     struct mix_dev *dp;

     if	((m = mixer_open(NULL))	== NULL)     /*	Open the default mixer.	*/
	     err(1, "mixer_open");
     TAILQ_FOREACH(dp, &m->devs, devs) {
	     m->dev = dp;		     /*	Select device. */
	     if	(M_ISMUTE(m, dp->devno))
	     if	(mixer_set_mute(m, MIX_MUTE) < 0)
		     warn("cannot mute device: %s", dp->name);


   Print all recording sources'	names and volumes
     struct mixer *m;
     struct mix_dev *dp;

     char *mix_name, *dev_name;

     mix_name =	...;
     if	((m = mixer_open(mix_name)) == NULL)
	     err(1, "mixer_open: %s", mix_name);

     TAILQ_FOREACH(dp, &m->devs, devs) {
	     if	(M_ISRECSRC(m, dp->devno))
			 dp->name, dp->vol.left, dp->vol.right);


     queue(3), sysctl(3), sound(4), mixer(8) and errno(2)

     Christos Margiolis	<>

FreeBSD	13.0			March 19, 2022			  FreeBSD 13.0


Want to link to this manual page? Use this URL:

home | help