Beispiel #1
0
void
gst_alsa_mixer_set_record (GstAlsaMixer * mixer,
    GstMixerTrack * track, gboolean record)
{
  GstAlsaMixerTrack *alsa_track = GST_ALSA_MIXER_TRACK (track);

  g_return_if_fail (mixer->handle != NULL);

  g_static_rec_mutex_lock (mixer->rec_mutex);

  gst_alsa_mixer_track_update (alsa_track);

  if (!!(record) == !!(track->flags & GST_MIXER_TRACK_RECORD)) {
    g_static_rec_mutex_unlock (mixer->rec_mutex);
    return;
  }

  if (record) {
    track->flags |= GST_MIXER_TRACK_RECORD;
  } else {
    track->flags &= ~GST_MIXER_TRACK_RECORD;
  }

  if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CSWITCH) {
    snd_mixer_selem_set_capture_switch_all (alsa_track->element,
        record ? 1 : 0);

    /* update all tracks in same exlusive cswitch group */
    if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CSWITCH_EXCL) {
      GList *item;

      for (item = mixer->tracklist; item != NULL; item = item->next) {

        if (GST_IS_ALSA_MIXER_TRACK (item->data)) {
          GstAlsaMixerTrack *item_alsa_track =
              GST_ALSA_MIXER_TRACK (item->data);

          if (item_alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CSWITCH_EXCL &&
              item_alsa_track->capture_group == alsa_track->capture_group) {
            gst_alsa_mixer_track_update (item_alsa_track);
          }
        }
      }
    }
  } else {
    gint i;

    for (i = 0; i < track->num_channels; i++) {
      long vol = record ? alsa_track->volumes[i] : track->min_volume;

      snd_mixer_selem_set_capture_volume (alsa_track->element, i, vol);
    }
  }
  g_static_rec_mutex_unlock (mixer->rec_mutex);
}
Beispiel #2
0
void
gst_alsa_mixer_set_volume (GstAlsaMixer * mixer, GstMixerTrack * track,
    gint * volumes)
{
  GstAlsaMixerTrack *alsa_track = GST_ALSA_MIXER_TRACK (track);
  gint i;

  g_return_if_fail (mixer->handle != NULL);

  g_static_rec_mutex_lock (mixer->rec_mutex);

  gst_alsa_mixer_track_update (alsa_track);

  if (track->flags & GST_MIXER_TRACK_OUTPUT) {

    /* Is emulated mute flag activated? */
    if (track->flags & GST_MIXER_TRACK_MUTE &&
        !(alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_PSWITCH)) {
      for (i = 0; i < track->num_channels; i++)
        alsa_track->volumes[i] = volumes[i];
    } else {
      if (check_if_volumes_are_the_same (track->num_channels, volumes)) {
        snd_mixer_selem_set_playback_volume_all (alsa_track->element,
            volumes[0]);
        for (i = 0; i < track->num_channels; i++)
          alsa_track->volumes[i] = volumes[0];
      } else {
        for (i = 0; i < track->num_channels; i++) {
          alsa_track->volumes[i] = volumes[i];
          snd_mixer_selem_set_playback_volume (alsa_track->element, i,
              volumes[i]);
        }
      }
    }

  } else if (track->flags & GST_MIXER_TRACK_INPUT) {

    /* Is emulated record flag activated? */
    if (track->flags & GST_MIXER_TRACK_RECORD ||
        alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CSWITCH) {
      if (check_if_volumes_are_the_same (track->num_channels, volumes)) {
        snd_mixer_selem_set_capture_volume_all (alsa_track->element,
            volumes[0]);
        for (i = 0; i < track->num_channels; i++)
          alsa_track->volumes[i] = volumes[0];
      } else {
        for (i = 0; i < track->num_channels; i++) {
          alsa_track->volumes[i] = volumes[i];
          snd_mixer_selem_set_capture_volume (alsa_track->element, i,
              volumes[i]);
        }
      }
    } else {
      for (i = 0; i < track->num_channels; i++)
        alsa_track->volumes[i] = volumes[i];
    }
  }
  g_static_rec_mutex_unlock (mixer->rec_mutex);
}
Beispiel #3
0
void
gst_alsa_mixer_set_mute (GstAlsaMixer * mixer, GstMixerTrack * track,
    gboolean mute)
{
  GstAlsaMixerTrack *alsa_track = GST_ALSA_MIXER_TRACK (track);

  g_return_if_fail (mixer->handle != NULL);

  g_static_rec_mutex_lock (mixer->rec_mutex);

  gst_alsa_mixer_track_update (alsa_track);

  if (!!(mute) == !!(track->flags & GST_MIXER_TRACK_MUTE)) {
    g_static_rec_mutex_unlock (mixer->rec_mutex);
    return;
  }
  if (mute) {
    track->flags |= GST_MIXER_TRACK_MUTE;

    if (alsa_track->shared_mute)
      ((GstMixerTrack *) (alsa_track->shared_mute))->flags |=
          GST_MIXER_TRACK_MUTE;
  } else {
    track->flags &= ~GST_MIXER_TRACK_MUTE;

    if (alsa_track->shared_mute)
      ((GstMixerTrack *) (alsa_track->shared_mute))->flags &=
          ~GST_MIXER_TRACK_MUTE;
  }

  if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_PSWITCH) {
    snd_mixer_selem_set_playback_switch_all (alsa_track->element, mute ? 0 : 1);
  } else {
    gint i;
    GstAlsaMixerTrack *ctrl_track;

    if ((track->flags & GST_MIXER_TRACK_INPUT)
        && alsa_track->shared_mute != NULL)
      ctrl_track = alsa_track->shared_mute;
    else
      ctrl_track = alsa_track;

    for (i = 0; i < ((GstMixerTrack *) ctrl_track)->num_channels; i++) {
      long vol =
          mute ? ((GstMixerTrack *) ctrl_track)->
          min_volume : ctrl_track->volumes[i];
      snd_mixer_selem_set_playback_volume (ctrl_track->element, i, vol);
    }
  }
  g_static_rec_mutex_unlock (mixer->rec_mutex);
}
Beispiel #4
0
void
gst_alsa_mixer_get_volume (GstAlsaMixer * mixer, GstMixerTrack * track,
    gint * volumes)
{
  gint i;
  GstAlsaMixerTrack *alsa_track = GST_ALSA_MIXER_TRACK (track);

  g_return_if_fail (mixer->handle != NULL);

  g_static_rec_mutex_lock (mixer->rec_mutex);

  gst_alsa_mixer_track_update (alsa_track);

  if (track->flags & GST_MIXER_TRACK_OUTPUT) {  /* return playback volume */

    /* Is emulated mute flag activated? */
    if (track->flags & GST_MIXER_TRACK_MUTE &&
        !(alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_PSWITCH)) {
      for (i = 0; i < track->num_channels; i++)
        volumes[i] = alsa_track->volumes[i];
    } else {
      for (i = 0; i < track->num_channels; i++) {
        long tmp = 0;

        snd_mixer_selem_get_playback_volume (alsa_track->element, i, &tmp);
        alsa_track->volumes[i] = volumes[i] = (gint) tmp;
      }
    }

  } else if (track->flags & GST_MIXER_TRACK_INPUT) {    /* return capture volume */

    /* Is emulated record flag activated? */
    if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CSWITCH ||
        track->flags & GST_MIXER_TRACK_RECORD) {
      for (i = 0; i < track->num_channels; i++) {
        long tmp = 0;

        snd_mixer_selem_get_capture_volume (alsa_track->element, i, &tmp);
        alsa_track->volumes[i] = volumes[i] = (gint) tmp;
      }
    } else {
      for (i = 0; i < track->num_channels; i++)
        volumes[i] = alsa_track->volumes[i];
    }
  }
  g_static_rec_mutex_unlock (mixer->rec_mutex);
}
Beispiel #5
0
static void
gst_alsa_mixer_update_track (GstAlsaMixer * mixer,
    GstAlsaMixerTrack * alsa_track)
{
  GstMixerTrack *track = (GstMixerTrack *) alsa_track;
  gboolean old_mute;
  gboolean old_record;
  gint i, n_channels;
  gint *old_volumes;

  GST_DEBUG ("Updating track %" GST_PTR_FORMAT, alsa_track);

  if (mixer->interface == NULL) {
    GST_WARNING ("Cannot send update notifications, no GstMixer * given");
    return;
  }

  old_mute = !!(GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE));
  old_record = !!(GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_RECORD));
  old_volumes = g_new (gint, track->num_channels);
  n_channels = track->num_channels;
  memcpy (old_volumes, alsa_track->volumes,
      sizeof (gint) * track->num_channels);

  gst_alsa_mixer_track_update (alsa_track);

  if (old_record !=
      !!(GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_RECORD))) {
    gst_mixer_record_toggled (mixer->interface, track,
        !!GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_RECORD));
  }
  if (old_mute != !!(GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE))) {
    gst_mixer_mute_toggled (mixer->interface, track,
        !!GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE));
  }

  n_channels = MIN (n_channels, track->num_channels);
  for (i = 0; i < n_channels; i++) {
    if (old_volumes[i] != alsa_track->volumes[i]) {
      gst_mixer_volume_changed (mixer->interface, track, alsa_track->volumes);
      break;
    }
  }
  g_free (old_volumes);
}
Beispiel #6
0
GstMixerTrack *
gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
    gint num, gint track_num, gint flags, gboolean sw,
    GstAlsaMixerTrack * shared_mute_track, gboolean append_capture)
{
  GstAlsaMixerTrack *alsa_track;
  GstMixerTrack *track;
  const gchar *name;
  const gchar *label;
  gint i;
  long min = 0, max = 0;
  const struct
  {
    const gchar orig[12];
    const gchar trans[12];
  } alsa_track_labels[] = {
    {
    "Master", N_("Master")}, {
    "Bass", N_("Bass")}, {
    "Treble", N_("Treble")}, {
    "PCM", N_("PCM")}, {
    "Synth", N_("Synth")}, {
    "Line", N_("Line-in")}, {
    "CD", N_("CD")}, {
    "Mic", N_("Microphone")}, {
    "PC Speaker", N_("PC Speaker")}, {
    "Playback", N_("Playback")}, {
    "Capture", N_("Capture")}
  };

  name = snd_mixer_selem_get_name (element);

  GST_LOG ("[%s] num=%d,track_num=%d,flags=0x%08x,sw=%s,shared_mute_track=%p",
      name, num, track_num, flags, (sw) ? "true" : "false", shared_mute_track);

  track = (GstMixerTrack *) g_object_new (GST_ALSA_MIXER_TRACK_TYPE,
      "untranslated-label", name, NULL);

  alsa_track = (GstAlsaMixerTrack *) track;

  GST_LOG ("[%s] created new mixer track %p", name, track);

  /* This reflects the assumptions used for GstAlsaMixerTrack */
  if (!(!!(flags & GST_MIXER_TRACK_OUTPUT) ^ !!(flags & GST_MIXER_TRACK_INPUT))) {
    GST_ERROR ("Mixer track must be either output or input!");
    g_return_val_if_reached (NULL);
  }

  track->flags = flags;
  alsa_track->element = element;
  alsa_track->shared_mute = shared_mute_track;
  alsa_track->track_num = track_num;
  alsa_track->alsa_channels = 0;

  gst_alsa_mixer_track_update_alsa_capabilities (alsa_track);

  if (flags & GST_MIXER_TRACK_OUTPUT) {
    while (alsa_track->alsa_channels < GST_ALSA_MAX_CHANNELS &&
        snd_mixer_selem_has_playback_channel (element,
            alsa_track->alsa_channels)) {
      alsa_track->alsa_channels++;
    }
    GST_LOG ("[%s] %d output channels", name, alsa_track->alsa_channels);
  } else if (flags & GST_MIXER_TRACK_INPUT) {
    while (alsa_track->alsa_channels < GST_ALSA_MAX_CHANNELS &&
        snd_mixer_selem_has_capture_channel (element,
            alsa_track->alsa_channels)) {
      alsa_track->alsa_channels++;
    }
    GST_LOG ("[%s] %d input channels", name, alsa_track->alsa_channels);
  } else {
    g_assert_not_reached ();
  }

  if (sw)
    track->num_channels = 0;
  else
    track->num_channels = alsa_track->alsa_channels;

  /* translate the name if we can */
  label = name;
  for (i = 0; i < G_N_ELEMENTS (alsa_track_labels); ++i) {
    if (g_utf8_collate (label, alsa_track_labels[i].orig) == 0) {
      label = _(alsa_track_labels[i].trans);
      break;
    }
  }

  if (num == 0) {
    track->label = g_strdup_printf ("%s%s%s", label,
        append_capture ? " " : "", append_capture ? _("Capture") : "");
  } else {
    track->label = g_strdup_printf ("%s%s%s %d", label,
        append_capture ? " " : "", append_capture ? _("Capture") : "", num);
  }

  /* set volume information */
  if (track->num_channels > 0) {
    if ((flags & GST_MIXER_TRACK_OUTPUT))
      snd_mixer_selem_get_playback_volume_range (element, &min, &max);
    else
      snd_mixer_selem_get_capture_volume_range (element, &min, &max);
  }
  track->min_volume = (gint) min;
  track->max_volume = (gint) max;

  for (i = 0; i < track->num_channels; i++) {
    long tmp = 0;

    if (flags & GST_MIXER_TRACK_OUTPUT)
      snd_mixer_selem_get_playback_volume (element, i, &tmp);
    else
      snd_mixer_selem_get_capture_volume (element, i, &tmp);

    alsa_track->volumes[i] = (gint) tmp;
  }

  gst_alsa_mixer_track_update (alsa_track);

  return track;
}