示例#1
0
static int elem_get_vol_percent(snd_mixer_elem_t *elem)
{
	int i, percent; 
	long pmin, pmax, volume;

	for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) {
		/* playback volume */
		if (snd_mixer_selem_has_playback_channel(elem, i) && 
				!snd_mixer_selem_has_common_volume(elem)) {
			snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax);
			if (snd_mixer_selem_has_playback_volume(elem))
				snd_mixer_selem_get_playback_volume(elem, i, &volume);

		}
		/* capture volume */
		else if (snd_mixer_selem_has_capture_channel(elem, i) && 
				!snd_mixer_selem_has_common_volume(elem)) {
			snd_mixer_selem_get_capture_volume_range(elem, &pmin, &pmax);
			if (snd_mixer_selem_has_capture_volume(elem))
				snd_mixer_selem_get_capture_volume(elem, i, &volume);
		} else {
		/* Misc. ex: Boost */
			snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax);
			snd_mixer_selem_get_playback_volume(elem, i, &volume);
		}
	}

	percent = (int) ((double)(volume - pmin) / (double)(pmax - pmin) * 100);

	return percent;
}
示例#2
0
static PxVolume get_volume_indexed(PxDev *dev, int i, int playback)
{
   snd_mixer_elem_t *elem;
   long vol, min, max;

   if (!dev->handle) {
      return 0.0;
   }

   if (i < 0 || i > dev->numselems) {
      return 0.0;
   }

   elem = dev->selems[i].elem;
   if (playback) {
      snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
      if (snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) {
         snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &vol);
         return (PxVolume) vol / (max - min);
      }
   }
   else {
      snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
      if (snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) {
         snd_mixer_selem_get_capture_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &vol);
         return (PxVolume) vol / (max - min);
      }
   }
   
   return 0.0;
}
示例#3
0
static void elem_set_vol_percent(snd_mixer_elem_t *elem, int vol_percent)
{
	int i;
	long pmin, pmax, value;
	
	//sdbg("%s: set mixer element volume\n", __func__);
	for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) {
		if (snd_mixer_selem_has_playback_channel(elem, i) && 
				!snd_mixer_selem_has_common_volume(elem)) {
			snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax);
		/* playback volume */
			if (snd_mixer_selem_has_playback_volume(elem)) {
				value = (int)rint((double)pmin + 0.01 * vol_percent * ((double)pmax - (double)pmin));
				snd_mixer_selem_set_playback_volume(elem, i, value);
			}
		} else if (snd_mixer_selem_has_capture_channel(elem, i) && 
				!snd_mixer_selem_has_common_volume(elem)) {
		/* capture volume */
			snd_mixer_selem_get_capture_volume_range(elem, &pmin, &pmax);
			if (snd_mixer_selem_has_capture_volume(elem)) {
				value = (int)rint((double)pmin + 0.01 * vol_percent * ((double)pmax - (double)pmin));
				snd_mixer_selem_set_capture_volume(elem, i, value);
			}
		} else {
		/* Misc. ex: Boost */
			snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax);
			value = (int)rint((double)pmin + 0.01 * vol_percent * ((double)pmax - (double)pmin));
			snd_mixer_selem_set_playback_volume(elem, i, value);

			snd_mixer_selem_get_capture_volume_range(elem, &pmin, &pmax);
			value = (int)rint((double)pmin + 0.01 * vol_percent * ((double)pmax - (double)pmin));
			snd_mixer_selem_set_capture_volume(elem, i, value);
		}
	}
}
示例#4
0
static enum MixerCode alsaMixerSelectCard(struct MixerSystem* system, int mixerId) {
	enum MixerCode code;
	snd_mixer_elem_t* mixerElem = NULL;
	AlsaMixerCard* card = (AlsaMixerCard*)system->active;
	if ( !card  ) {
		if ( card == system->mixerCard->pElement[mixerId] ) {
			return MIXER_CODE_OK;
		}
		alsaMixerCardClose(system);
	}

	code = commonMixerSelectCard(system, mixerId);
	if ( code != MIXER_CODE_OK ) {
		GOC_DEBUG("Cannot select card by commonMixerSelectCard");
		return code;
	}
	card = (AlsaMixerCard*)system->active;

	GOC_CHEOP_DEBUG(snd_mixer_open( &card->sndmixer, 0 ) == 0, return MIXER_CODE_CANNOT_OPEN_CARD);
	GOC_CHEOP_DEBUG(snd_mixer_attach( card->sndmixer, card->physicalName ) == 0, return MIXER_CODE_CANNOT_OPEN_CARD);
	GOC_CHEOP_DEBUG(snd_mixer_selem_register( card->sndmixer, NULL, NULL ) == 0, return MIXER_CODE_CANNOT_OPEN_CARD);
	GOC_CHEOP_DEBUG(snd_mixer_load( card->sndmixer ) == 0, return MIXER_CODE_CANNOT_OPEN_CARD);

	mixerElem = snd_mixer_first_elem( card->sndmixer );
	while ( mixerElem ) {
		AlsaMixerElement* pMixerElement = alsaMixerElementAlloc();
		for (int channel = 0; channel <= SND_MIXER_SCHN_LAST; channel++ ) {
			if ( snd_mixer_selem_has_playback_channel(mixerElem, channel)
				&& snd_mixer_selem_get_playback_volume_range(mixerElem, &pMixerElement->rangemin, &pMixerElement->rangemax) == 0
				&& snd_mixer_selem_get_playback_volume(mixerElem, channel, &pMixerElement->volume) == 0 ) {
					pMixerElement->name = goc_stringCopy(NULL, snd_mixer_selem_get_name(mixerElem));
					pMixerElement->type = MIXER_ELEMENT_PLAYBACK;
					pMixerElement->sndelement = mixerElem;
					card->mixerElement = goc_arrayAdd( card->mixerElement, pMixerElement );
					break;
			} else if ( snd_mixer_selem_has_capture_channel(mixerElem, channel)
				&& snd_mixer_selem_get_capture_volume_range(mixerElem, &pMixerElement->rangemin, &pMixerElement->rangemax) == 0
				&& snd_mixer_selem_get_capture_volume(mixerElem, channel, &pMixerElement->volume) == 0 ) {
					pMixerElement->name = goc_stringCopy(NULL, snd_mixer_selem_get_name(mixerElem));
					pMixerElement->type = MIXER_ELEMENT_CAPTURE;
					pMixerElement->sndelement = mixerElem;
					card->mixerElement = goc_arrayAdd( card->mixerElement, pMixerElement );
					break;
			}
		}
		mixerElem = snd_mixer_elem_next( mixerElem );
	}
	return MIXER_CODE_OK;
}
示例#5
0
static int elem_get_status(snd_mixer_elem_t *elem)
{
	int i, psw = -1;

	for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) {
		if (snd_mixer_selem_has_playback_channel(elem, i) && 
				snd_mixer_selem_has_playback_switch(elem))
			snd_mixer_selem_get_playback_switch(elem, i, &psw);
		else if (snd_mixer_selem_has_capture_channel(elem, i) && 
				snd_mixer_selem_has_capture_switch(elem))
			snd_mixer_selem_get_capture_switch(elem, i, &psw);
	}

	return psw;
}
示例#6
0
/*
 * Class:     org_tritonus_lowlevel_alsa_AlsaMixerElement
 * Method:    hasPlaybackChannel
 * Signature: (I)Z
 */
JNIEXPORT jboolean JNICALL
Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackChannel
(JNIEnv* env, jobject obj, jint nChannelType)
{
    snd_mixer_elem_t*	handle;
    int			nReturn;

    if (debug_flag) {
        (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackChannel(): begin\n");
    }
    handle = getHandle(env, obj);
    nReturn = snd_mixer_selem_has_playback_channel(handle, (snd_mixer_selem_channel_id_t) nChannelType);
    if (debug_flag) {
        (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_hasPlaybackChannel(): end\n");
    }
    return (jboolean) nReturn;
}
static PyObject*
ALSAAudio_get_volume(output_ALSAAudio *self, PyObject *args)
{
    if (self->mixer_elem) {
        /*get the average volume from all supported output channels*/
        const snd_mixer_selem_channel_id_t channels[] = {
            SND_MIXER_SCHN_FRONT_LEFT,
            SND_MIXER_SCHN_FRONT_RIGHT,
            SND_MIXER_SCHN_REAR_LEFT,
            SND_MIXER_SCHN_REAR_RIGHT,
            SND_MIXER_SCHN_FRONT_CENTER,
            SND_MIXER_SCHN_WOOFER,
            SND_MIXER_SCHN_SIDE_LEFT,
            SND_MIXER_SCHN_SIDE_RIGHT,
            SND_MIXER_SCHN_REAR_CENTER};
        const size_t channel_count =
            sizeof(channels) / sizeof(snd_mixer_selem_channel_id_t);
        size_t i;
        double total_volume = 0.0;
        unsigned total_channels = 0;

        for (i = 0; i < channel_count; i++) {
            long channel_volume;
            if (snd_mixer_selem_has_playback_channel(self->mixer_elem,
                                                     channels[i]) &&
                (snd_mixer_selem_get_playback_volume(self->mixer_elem,
                                                     channels[i],
                                                     &channel_volume) == 0)) {
                total_volume += channel_volume;
                total_channels++;
            }
        }

        if (total_channels > 0) {
            const double average_volume = total_volume / total_channels;

            /*convert to range min_volume->max_volume*/
            return PyFloat_FromDouble(average_volume / self->volume_max);
        } else {
            return PyFloat_FromDouble(0.0);
        }
    } else {
        return PyFloat_FromDouble(0.0);
    }
}
示例#8
0
static int alsa_read_mixer_raw (snd_mixer_elem_t *elem)
{
	if (mixer_handle) {
		long volume = 0;
		int nchannels = 0;
		int i;
		int err;

		assert (elem != NULL);

		handle_mixer_events (mixer_handle);

		for (i = 0; i < SND_MIXER_SCHN_LAST; i++)
			if (snd_mixer_selem_has_playback_channel(elem,
						1 << i)) {
				long vol;
				
				nchannels++;
				if ((err = snd_mixer_selem_get_playback_volume(
								elem,
								1 << i,
								&vol)) < 0) {
					error ("Can't read mixer: %s",
							snd_strerror(err));
					return -1;
						
				}
				/*logit ("Vol %d: %ld", i, vol);*/
				volume += vol;
			}

		if (nchannels > 0)
			volume /= nchannels;
		else {
			logit ("Mixer has no channels");
			volume = -1;
		}

		/*logit ("Max: %ld, Min: %ld", mixer_max, mixer_min);*/
		return volume;

	}
	else
		return -1;
}
示例#9
0
static gint
_j4status_alsa_section_mixer_callback(snd_mixer_t *mixer, guint mask, snd_mixer_elem_t *elem)
{
    J4statusAlsaSection *section = snd_mixer_get_callback_private(mixer);
    if ( mask & SND_CTL_EVENT_MASK_ADD )
    {
        if ( ( snd_mixer_selem_get_index(elem) == 0 )
             && ( g_strcmp0(snd_mixer_selem_get_name(elem), "Master") == 0 )
             && snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)
             && ( snd_mixer_elem_get_callback_private(elem) == NULL )
            )
        {
            snd_mixer_elem_set_callback(elem, _j4status_alsa_section_elem_callback);
            snd_mixer_elem_set_callback_private(elem, section);
        }
    }
    return 0;
}
示例#10
0
static int set_normalized_volume_all(snd_mixer_elem_t *elem,
				 double volume,
				 int dir,
				 enum ctl_dir ctl_dir)
{
	snd_mixer_selem_channel_id_t chn;
	int err;

	for (chn = 0; chn < 32; chn++) {
		if (!snd_mixer_selem_has_playback_channel(elem, chn))
			continue;
		err = set_normalized_volume(elem, chn, volume, dir, ctl_dir);
		if (err < 0)
			return err;
		if (chn == 0 && snd_mixer_selem_has_playback_volume_joined(elem))
			return 0;
	}
	return 0;
}
示例#11
0
/* mute: 0 -> mute,  1 -> unmute */
void sound_mixer_mute(const char *mixer, MUTEST mute)
{
	int i;
	snd_mixer_t *handle = NULL;
	snd_mixer_elem_t *elem = NULL;

	elem = sound_get_elem(mixer, &handle);
	if (!elem)
		return;

	for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) {
		if (snd_mixer_selem_has_playback_channel(elem, i) &&
				snd_mixer_selem_has_playback_switch(elem))
			snd_mixer_selem_set_playback_switch(elem, i, mute);
		else if (snd_mixer_selem_has_capture_channel(elem, i) &&
				snd_mixer_selem_has_capture_switch(elem))
			snd_mixer_selem_set_capture_switch(elem, i, mute);
	}
	snd_mixer_close(handle);
}
示例#12
0
static void
_j4status_alsa_section_update(J4statusAlsaSection *section, snd_mixer_elem_t *elem)
{
    if ( ( ! snd_mixer_selem_has_playback_volume(elem) )
         || ( ! snd_mixer_selem_has_playback_switch(elem) )
         || ( ! snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) ) )
        return;

    int error;
    gboolean pswitch = TRUE;
    error = snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, &pswitch);
    if ( error < 0 )
        g_warning("Couldn't get muted status: %s", snd_strerror(error));
    else
    {
        if ( pswitch )
            j4status_section_set_state(section->section, J4STATUS_STATE_GOOD);
        else
            j4status_section_set_state(section->section, J4STATUS_STATE_BAD);
    }

    glong volume = 0;
    if ( section->use_dB )
        error = snd_mixer_selem_get_playback_dB(elem, SND_MIXER_SCHN_FRONT_LEFT, &volume);
    else
        error = snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &volume);
    if ( error < 0 )
        g_warning("Couldn't get volume: %s", snd_strerror(error));
    else
    {
        guint8 vol;
        gchar *v;
        vol = _j4status_alsa_get_normalized_volume(volume, section->min, section->max, section->use_dB);
        v = g_strdup_printf("%hu%%", vol);
        j4status_section_set_value(section->section, v);
    }
}
示例#13
0
static void set_volume_indexed(PxDev *dev, int i, PxVolume volume, int playback)
{
   snd_mixer_elem_t *elem;
   long vol, min, max;
   int j;

   if (!dev->handle) {
      return;
   }

   if (i < 0 || i > dev->numselems) {
      return;
   }

   elem = dev->selems[i].elem;
   if (playback) {
      snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
      for (j = 0; j < SND_MIXER_SCHN_LAST; j++) {
         if (snd_mixer_selem_has_playback_channel(elem, j)) {
            vol = (long) (volume * (max - min) + 0.5);
            snd_mixer_selem_set_playback_volume(elem, j, vol);
         }
      }
   }
   else {
      snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
      for (j = 0; j < SND_MIXER_SCHN_LAST; j++) {
         if (snd_mixer_selem_has_capture_channel(elem, j)) {
            vol = (long) (volume * (max - min) + 0.5);
            snd_mixer_selem_set_capture_volume(elem, j, vol);
         }
      }
   }

   return;
}
void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
    PortMixer* portMixer;
    snd_mixer_elem_t* elem;
    void* control;
    PortControl* portControl;
    void* controls[10];
    int numControls;
    char* portName;
    int isPlayback = 0;
    int isMono;
    int isStereo;
    char* type;
    snd_mixer_selem_channel_id_t channel;

    TRACE0("> PORT_GetControls\n");
    if (id == NULL) {
        ERROR0("Invalid handle!");
        // $$mp: an error code should be returned.
        return;
    }
    portMixer = (PortMixer*) id;
    if (portIndex < 0 || portIndex >= portMixer->numElems) {
        ERROR0("Port index out of range!");
        // $$mp: an error code should be returned.
        return;
    }
    numControls = 0;
    elem = portMixer->elems[portIndex];
    if (snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) {
        /* Since we've split/duplicated elements with both playback and capture on the recovery
           of elements, we now can assume that we handle only to deal with either playback or
           capture. */
        isPlayback = isPlaybackFunction(portMixer->types[portIndex]);
        isMono = (isPlayback && snd_mixer_selem_is_playback_mono(elem)) ||
            (!isPlayback && snd_mixer_selem_is_capture_mono(elem));
        isStereo = (isPlayback &&
                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
                    snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) ||
            (!isPlayback &&
             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT) &&
             snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT));
        // single volume control
        if (isMono || isStereo) {
            if (getControlSlot(portMixer, &portControl)) {
                portControl->elem = elem;
                portControl->portType = portMixer->types[portIndex];
                portControl->controlType = CONTROL_TYPE_VOLUME;
                if (isMono) {
                    portControl->channel = CHANNELS_MONO;
                } else {
                    portControl->channel = CHANNELS_STEREO;
                }
                control = createVolumeControl(creator, portControl, elem, isPlayback);
                if (control != NULL) {
                    controls[numControls++] = control;
                }
            }
        } else { // more than two channels, each channels has its own control.
            for (channel = SND_MIXER_SCHN_FRONT_LEFT; channel <= SND_MIXER_SCHN_LAST; channel++) {
                if ((isPlayback && snd_mixer_selem_has_playback_channel(elem, channel)) ||
                    (!isPlayback && snd_mixer_selem_has_capture_channel(elem, channel))) {
                    if (getControlSlot(portMixer, &portControl)) {
                        portControl->elem = elem;
                        portControl->portType = portMixer->types[portIndex];
                        portControl->controlType = CONTROL_TYPE_VOLUME;
                        portControl->channel = channel;
                        control = createVolumeControl(creator, portControl, elem, isPlayback);
                        // We wrap in a compound control to provide the channel name.
                        if (control != NULL) {
                            /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
                               declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
                               to take a const char* parameter. */
                            control = (creator->newCompoundControl)(creator, (char*) snd_mixer_selem_channel_name(channel), &control, 1);
                        }
                        if (control != NULL) {
                            controls[numControls++] = control;
                        }
                    }
                }
            }
        }
        // BALANCE control
        if (isStereo) {
            if (getControlSlot(portMixer, &portControl)) {
                portControl->elem = elem;
                portControl->portType = portMixer->types[portIndex];
                portControl->controlType = CONTROL_TYPE_BALANCE;
                portControl->channel = CHANNELS_STEREO;
                /* $$mp: The value for precision is chosen more or less arbitrarily. */
                control = (creator->newFloatControl)(creator, portControl, CONTROL_TYPE_BALANCE, -1.0F, 1.0F, 0.01F, "");
                if (control != NULL) {
                    controls[numControls++] = control;
                }
            }
        }
    }
    if (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_capture_switch(elem)) {
        if (getControlSlot(portMixer, &portControl)) {
            type = isPlayback ? CONTROL_TYPE_MUTE : CONTROL_TYPE_SELECT;
            portControl->elem = elem;
            portControl->portType = portMixer->types[portIndex];
            portControl->controlType = type;
            control = (creator->newBooleanControl)(creator, portControl, type);
            if (control != NULL) {
                controls[numControls++] = control;
            }
        }
    }
    /* $$mp 2003-09-14: The following cast shouln't be necessary. Instead, the
       declaration of PORT_NewCompoundControlPtr in Ports.h should be changed
       to take a const char* parameter. */
    portName = (char*) snd_mixer_selem_get_name(elem);
    control = (creator->newCompoundControl)(creator, portName, controls, numControls);
    if (control != NULL) {
        (creator->addControl)(creator, control);
    }
    TRACE0("< PORT_GetControls\n");
}
示例#15
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;
}
示例#16
0
/******************************************************************************
 *   setMixerVolume
 *****************************************************************************/
static Int setMixerVolume (Sound_Attrs *attrs)
{
    Int status;
    snd_mixer_t *rcMixer;
    snd_mixer_elem_t    *elem;
    snd_mixer_selem_id_t    *sid;

    snd_mixer_selem_id_malloc (&sid);

    /* Open the mixer device */
    status = snd_mixer_open (&rcMixer, 0);

    if ( status<0 ) {
        Dmai_err2 ("Failed to open mixer on %s (%s)\n",
                   AUDIO_MIXER, snd_strerror (status));
        return Dmai_EFAIL;
    }

    /* Attach mixer with sound card */
    status = snd_mixer_attach (rcMixer,AUDIO_MIXER);

    if (status <0) {
        Dmai_err2 ("Failed to attach mixer on %s (%s)\n",
                   AUDIO_MIXER, snd_strerror (status));
        return Dmai_EFAIL;
    }

    /* Register mixer with selected elements */
    status = snd_mixer_selem_register (rcMixer, NULL, NULL);

    if (status <0) {
        Dmai_err2 ("Failed to register mixer on %s (%s)\n",
                   AUDIO_MIXER, snd_strerror (status));
        return Dmai_EFAIL;
    }
    /* Load mixer */
    status = snd_mixer_load (rcMixer);

    if (status <0) {
        Dmai_err2 ("Failed to load mixer on %s (%s)\n",
                   AUDIO_MIXER, snd_strerror (status));
        return Dmai_EFAIL;
    }

    for (elem = snd_mixer_first_elem (rcMixer); elem; 
            elem=snd_mixer_elem_next(elem)) {

        snd_mixer_selem_get_id(elem,sid);
        if (!snd_mixer_selem_is_active(elem))
            continue;

        if (attrs->mode == Sound_Mode_OUTPUT || 
             attrs->mode == Sound_Mode_FULLDUPLEX) {
            if (snd_mixer_selem_has_playback_channel(elem, 
                 SND_MIXER_SCHN_FRONT_LEFT))
                snd_mixer_selem_set_playback_volume (elem, 
                SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain);
            if (snd_mixer_selem_has_playback_channel(elem, 
                          SND_MIXER_SCHN_FRONT_RIGHT))
                snd_mixer_selem_set_playback_volume (elem, 
                          SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain);
        }

        if (attrs->mode == Sound_Mode_INPUT || 
                    attrs->mode == Sound_Mode_FULLDUPLEX) {
            if (snd_mixer_selem_has_capture_channel(elem,
                    SND_MIXER_SCHN_FRONT_LEFT))
                snd_mixer_selem_set_capture_volume (elem, 
                           SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain);
            if (snd_mixer_selem_has_capture_channel(elem, 
                    SND_MIXER_SCHN_FRONT_RIGHT))
                snd_mixer_selem_set_capture_volume (elem, 
                           SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain);
        }
    }

    snd_mixer_selem_id_free (sid);
    snd_mixer_close (rcMixer);

    return Dmai_EOK;
}