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

FreeBSD Manual Pages

  
 
  

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

NAME
     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,
     mixer_get_path,	MIX_ISDEV,    MIX_ISMUTE,    MIX_ISREC,    MIX_ISRECSRC,
     MIX_VOLNORM, MIX_VOLDENORM -- interface to OSS mixers

LIBRARY
     Mixer library (libmixer, -lmixer)

SYNOPSIS
     #include <mixer.h>

     struct mixer *
     mixer_open(const char *name);

     int
     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);

     int
     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));

     int
     mixer_add_ctl_s(mix_ctl_t *ctl);

     int
     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);

     int
     mixer_set_vol(struct mixer *m, mix_volume_t vol);

     int
     mixer_set_mute(struct mixer *m, int opt);

     int
     mixer_mod_recsrc(struct mixer *m, int opt);

     int
     mixer_get_dunit(void);

     int
     mixer_set_dunit(struct mixer *m, int unit);

     int
     mixer_get_mode(int unit);

     int
     mixer_get_nmixers(void);

     int
     mixer_get_path(char * buf, size_t size, int unit);

     int
     MIX_ISDEV(struct mixer *m, int devno);

     int
     MIX_ISMUTE(struct mixer *m, int devno);

     int
     MIX_ISREC(struct mixer *m, int devno);

     int
     MIX_ISRECSRC(struct mixer *m, int devno);

     float
     MIX_VOLNORM(int v);

     int
     MIX_VOLDENORM(float v);

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

   Mixer
     A mixer is described by the following structure:

     struct mixer {
	     TAILQ_HEAD(mix_devhead, 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 fields.

     ci 	OSS  audio  card information.  This structure is also defined in
		<sys/soundcard.h>.

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

     fd 	File  descriptor  returned  when  the	mixer	is   opened   in
		mixer_open().

     unit	Audio card unit.  Since each mixer device maps to a pcmX device,
		unit is always equal to the number of that pcmX device.  For ex-
		ample,	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 sup-
		ported 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
		again.

     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
		one.

   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_ctlhead, 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 vol-
		   umes  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 de-
		   vice.

     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 ex-
		 ample,  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  han-
     dle to the device, which is used as an argument in most other functions 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 using the
     mixer.

   Manipulating the mixer
     The mixer_get_dev() and mixer_get_dev_byname() functions select a mixer de-
     vice, either by its number or by its name respectively.  The  mixer  struc-
     ture  keeps a list of all the devices, but only one can be manipulated at a
     time.  Each time a new device is to be manipulated, one of  the  two  func-
     tions 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 vol-
     umes 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 un-
			   mute if muted).

     The mixer_mod_recsrc() function modifies a recording device.  The	selected
     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) controls.

     The  mixer_get_mode()  function returns the operating mode of the audio de-
     vice the mixer belongs to.  The following values can be OR'ed in case  more
     than one mode is supported:

	   MIX_MODE_MIXER  The audio device has a mixer.

	   MIX_MODE_PLAY   The audio device supports playback.

	   MIX_MODE_REC    The audio device supports recording.

     The  mixer_get_nmixers()  function  returns  the maximum mixer unit number.
     Although this might sound as incorrect behavior, given that one  would  ex-
     pect  "nmixers"  to  refer to the total number of active mixers, it is more
     intuitive for applications that want to loop through all mixer devices (see
     the "EXAMPLES" section).

     The mixer_get_path() function writes the path of the mixer device specified
     in the unit argument to the buffer specified in buf.  unit  can  be  either
     -1,  in  which  case  mixer_get_path()  will  fetch the path of the default
     mixer, or between 0 and the maximum mixer unit.

     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 number.
     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 device
     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 sepa-
     rate argument.

     The mixer_remove_ctl() functions removes a control from the device its  at-
     tached to.

     The mixer_get_ctl() function searches for a control in the device specified
     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.

RETURN VALUES
     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(),	   mixer_get_nmixers(),      and
     mixer_get_path() 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.

EXAMPLES
   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");

     (void)mixer_close(m);

   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))
		     continue;
	     if (mixer_set_mute(m, MIX_MUTE) < 0)
		     warn("cannot mute device: %s", dp->name);
     }

     (void)mixer_close(m);

   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))
		     printf("%s\t%.2f:%.2f\n",
			 dp->name, dp->vol.left, dp->vol.right);
     }

     (void)mixer_close(m);

   Loop through all mixer devices in the system
     struct mixer *m;
     char buf[NAME_MAX];
     int n;

     if ((n = mixer_get_nmixers()) < 0)
	     errx(1, "no mixers present in the system");
     for (i = 0; i < n; i++) {
	     (void)mixer_get_path(buf, sizeof(buf), i);
	     if ((m = mixer_open(buf)) == NULL)
		     continue;
	     ...
	     (void)mixer_close(m);
     }

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

AUTHORS
     Christos Margiolis <christos@FreeBSD.org>

FreeBSD ports 15.quarterly	 August 4, 2024 			MIXER(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=mixer&sektion=3&manpath=FreeBSD+15.1-RELEASE+and+Ports.quarterly>

home | help