Previous Next Table of Contents

4. Mixer Interface

Mixer Interface allows to application change volume level of soundcards input/output channel in both linear (0-100) range and in decibels. It also supports features like hardware mute, input sound source etc.

4.1 Low-Level Layer

Mixer devices aren't opened exclusively. This allows to open device multiple times with one or more processes for the same mixer device.

int snd_mixer_open( void **handle, int card, int device )

Function creates new handle and opens connection to kernel sound mixer interface to soundcard number card (0-N) and mixer device number device. Function also checks if protocol is compatible to prevent use old programs with new kernel API. Function returns zero if success otherwise it returns negative error code.

int snd_mixer_close( void *handle )

Function frees all resources allocated with mixer handle and closes connection to kernel sound mixer interface. Function returns zero if success otherwise it returns negative error code.

int snd_mixer_file_descriptor( void *handle )

Function returns file descriptor of connection to kernel sound mixer interface. This function should be used only with very special cases. Function returns negative error code if some error was occured.

File descriptor should be used for select synchronous multiplexer function for read direction. Application should call snd_mixer_read function if some data is waiting for read. This call is very recomended and leaves place for this function to handle some new kernel API specification.

int snd_mixer_channels( void *handle )

Function returns positive count of mixer channels for appropriate mixer device, otherwise return value is negative and means error code. Zero value should never be returned.

int snd_mixer_info( void *handle, snd_mixer_info_t *info )

Function returns filled *info structure. Function returns zero if success otherwise it returns negative error code.


  #define SND_MIXER_INFO_CAP_EXCL_RECORD  0x00000001

  struct snd_mixer_info {
    unsigned int type;            /* type of soundcard - SND_CARD_TYPE_XXXX */
    unsigned int channels;        /* count of mixer devices */
    unsigned int caps;            /* some flags about this device (SND_MIXER_INFO_CAP_XXXX) */
    unsigned char id[32];         /* ID of this mixer */
    unsigned char name[80];       /* name of this device */
    char reserved[ 32 ];          /* reserved for future use */
  };
  

int snd_mixer_channel( void *handle, const char *channel_id )

Function returns channel number (index) associated with channel_id (channel name) otherwise function returns negative error code.


  #define SND_MIXER_ID_MASTER             "Master"
  #define SND_MIXER_ID_BASS               "Bass"
  #define SND_MIXER_ID_TREBLE             "Treble"
  #define SND_MIXER_ID_SYNTHESIZER        "Synth"
  #define SND_MIXER_ID_SYNTHESIZER1       "Synth 1"
  #define SND_MIXER_ID_FM                 "FM"
  #define SND_MIXER_ID_EFFECT             "Effect"
  #define SND_MIXER_ID_PCM                "PCM"
  #define SND_MIXER_ID_PCM1               "PCM 1"
  #define SND_MIXER_ID_LINE               "Line-In"
  #define SND_MIXER_ID_MIC                "MIC"
  #define SND_MIXER_ID_CD                 "CD"
  #define SND_MIXER_ID_GAIN               "Record-Gain"
  #define SND_MIXER_ID_IGAIN              "In-Gain"
  #define SND_MIXER_ID_OGAIN              "Out-Gain"
  #define SND_MIXER_ID_LOOPBACK           "Loopback"
  #define SND_MIXER_ID_SPEAKER            "PC Speaker"
  #define SND_MIXER_ID_AUXA               "Aux A"
  #define SND_MIXER_ID_AUXB               "Aux B"
  #define SND_MIXER_ID_AUXC               "Aux C"
  

int snd_mixer_channel_info( void *handle, int channel, snd_mixer_channel_info_t *info )

Function returns filled *info structure. Argument channel specifies channel (0 to N) for which is info requested. Function returns zero if success otherwise it returns negative error code.


  #define SND_MIXER_CINFO_CAP_RECORD      0x00000001
  #define SND_MIXER_CINFO_CAP_STEREO      0x00000002
  #define SND_MIXER_CINFO_CAP_MUTE        0x00000004
  #define SND_MIXER_CINFO_CAP_HWMUTE      0x00000008      /* channel supports hardware mute */
  #define SND_MIXER_CINFO_CAP_DIGITAL     0x00000010      /* channel does digital (not analog) mixing */

  struct snd_mixer_channel_info {
    unsigned int channel;         /* channel # (filled by application) */
    unsigned int parent;          /* parent channel # or SND_MIXER_PARENT */
    unsigned char name[12];       /* name of this device */
    unsigned int caps;            /* some flags about this device (SND_MIXER_CINFO_XXXX) */
    int min_dB;                   /* minimum decibel value (*100) */
    int max_dB;                   /* maximum decibel value (*100) */
    int step_dB;                  /* step decibel value (*100) */
    unsigned char reserved[16];
  };
  

int snd_mixer_channel_read( void *handle, int channel, snd_mixer_channel_t *data )

Function returns filled *data structure. Argument channel specifies channel (0 to N) for which is data requested. Function returns zero if success otherwise it returns negative error code.


  #define SND_MIXER_FLG_RECORD            0x00000001      /* channel record source flag */
  #define SND_MIXER_FLG_MUTE_LEFT         0x00010000
  #define SND_MIXER_FLG_MUTE_RIGHT        0x00020000
  #define SND_MIXER_FLG_MUTE              0x00030000
  #define SND_MIXER_FLG_DECIBEL           0x40000000
  #define SND_MIXER_FLG_FORCE             0x80000000

  struct snd_mixer_channel {
    unsigned int channel;         /* channel # (filled by application) */
    unsigned int flags;           /* some flags to read/write (SND_MIXER_FLG_XXXX) */
    int left;                     /* 0 - 100 */
    int right;                    /* 0 - 100 */
    int left_dB;                  /* dB * 10 */
    int right_dB;                 /* dB * 10 */
    unsigned char reserved[16];
  };
  

SND_MIXER_FLG_RECORD

Record source flag.

SND_MIXER_FLG_DECIBEL

If this bit is set, driver set volume from dB variables left_dB and right_dB.

SND_MIXER_FLG_FORCE

Force set - this bit shouldn't be used from user space. Reserved for kernel.

int snd_mixer_channel_write( void *handle, int channel, snd_mixer_channel_t *data )

Function writes *data structure to kernel. Argument channel specifies channel (0 to N) for which is data requested. Function returns zero if success otherwise it returns negative error code. This functions is opposite to snd_mixer_channel_read.

int snd_mixer_special_read( void *handle, snd_mixer_special_t *special )

Not documented...

int snd_mixer_special_write( void *handle, snd_mixer_special_t *special )

Not documented...

int snd_mixer_read( void *handle, snd_mixer_callbacks_t *callbacks )

This function reads and parses data from driver. Parsed actions are returned back to the application over callbacks structure. Application should not parse data from the driver in standard cases. This function returns immediately after read all data from driver. Function doesn't block process.


  typedef struct snd_mixer_callbacks {
    void *private_data;           /* should be used by application */
    void (*channel_was_changed)( void *private_data, int channel );
    void *reserved[15];           /* reserved for future use - must be NULL!!! */
  } snd_mixer_callbacks_t;
  

4.2 Examples

Bellow example shows how can be set detected all PCM devices for first soundcard (#0) and first device (#0) for this soundcard in the system and sets master volume (if present) to 50.


int card = 0, device = 0, err;
void *handle;
snd_mixer_info_t info;
snd_mixer_channel_t channel;

if ( (err = snd_mixer_open( &handle, card, device )) < 0 ) {
  fprintf( stderr, "open failed: %s\n", snd_strerror( err ) );
  return;
}
if ( (err = snd_mixer_info( handle, &info )) < 0 ) {
  fprintf( stderr, "info failed: %s\n", snd_strerror( err ) );
  snd_mixer_close( handle );
  return;
}
printf( "Installed MIXER channels for card #i and device %i: %i\n",
                                        card + 1, device, info.channels );
master = snd_mixer_channel( handle, SND_MIXER_ID_MASTER );
if ( master >= 0 ) {
  if ( (err = snd_mixer_read( handle, master, &channel )) < 0 ) {
    fprintf( stderr, "master read failed: %s\n", snd_strerror( err ) );
    snd_mixer_close( handle );
    return;
  }
  channel -> left = channel -> right = 50;
  if ( (err = snd_mixer_write( handle, master, &channel )) < 0 ) {
    fprintf( stderr, "master write failed: %s\n", snd_strerror( err ) );
    snd_mixer_close( handle );
    return;
  }
}
snd_mixer_close( handle );


Previous Next Table of Contents