Previous Next Table of Contents

4. Mixer

Mixer related structures and function is in include/mixer.h header file.

4.1 Variables and functions

Variables from snd_kmixer_t structure which must be filled:

Variables from snd_kmixer_t structure which should be filled:

Variables from struct snd_stru_mixer_hw structure which must be filled:

Variables from struct snd_stru_mixer_hw structure which should be filled:

Variables from snd_kmixer_channel_t structure which must be filled:

Variables from snd_kmixer_channel_t structure which should be filled:

Variables from struct snd_stru_mixer_channel_hw structure which must be filled:

Variables from struct snd_stru_mixer_channel_hw structure which should be filled:

Functions list:

4.2 Exaples


#define CS4231_MIXS (sizeof(snd_cs4231_mixs)/sizeof(struct snd_stru_mixer_channel_hw))
#define CS4231_PRIVATE( left, right, shift, mute ) ((left << 24)|(right << 16)|(shift<<8)|mute)

static struct snd_stru_mixer_channel_hw snd_cs4231_mixs[] = {
  {
    SND_MIXER_PRI_GAIN,         /* priority */
    SND_MIXER_PRI_PARENT,       /* parent priority */
    SND_MIXER_ID_GAIN,          /* device name */
    SND_MIXER_OSS_IMIX,         /* OSS device # */
    0, 1, 0, 0, 1,              /* mute/stereo/record/digital/input */
    0, 15,                      /* min, max value */
    0, 2250, 150,               /* min, max, step - dB */
    CS4231_PRIVATE( CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0x00 ) | 0x2000,
    NULL,                       /* compute dB -> linear */
    NULL,                       /* compute linear -> dB */
    NULL,                       /* record source */
    NULL,                       /* set mute */
    snd_cs4231_volume_level,    /* set volume level */
  },
  ....
};

snd_kmixer_t *snd_cs4231_new_mixer( snd_pcm_t *pcm )
{
  int idx;
  cs4231_t *codec;
  snd_kmixer_t *mixer;
  snd_kmixer_channel_t *channel;

  if ( !pcm || !pcm -> card ) return NULL;
  codec = (cs4231_t *)pcm -> private_data;
  if ( !codec ) return NULL;
  mixer = snd_mixer_new( pcm -> card, pcm -> id );
  if ( !mixer ) return NULL;
  strcpy( mixer -> name, pcm -> name );
  for ( idx = 0; idx < CS4231_MIXS; idx++ ) {
    channel = snd_mixer_new_channel( mixer, &snd_cs4231_mixs[ idx ] );
    if ( !channel ) {
      snd_mixer_free( mixer );
      return NULL;
    }
  }
  mixer -> hw.caps = SND_MIXER_INFO_CAP_EXCL_RECORD;
  mixer -> private_data = codec;
  codec -> mixer = mixer;
  return mixer;
}

Do you need modify some default mixer channel assignment?


  snd_kmixer_channel_t *channel;

  /* ok. InterWave have MIC different (stereo) */
  channel = snd_mixer_find_channel( mixer, SND_MIXER_PRI_MIC );
  channel -> hw.stereo = 1;
  channel -> hw.max = 31;
  channel -> hw.private_value = CS4231_PRIVATE( CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0x80 );

  /* reassign AUXA to SYNTHESIZER */
  channel = snd_mixer_find_channel( mixer, SND_MIXER_PRI_AUXA );
  channel -> hw.priority = SND_MIXER_PRI_SYNTHESIZER;
  channel -> hw.ossdev = SND_MIXER_OSS_SYNTH;
  strcpy( channel -> hw.name, SND_MIXER_ID_SYNTHESIZER );
  snd_mixer_reorder_channel( mixer, channel );

Do you need add some mixer channel to generic mixer?


  static struct snd_stru_mixer_channel_hw master = {
    SND_MIXER_PRI_MASTER,               /* priority */
    SND_MIXER_PRI_PARENT,               /* parent priority */
    SND_MIXER_ID_MASTER,                /* device name */
    SND_MIXER_OSS_VOLUME,               /* OSS device # */
    1, 1, 1, 0, 0,                      /* mute/stereo/record/digital */
    0, 31,                              /* max. value */
    -3450, 1200, 150,                   /* min, max, step - dB */
    CS4231_PRIVATE( CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0x80
    NULL,                               /* compute dB -> linear */
    NULL,                               /* compute linear -> dB */
    NULL,                               /* record source */
    NULL,                               /* set mute */
    NULL,                               /* set volume level */
  };
  int idx;

  /* make master as parent */
  for ( idx = 0; idx < mixer -> channels_count; idx++ ) {
    channel = mixer -> channels[ idx ];
    if ( !channel -> hw.input )
      channel -> hw.parent_priority = SND_MIXER_PRI_MASTER;
  }
  /* add master volume control */
  master.set_record_source = channel -> hw.set_record_source;
  master.set_mute = channel -> hw.set_mute;
  master.set_volume_level = channel -> hw.set_volume_level;
  channel = snd_mixer_new_channel( mixer, &master );
  if ( !channel ) return -ENOMEM;

Mixer device registering:


  snd_card_t *card;
  snd_pcm_t *pcm.
  snd_kmixer_t *mixer;

  ...
  mixer = snd_es1688_new_mixer( pcm );
  if ( !mixer ) {
    snd_pcm_free( pcm );
    snd_card_free( card );
    return -NXIO;
  }
  ...
  if ( snd_mixer_register( mixer, 0 ) ) {
    ... unregister already registered devices ...
    snd_mixer_free( mixer );
    snd_pcm_free( pcm );
    snd_card_free( card );
    return -ENXIO;
  }
  ...
  snd_mixer_unregister( mixer );


Previous Next Table of Contents