Пример #1
0
static snd_mixer_elem_t *
gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle)
{
  snd_mixer_elem_t *element;
  gint i, count;

  count = snd_mixer_get_count (handle);

  /* Check if we have a playback mixer labelled as 'Master' */
  element = snd_mixer_first_elem (handle);
  for (i = 0; i < count; i++) {
    if (snd_mixer_selem_has_playback_volume (element) &&
        strcmp (snd_mixer_selem_get_name (element), "Master") == 0) {
      return element;
    }
    element = snd_mixer_elem_next (element);
  }

  /* If not, check if we have a playback mixer labelled as 'Front' */
  element = snd_mixer_first_elem (handle);
  for (i = 0; i < count; i++) {
    if (snd_mixer_selem_has_playback_volume (element) &&
        strcmp (snd_mixer_selem_get_name (element), "Front") == 0) {
      return element;
    }
    element = snd_mixer_elem_next (element);
  }

  /* If not, check if we have a playback mixer labelled as 'PCM' */
  element = snd_mixer_first_elem (handle);
  for (i = 0; i < count; i++) {
    if (snd_mixer_selem_has_playback_volume (element) &&
        strcmp (snd_mixer_selem_get_name (element), "PCM") == 0) {
      return element;
    }
    element = snd_mixer_elem_next (element);
  }

  /* If not, check if we have a playback mixer with both volume and switch */
  element = snd_mixer_first_elem (handle);
  for (i = 0; i < count; i++) {
    if (snd_mixer_selem_has_playback_volume (element) &&
        snd_mixer_selem_has_playback_switch (element)) {
      return element;
    }
    element = snd_mixer_elem_next (element);
  }

  /* If not, take any playback mixer with a volume control */
  element = snd_mixer_first_elem (handle);
  for (i = 0; i < count; i++) {
    if (snd_mixer_selem_has_playback_volume (element)) {
      return element;
    }
    element = snd_mixer_elem_next (element);
  }

  /* Looks like we're out of luck ... */
  return NULL;
}
Пример #2
0
static void set_volume(AudioCapture *capture, int level) {
  snd_mixer_t *mixer=NULL;
  
  int err;
  err=snd_mixer_open(&mixer,0);
  if(err < 0) {
    fprintf(stderr, "Could not open alsa mixer: %s\r\n",snd_strerror(err));
    exit(1);
  }
  
  char hw_id[100];
  snprintf(hw_id, sizeof(hw_id), "hw:%d", capture->pcm_id);

  if ((err = snd_mixer_attach (mixer, hw_id)) < 0){
		fprintf(stderr, "Could not attach mixer to card(%s): %s\r\n", hw_id, snd_strerror(err));
		snd_mixer_close(mixer);
    exit(1);
	}
	if ((err = snd_mixer_selem_register (mixer, NULL, NULL)) < 0){
		fprintf(stderr, "snd_mixer_selem_register: %s\r\n",snd_strerror(err));
		snd_mixer_close(mixer);
		exit(1);
	}
	if ((err = snd_mixer_load (mixer)) < 0){
		fprintf(stderr, "snd_mixer_load: %s\r\n",snd_strerror(err));
		snd_mixer_close(mixer);
		exit(1);
	}
	
	snd_mixer_elem_t *elem;
	elem = snd_mixer_first_elem(mixer);
	
	while(elem) {
    const char *elemname = snd_mixer_selem_get_name(elem);
    if(strcmp(elemname, "Capture") && strcmp(elemname, "Mic")) {
      fprintf(stderr, "Skip setting volume for %s\r\n", elemname);
      elem=snd_mixer_elem_next(elem);
      continue;
    }
  	if (snd_mixer_selem_has_capture_volume(elem)){
      fprintf(stderr, "Set volume for %s\r\n", elemname);
    	long sndMixerPMin;
    	long sndMixerPMax;
      long newvol;
    	snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
    	newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin;
      snd_mixer_selem_set_capture_volume_all(elem,newvol);
      elem=snd_mixer_elem_next(elem);
  	} else {
      fprintf(stderr, "Can't set capture volume\r\n");
      exit(1);
  	}
	}
}
Пример #3
0
void mixerGuiAlsaMix::cardChanged( int card )
{
#ifdef HAVE_ALSA
	channelSelect->clear();
	// get the cards channels
	snd_mixer_t* alsaDev;
	snd_mixer_open( &alsaDev, 0);
	char device[16];
	sprintf(device, "hw:%i", card);
	snd_mixer_attach(alsaDev, device );
	snd_mixer_selem_register(alsaDev, NULL, NULL);
	snd_mixer_load(alsaDev);  //load up the mixer

	snd_mixer_elem_t* mixerElem = snd_mixer_first_elem(alsaDev);
	while( mixerElem != snd_mixer_last_elem(alsaDev) )
	{
	    if(snd_mixer_selem_has_playback_volume(mixerElem) || snd_mixer_selem_has_capture_volume(mixerElem))
		channelSelect->addItem( QString( snd_mixer_selem_get_name(mixerElem)), QVariant( snd_mixer_selem_get_name(mixerElem)) );
	    mixerElem=snd_mixer_elem_next( mixerElem );
	}

	for(int i=0; i<= channelSelect->count(); i++ )
	    if( channelSelect->itemData(i) == settings["alsa_channel"].toString() )
		channelSelect->setCurrentIndex( i );
#endif
}
Пример #4
0
static snd_mixer_elem_t *find_mixer_elem_by_name(const char *goal_name)
{
	snd_mixer_elem_t *elem;
	snd_mixer_selem_id_t *sid = NULL;

	snd_mixer_selem_id_malloc(&sid);

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

		const char *name;

		snd_mixer_selem_get_id(elem, sid);
		name = snd_mixer_selem_id_get_name(sid);
		d_print("name = %s\n", name);
		d_print("has playback volume = %d\n", snd_mixer_selem_has_playback_volume(elem));
		d_print("has playback switch = %d\n", snd_mixer_selem_has_playback_switch(elem));

		if (strcasecmp(name, goal_name) == 0) {
			if (!snd_mixer_selem_has_playback_volume(elem)) {
				d_print("mixer element `%s' does not have playback volume\n", name);
				elem = NULL;
			}
			break;
		}
	}

	snd_mixer_selem_id_free(sid);
	return elem;
}
Пример #5
0
static int alsa_mixer_open(int *volume_max)
{
	snd_mixer_selem_id_t *sid;
	snd_mixer_elem_t *elem;
	int count;
	int rc;

	snd_mixer_selem_id_alloca(&sid);

	rc = snd_mixer_open(&alsa_mixer_handle, 0);
	if (rc < 0)
		goto error;
	rc = snd_mixer_attach(alsa_mixer_handle, alsa_mixer_device);
	if (rc < 0)
		goto error;
	rc = snd_mixer_selem_register(alsa_mixer_handle, NULL, NULL);
	if (rc < 0)
		goto error;
	rc = snd_mixer_load(alsa_mixer_handle);
	if (rc < 0)
		goto error;
	count = snd_mixer_get_count(alsa_mixer_handle);
	if (count == 0) {
		d_print("error: mixer does not have elements\n");
		return -2;
	}
	elem = snd_mixer_first_elem(alsa_mixer_handle);
	while (elem) {
		const char *name;
		int has_vol, has_switch;

		snd_mixer_selem_get_id(elem, sid);
		name = snd_mixer_selem_id_get_name(sid);
		d_print("name = %s\n", name);
		d_print("has playback volume = %d\n", snd_mixer_selem_has_playback_volume(elem));
		d_print("has playback switch = %d\n", snd_mixer_selem_has_playback_switch(elem));
		if (strcasecmp(name, alsa_mixer_element)) {
			elem = snd_mixer_elem_next(elem);
			continue;
		}
		has_vol = snd_mixer_selem_has_playback_volume(elem);
		if (!has_vol) {
			d_print("mixer element `%s' does not have playback volume\n", name);
			return -2;
		}
		snd_mixer_selem_get_playback_volume_range(elem,
				&mixer_vol_min, &mixer_vol_max);
		has_switch = snd_mixer_selem_has_playback_switch(elem);
		/* FIXME: get number of channels */
		mixer_elem = elem;
		*volume_max = mixer_vol_max - mixer_vol_min;
		return 0;
	}
	d_print("error: mixer element `%s' not found\n", alsa_mixer_element);
	return -2;
error:
	d_print("error: %s\n", snd_strerror(rc));
	return -1;
}
Пример #6
0
void
moko_alsa_volume_control_set_element_from_name (MokoAlsaVolumeControl *control,
					       const gchar *name)
{
	MokoAlsaVolumeControlPrivate *priv =
		ALSA_VOLUME_CONTROL_PRIVATE (control);

	if (!priv->device) return;
	
	detach_mixer (control);
	
	if (!name) {
		moko_alsa_volume_control_set_element (control, NULL);
		return;
	}
	
	open_mixer (control);
	if ((snd_mixer_attach (priv->mixer_handle, priv->device) == 0) &&
	    (snd_mixer_selem_register (priv->mixer_handle, NULL, NULL) == 0) &&
	    (snd_mixer_load (priv->mixer_handle) == 0)) {
		snd_mixer_elem_t *elem;
		
		elem = snd_mixer_first_elem (priv->mixer_handle);
		while (elem) {
			const char *elem_name = snd_mixer_selem_get_name (elem);
			if (strcmp (elem_name, name) == 0)
				break;
			elem = snd_mixer_elem_next (elem);
		}
		
		if (!elem) {
			snd_mixer_detach (priv->mixer_handle, priv->device);
			close_mixer (control);
			g_warning ("Mixer element '%s' not found", name);
			attach_mixer (control);
		} else {
			snd_mixer_selem_id_t *id;
			if (snd_mixer_selem_id_malloc (&id) != 0) {
				g_warning ("Unable to allocate element id");
				snd_mixer_detach (
					priv->mixer_handle, priv->device);
				close_mixer (control);
			} else {
				snd_mixer_selem_get_id (elem, id);
				snd_mixer_detach (
					priv->mixer_handle, priv->device);
				close_mixer (control);
				g_debug ("Setting element ID");
				moko_alsa_volume_control_set_element (
					control, id);
				snd_mixer_selem_id_free (id);
			}
		}
	} else
		g_warning ("Unable to open mixer on card '%s'", priv->device);
}
Пример #7
0
static int initialize_mixer_device(struct audio_info_struct *ai, char *error)
{
    int              sts;
    snd_mixer_t      *mixer;
    char             *mixerdev = "default";
    const char       *elemnam;
    snd_mixer_elem_t *mixerelem;

    sts = snd_mixer_open(&mixer, 0);
    if (sts) {
        if (error) {
            sprintf(error, "snd_mixer_open failed; %d\n", sts);
        }
        return 1;
    }

    if (mixer) {
        sts = snd_mixer_attach(mixer, mixerdev);
        if (sts) {
            if (error) {
                sprintf(error, "snd_mixer_attach: failed; %d\n", sts);
            }
            return 1;
        }
        sts = snd_mixer_selem_register(mixer, NULL, NULL);
        if (sts) {
            if (error) {
                sprintf(error, "snd_mixer_selem_register: failed; %d\n", sts);
            }
            return 1;
        }
        sts = snd_mixer_load(mixer);
        if (sts) {
            if (error) {
                sprintf(error, "snd_mixer_selem_register: failed; %d\n", sts);
            }

            return 1;
        }

        mixerelem = snd_mixer_first_elem(mixer);
        snd_mixer_set_callback(mixer, mixer_callback_func);

        while (mixerelem) {
            elemnam = snd_mixer_selem_get_name(mixerelem);
            if (strcasecmp(elemnam, "Master") == 0) {
                ai->vh = mixerelem;
                return 0;
            }
            mixerelem = snd_mixer_elem_next(mixerelem);
        }
    }
    return 1;
}
Пример #8
0
void asound_setup(const gchar * card, const gchar * channel,
	void (*volume_changed)(int,gboolean))
{
	// Make sure (for now) that the setup function only gets called once
	static int asound_setup_called = 0;
	assert(asound_setup_called == 0);
	asound_setup_called++;

	// Save card, volume_changed
	strcpy(m_card, card);
	m_volume_changed = volume_changed;

	// Load the mixer for the provided cardname
	snd_mixer_open(&m_mixer, 0);
	snd_mixer_attach(m_mixer, m_card);
	snd_mixer_selem_register(m_mixer, NULL, NULL);
	snd_mixer_load(m_mixer);

	// Setup g_io_watch for the mixer
	int count = snd_mixer_poll_descriptors_count(m_mixer);
	if(count >= 1)
	{
		struct pollfd pfd;

		count = snd_mixer_poll_descriptors(m_mixer, &pfd, 1);
		if(count == 1)
		{
			GIOChannel * giochannel = g_io_channel_unix_new(pfd.fd);
			g_io_add_watch_full(giochannel, G_PRIORITY_DEFAULT,
				G_IO_IN, asound_poll_cb, NULL, NULL);
		}
	}

	// Iterate over the elements in the mixer and store them in m_channel_names
	int elemcount = snd_mixer_get_count(m_mixer);
	snd_mixer_elem_t * elem = snd_mixer_first_elem(m_mixer);
	int loop;
	for(loop = 0; loop < elemcount; loop++)
	{
		const char * elemname = snd_mixer_selem_get_name(elem);
		if(snd_mixer_selem_has_playback_volume(elem))
		{
			m_channel_names = g_list_append(m_channel_names,
				(gpointer)g_strdup(elemname));
		}
		elem = snd_mixer_elem_next(elem);
	}

	// Setup m_elem using the provided channelname
	if(channel != NULL && asound_channel_exists(channel))
		asound_set_channel(channel);
	else if(m_channel_names != NULL)
		asound_set_channel((const gchar*)m_channel_names->data);
}
Пример #9
0
snd_mixer_elem_t* AlsaMixer::get_first_playback_elem()
{
    snd_mixer_elem_t* elem;
    for (elem = snd_mixer_first_elem(this->handle);
         elem;
         elem = snd_mixer_elem_next(elem))
    {
        if (snd_mixer_selem_is_active(elem) &&
            snd_mixer_selem_has_playback_volume(elem))
            return elem;
    }
}
Пример #10
0
static void set_mixer_element(snd_mixer_t *mixer,const char *name, int level,MixerAction action){
	const char *elemname;
	snd_mixer_elem_t *elem;
	long sndMixerPMin=0;
	long sndMixerPMax=0;
	long newvol=0;
	
	elem=snd_mixer_first_elem(mixer);
	
	while (elem!=NULL){
		elemname=snd_mixer_selem_get_name(elem);
		//ms_message("Found alsa mixer element %s.",elemname);
		if (strcmp(elemname,name)==0){
			switch(action){
				case CAPTURE:
				if (snd_mixer_selem_has_capture_volume(elem)){
					snd_mixer_selem_get_capture_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
					newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin;
					snd_mixer_selem_set_capture_volume_all(elem,newvol);
					//ms_message("Successfully set capture level for %s.",elemname);
					return;
				}
				break;
				case PLAYBACK:
				if (snd_mixer_selem_has_playback_volume(elem)){
					snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
					newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin;
					snd_mixer_selem_set_playback_volume_all(elem,newvol);
					//ms_message("Successfully set playback level for %s.",elemname);
					return;
				}
				break;
				case CAPTURE_SWITCH:
				if (snd_mixer_selem_has_capture_switch(elem)){
					snd_mixer_selem_set_capture_switch_all(elem,level);
					//ms_message("Successfully set capture switch for %s.",elemname);
				}
				break;
				case PLAYBACK_SWITCH:
				if (snd_mixer_selem_has_playback_switch(elem)){
					snd_mixer_selem_set_playback_switch_all(elem,level);
					//ms_message("Successfully set capture switch for %s.",elemname);
				}
				break;

			}
		}
		elem=snd_mixer_elem_next(elem);
	}

	return ;
}
Пример #11
0
snd_mixer_elem_t* AlsaMixer::get_playback_elem(const std::string name)
{
    snd_mixer_elem_t* elem;
    for (elem = snd_mixer_first_elem(this->handle);
         elem;
         elem = snd_mixer_elem_next(elem))
    {
        if (snd_mixer_selem_is_active(elem) &&
            snd_mixer_selem_has_playback_volume(elem) &&
            (name == snd_mixer_selem_get_name(elem)))
            return elem;
    }
}
Пример #12
0
int
sa_stream_set_volume_abs(sa_stream_t *s, float vol) {
  snd_mixer_t* mixer = 0;
  snd_mixer_elem_t* elem = 0;
  if (s == NULL || s->output_unit == NULL) {
    return SA_ERROR_NO_INIT;
  }

  if (snd_mixer_open(&mixer, 0) < 0) {
    return SA_ERROR_SYSTEM;
  }

  if (snd_mixer_attach(mixer, "default") < 0) {
    snd_mixer_close(mixer);
    return SA_ERROR_SYSTEM;
  }

  if (snd_mixer_selem_register(mixer, NULL, NULL) < 0) {
    snd_mixer_close(mixer);
    return SA_ERROR_SYSTEM;
  }

  if (snd_mixer_load(mixer) < 0) {
    snd_mixer_close(mixer);
    return SA_ERROR_SYSTEM;
  }

#if 0
  snd_mixer_elem_t* elem = 0;
  for (elem = snd_mixer_first_elem(mixer); elem != NULL; elem = snd_mixer_elem_next(elem)) {
    if (snd_mixer_selem_has_playback_volume(elem)) {
      printf("Playback %s\n", snd_mixer_selem_get_name(elem));
    }
    else {
      printf("No Playback: %s\n", snd_mixer_selem_get_name(elem));
    }
  }
#endif
  elem = snd_mixer_first_elem(mixer);
  if (elem && snd_mixer_selem_has_playback_volume(elem)) {
    long min = 0;
    long max = 0;
    if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) >= 0) {
      snd_mixer_selem_set_playback_volume_all(elem, (max-min)*vol + min);
    } 
  }
  snd_mixer_close(mixer);

  return SA_SUCCESS;
}
Пример #13
0
static int get_mixer_element(snd_mixer_t *mixer,const char *name, MixerAction action){
	long value=0;
	const char *elemname;
	snd_mixer_elem_t *elem;
	int err;
	long sndMixerPMin=0;
	long sndMixerPMax=0;
	long newvol=0;
	elem=snd_mixer_first_elem(mixer);
	while (elem!=NULL){
		elemname=snd_mixer_selem_get_name(elem);
		//ms_message("Found alsa mixer element %s.",elemname);
		if (strcmp(elemname,name)==0){
			switch (action){
				case CAPTURE:
				if (snd_mixer_selem_has_capture_volume(elem)){
					snd_mixer_selem_get_capture_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
					err=snd_mixer_selem_get_capture_volume(elem,SND_MIXER_SCHN_UNKNOWN,&newvol);
					newvol-=sndMixerPMin;
					value=(100*newvol)/(sndMixerPMax-sndMixerPMin);
					if (err<0) ms_warning("Could not get capture volume for %s:%s",name,snd_strerror(err));
					//else ms_message("Successfully get capture level for %s.",elemname);
					break;
				}
				break;
				case PLAYBACK:
				if (snd_mixer_selem_has_playback_volume(elem)){
					snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax);
					err=snd_mixer_selem_get_playback_volume(elem,SND_MIXER_SCHN_FRONT_LEFT,&newvol);
					newvol-=sndMixerPMin;
					value=(100*newvol)/(sndMixerPMax-sndMixerPMin);
					if (err<0) ms_warning("Could not get playback volume for %s:%s",name,snd_strerror(err));
					//else ms_message("Successfully get playback level for %s.",elemname);
					break;
				}
				break;
				case CAPTURE_SWITCH:
				
				break;
				case PLAYBACK_SWITCH:

				break;
			}
		}
		elem=snd_mixer_elem_next(elem);
	}
	
	return value;
}
Пример #14
0
/*
 * The purpose of this function is to let the user to select 
 *   the input where he plugged his signals.
 * Now if user select "default", as device, we have to select the input
 *   on the mixer of the card used by  "default".
 * What is the card used by device  "default" ?
 */ 
static void
as_setup_input_combo (GtkWidget *combo, SoundParams *sparams)
{
   snd_mixer_t *handle;
   int i ;
   snd_mixer_selem_id_t *sid;
   snd_mixer_elem_t *elem;
   snd_mixer_selem_id_alloca(&sid);
   char *devname;
   char name[32];

   devname = sparams->device_name;
   if ( *sparams->indexstr == '-' ) {
      sprintf(name, "hw:%d", sparams->firstcard);
      devname = name;
   }
   handle = sound_open_mixer(devname);
   if ( handle == NULL ){
      return ;
   }   

   for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) {
      snd_mixer_selem_get_id(elem, sid);
      if (! snd_mixer_selem_is_active(elem)) {
	 continue;
      }
      const char *control_name = snd_mixer_selem_id_get_name(sid);
//      printf("Simple mixer control '%s',%i\n", control_name,  snd_mixer_selem_id_get_index(sid));
      if (snd_mixer_selem_is_enum_capture(elem)) {
	 int items;
	 char itemname[40];
	 app_free(sparams->control_name);
	 sparams->control_name = app_strdup(control_name);
	 items = snd_mixer_selem_get_enum_items(elem);
//	 printf("  Items:");
	 for (i = 0; i < items; i++) {
	    snd_mixer_selem_get_enum_item_name(elem, i, sizeof(itemname) - 1, itemname);
//	    printf(" '%s'", itemname);
            gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), itemname );
	    if ( i == sparams->input ) {
	       gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i);
	    }
	 }
//	 printf("\n");
      }
   }
   snd_mixer_close(handle);
   return ;
}
Пример #15
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;
}
Пример #16
0
void list_mixers(const char *output_device) {
	int err;
	snd_mixer_t *handle;
	snd_mixer_selem_id_t *sid;
	snd_mixer_elem_t *elem;
	char *ctl = ctl4device(output_device);
	snd_mixer_selem_id_alloca(&sid);

	LOG_INFO("listing mixers for: %s", output_device);

	if ((err = snd_mixer_open(&handle, 0)) < 0) {
		LOG_ERROR("open error: %s", snd_strerror(err));
		return;
	}
	if ((err = snd_mixer_attach(handle, ctl)) < 0) {
		LOG_ERROR("attach error: %s", snd_strerror(err));
		snd_mixer_close(handle);
		free(ctl);
		return;
	}
	free(ctl);
	if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
		LOG_ERROR("register error: %s", snd_strerror(err));
		snd_mixer_close(handle);
		return;
	}
	if ((err = snd_mixer_load(handle)) < 0) {
		LOG_ERROR("load error: %s", snd_strerror(err));
		snd_mixer_close(handle);
		return;
	}

	printf("Volume controls for %s\n", output_device);
	for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) {
		if (snd_mixer_selem_has_playback_volume(elem)) {
			snd_mixer_selem_get_id(elem, sid);
			printf("   %s", snd_mixer_selem_id_get_name(sid));
			if (snd_mixer_selem_id_get_index(sid)) {
				printf(",%d", snd_mixer_selem_id_get_index(sid));
			}
			printf("\n");
		}
	}
	printf("\n");

	snd_mixer_close(handle);
}
Пример #17
0
void SoundPref::getMixerDevices(int mode)
{
	snd_mixer_t *mixer;
	QComboBox *cmb;
	if (mode == modePlayback)
		cmb = ui.playbackMixerDeviceCmb;
	else {
		// TODO : capture mixer devices
	}
	cmb->clear();

	int err;
	if ((err = snd->getMixer(&mixer, mixerCard)) < 0) {
		return;
	}

	snd_mixer_elem_t *elem;
	snd_mixer_selem_id_t *sid;
	snd_mixer_selem_id_alloca(&sid);
	int indx = 0;
	int current = -1;

	cmb->addItem("");

	for (elem = snd_mixer_first_elem(mixer); elem; elem = snd_mixer_elem_next(elem)) {
		snd_mixer_selem_get_id(elem, sid);
		if (!snd_mixer_selem_is_active(elem))
			continue;
		QString device = snd_mixer_selem_id_get_name(sid);
		if (mode == modePlayback) {
			if (snd_mixer_selem_has_playback_volume(elem))
				cmb->addItem(device);
		} else if (mode == modeCapture) {
			// TODO:
		} else
			continue;
		if (device == mixerDevice) {
			current = indx;
		}
		indx ++;
	}
	if (current >= 0)
		cmb->setCurrentIndex(current+1);
	
	snd_mixer_close(mixer);
}
Пример #18
0
static snd_mixer_elem_t*
find_playback_mixer_element(snd_mixer_t *mixer, const char *name)
{
    snd_mixer_elem_t *mixer_elem;

    for (mixer_elem = snd_mixer_first_elem(mixer);
         mixer_elem != NULL;
         mixer_elem = snd_mixer_elem_next(mixer_elem)) {
        const char *elem_name = snd_mixer_selem_get_name(mixer_elem);
        if ((elem_name != NULL) &&
            snd_mixer_selem_has_playback_volume(mixer_elem) &&
            (!strcmp(name, elem_name))) {
            return mixer_elem;
        }
    }

    return NULL;
}
INT32 PORT_GetPortCount(void* id) {
    PortMixer* portMixer;
    snd_mixer_elem_t *elem;

    TRACE0("> PORT_GetPortCount\n");
    if (id == NULL) {
        // $$mp: Should become a descriptive error code (invalid handle).
        return -1;
    }
    portMixer = (PortMixer*) id;
    if (portMixer->numElems == 0) {
        for (elem = snd_mixer_first_elem(portMixer->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {
            if (!snd_mixer_selem_is_active(elem))
                continue;
            TRACE2("Simple mixer control '%s',%i\n",
                   snd_mixer_selem_get_name(elem),
                   snd_mixer_selem_get_index(elem));
            if (snd_mixer_selem_has_playback_volume(elem)) {
                portMixer->elems[portMixer->numElems] = elem;
                portMixer->types[portMixer->numElems] = PORT_DST_UNKNOWN;
                portMixer->numElems++;
            }
            // to prevent buffer overflow
            if (portMixer->numElems >= MAX_ELEMS) {
                break;
            }
            /* If an element has both playback an capture volume, it is put into the arrays
               twice. */
            if (snd_mixer_selem_has_capture_volume(elem)) {
                portMixer->elems[portMixer->numElems] = elem;
                portMixer->types[portMixer->numElems] = PORT_SRC_UNKNOWN;
                portMixer->numElems++;
            }
            // to prevent buffer overflow
            if (portMixer->numElems >= MAX_ELEMS) {
                break;
            }
        }
    }
    TRACE0("< PORT_GetPortCount\n");
    return portMixer->numElems;
}
Пример #20
0
int init_alsa_volume_control(char *name)
{
	snd_mixer_open(&mixer,0);
	snd_mixer_attach(mixer,name);
	snd_mixer_selem_register(mixer,NULL,NULL);
	snd_mixer_load(mixer);

	mixerelem = snd_mixer_first_elem(mixer);

	while (mixerelem) {
		/* It should work on most of the systems. Tested on Debian, Fedora, Gentoo, Ubuntu, RedHat, CentOS */
		if (strcasecmp(snd_mixer_selem_get_name(mixerelem), "Master") == 0) {
			snd_mixer_selem_get_playback_volume_range(mixerelem,&volume_min,&volume_max);
			return 0;
		}
		mixerelem = snd_mixer_elem_next(mixerelem);
	}

 return 1;
}
Пример #21
0
void lamixer_mixer_init(char card[64])
{
	snd_mixer_elem_t *elem;
	gint err;
	
	snd_mixer_selem_id_alloca(&sid);

	err = snd_mixer_open (&mixer_handle, 0);
	err = snd_mixer_attach (mixer_handle, card);
	err = snd_mixer_selem_register (mixer_handle, NULL, NULL);
	err = snd_mixer_load (mixer_handle);
	
	for (elem = snd_mixer_first_elem(mixer_handle); elem; elem = snd_mixer_elem_next(elem)) {
		snd_mixer_selem_get_id(elem, sid);

		if (!snd_mixer_selem_is_active(elem))
			continue;

		VolumeBoxes = g_list_append(VolumeBoxes, lamixer_volelem_new(elem));
	}
}
void set_state(char *elem_name, int state)
{
  snd_mixer_elem_t *elem; 
  for ( elem = snd_mixer_first_elem( mixerFd); elem; elem = snd_mixer_elem_next( elem) ) {

      printf("want %s, found %s\n",
          elem_name, 
          snd_mixer_selem_get_name( elem)

      );

      if (elem_name && strcmp(elem_name,snd_mixer_selem_get_name( elem)))
        continue;

      snd_mixer_selem_set_playback_switch_all(elem, state);


  }


}
Пример #23
0
void NeoControl::updateMixer()
{
    if(screen != ScreenMixer)
    {
        return;
    }
    if(slider4->sliding || slider5->sliding)
    {
        QTimer::singleShot(100, this, SLOT(updateMixer()));
        return;
    }

    snd_mixer_elem_t *elem;
    snd_mixer_elem_t *elem4 = NULL;
    snd_mixer_elem_t *elem5 = NULL;

    for (elem = snd_mixer_first_elem(mixerFd); elem;
            elem = snd_mixer_elem_next(elem)) {
        QString elemName = QString(snd_mixer_selem_get_name(elem));

        if(elemName == "Speaker")
        {
            elem4 = elem;
        }
        else if(elemName == "Mono Playback")
        {
            elem5 = elem;
        }
    }

    slider4->setMixerElem(elem4, true);
    slider5->setMixerElem(elem5, true);

    label4->setText(tr("Playback (control.4) %1").arg(slider4->volume));        // Mono Playback Volume
    label5->setText(tr("Microphone (control.5) %1").arg(slider5->volume));      // Mono Sidetone Playback Volume

    label->setText(tr("Call volume settings"));

    QTimer::singleShot(1000, this, SLOT(updateMixer()));
}
Пример #24
0
/**
 * Get all playable channels for a single alsa card and
 * return them as a GSList.
 *
 * @param card HCTL name of the alsa card
 * @return the GSList of channels
 */
static GSList *
get_channels(const char *card)
{
    int ccount, i;
    snd_mixer_t *mixer;
    snd_mixer_elem_t *telem;
    GSList *channels = NULL;

    mixer = open_mixer(card, NULL, 0);
    if (mixer == NULL)
        return NULL;

    ccount = snd_mixer_get_count(mixer);
    telem = snd_mixer_first_elem(mixer);

    for (i = 0; i < ccount; i++) {
        if (snd_mixer_selem_has_playback_volume(telem))
            channels = g_slist_append(channels,
                                      strdup(snd_mixer_selem_get_name(telem)));
        telem = snd_mixer_elem_next(telem);
    }

#ifdef DEBUG
    GSList *tmp = channels;
    if (tmp) {
        printf("Card %s: available channels\n", card);
        while (tmp) {
            printf("\t%s\n", (char *) tmp->data);
            tmp = tmp->next;
        }
    } else {
        printf("Card %s: no playable channels\n", card);
    }
#endif

    close_mixer(mixer, card);

    return channels;
}
Пример #25
0
static void get_mixer_name(struct alsa_factory *af)
{
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;

    if (snd_mixer_open(&handle, 0) < 0)
	return;

    if (snd_mixer_attach(handle, "default") < 0) {
	snd_mixer_close(handle);
	return;
    }

    if (snd_mixer_selem_register(handle, NULL, NULL) < 0) {
	snd_mixer_close(handle);
	return;
    }

    if (snd_mixer_load(handle) < 0) {
	snd_mixer_close(handle);
	return;
    }

    for (elem = snd_mixer_first_elem(handle); elem;
	 elem = snd_mixer_elem_next(elem))
    {
	if (snd_mixer_selem_is_active(elem) &&
	    snd_mixer_selem_has_playback_volume(elem))
	{
	    pj_ansi_strncpy(af->pb_mixer_name, snd_mixer_selem_get_name(elem),
	    		    sizeof(af->pb_mixer_name));
	    TRACE_((THIS_FILE, "Playback mixer name: %s", af->pb_mixer_name));
	    break;
	}
    }
    snd_mixer_close(handle);
}
Пример #26
0
/* openmoko_mixer_open */
static int _openmoko_mixer_open(Openmoko * openmoko)
{
#ifdef __linux__
	PhonePluginHelper * helper = openmoko->helper;
	char const * audio_device;
	snd_mixer_elem_t * elem;

	openmoko->mixer_elem = NULL;
	openmoko->mixer_elem_headphone = NULL;
	openmoko->mixer_elem_speaker = NULL;
	if((audio_device = helper->config_get(helper->phone, "openmoko",
					"audio_device")) == NULL)
		audio_device = "hw:0";
	if(snd_mixer_open(&openmoko->mixer, 0) != 0)
	{
		openmoko->mixer = NULL;
		return -1;
	}
	if(snd_mixer_attach(openmoko->mixer, audio_device) != 0
			|| snd_mixer_selem_register(openmoko->mixer, NULL, NULL)
			|| snd_mixer_load(openmoko->mixer) != 0)
	{
		_openmoko_mixer_close(openmoko);
		return -1;
	}
	for(elem = snd_mixer_first_elem(openmoko->mixer); elem != NULL;
			elem = snd_mixer_elem_next(elem))
		if(strcmp(snd_mixer_selem_get_name(elem), "Headphone") == 0
				&& snd_mixer_selem_has_playback_volume(elem))
			openmoko->mixer_elem_headphone = elem;
		else if(strcmp(snd_mixer_selem_get_name(elem), "Speaker") == 0
				&& snd_mixer_selem_has_playback_volume(elem))
			openmoko->mixer_elem_speaker = elem;
#endif /* __linux__ */
	return 0;
}
ALSAMixer::ALSAMixer()
{
    int err;

    initMixer (&mMixer[SND_PCM_STREAM_PLAYBACK], "AndroidOut");
    initMixer (&mMixer[SND_PCM_STREAM_CAPTURE], "AndroidIn");

    snd_mixer_selem_id_t *sid;
    snd_mixer_selem_id_alloca(&sid);

    for (int i = 0; i <= SND_PCM_STREAM_LAST; i++) {

        if (!mMixer[i]) continue;

        mixer_info_t *info = mixerMasterProp[i].mInfo = new mixer_info_t;

        property_get (mixerMasterProp[i].propName,
                      info->name,
                      mixerMasterProp[i].propDefault);

        for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]);
             elem;
             elem = snd_mixer_elem_next(elem)) {

            if (!snd_mixer_selem_is_active(elem))
                continue;

            snd_mixer_selem_get_id(elem, sid);

            // Find PCM playback volume control element.
            const char *elementName = snd_mixer_selem_id_get_name(sid);

            if (info->elem == NULL &&
                strcmp(elementName, info->name) == 0 &&
                hasVolume[i] (elem)) {

                info->elem = elem;
                getVolumeRange[i] (elem, &info->min, &info->max);
                //info->volume = info->max;
                //setVol[i] (elem, info->volume);
                //if (i == SND_PCM_STREAM_PLAYBACK &&
                //    snd_mixer_selem_has_playback_switch (elem))
                //    snd_mixer_selem_set_playback_switch_all (elem, 1);
                break;
            }
        }

        ALOGV("Mixer: master '%s' %s.", info->name, info->elem ? "found" : "not found");

        for (int j = 0; mixerProp[j][i].device; j++) {

            mixer_info_t *info = mixerProp[j][i].mInfo = new mixer_info_t;

            property_get (mixerProp[j][i].propName,
                          info->name,
                          mixerProp[j][i].propDefault);

            for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]);
                 elem;
                 elem = snd_mixer_elem_next(elem)) {

                if (!snd_mixer_selem_is_active(elem))
                    continue;

                snd_mixer_selem_get_id(elem, sid);

                // Find PCM playback volume control element.
                const char *elementName = snd_mixer_selem_id_get_name(sid);

               if (info->elem == NULL &&
                    strcmp(elementName, info->name) == 0 &&
                    hasVolume[i] (elem)) {

                    info->elem = elem;
                    getVolumeRange[i] (elem, &info->min, &info->max);
                    //info->volume = info->max;
                    //setVol[i] (elem, info->volume);
                    //if (i == SND_PCM_STREAM_PLAYBACK &&
                    //    snd_mixer_selem_has_playback_switch (elem))
                    //    snd_mixer_selem_set_playback_switch_all (elem, 1);
                    break;
                }
            }
            ALOGV("Mixer: route '%s' %s.", info->name, info->elem ? "found" : "not found");
        }
    }
    ALOGV("mixer initialized.");
}
Пример #28
0
static void
alsa_configure (struct sound_device *sd)
{
  int val, err, dir;
  unsigned uval;
  struct alsa_params *p = (struct alsa_params *) sd->data;
  snd_pcm_uframes_t buffer_size;

  xassert (p->handle != 0);

  err = snd_pcm_hw_params_malloc (&p->hwparams);
  if (err < 0)
    alsa_sound_perror ("Could not allocate hardware parameter structure", err);

  err = snd_pcm_sw_params_malloc (&p->swparams);
  if (err < 0)
    alsa_sound_perror ("Could not allocate software parameter structure", err);

  err = snd_pcm_hw_params_any (p->handle, p->hwparams);
  if (err < 0)
    alsa_sound_perror ("Could not initialize hardware parameter structure", err);

  err = snd_pcm_hw_params_set_access (p->handle, p->hwparams,
                                      SND_PCM_ACCESS_RW_INTERLEAVED);
  if (err < 0)
    alsa_sound_perror ("Could not set access type", err);

  val = sd->format;
  err = snd_pcm_hw_params_set_format (p->handle, p->hwparams, val);
  if (err < 0)
    alsa_sound_perror ("Could not set sound format", err);

  uval = sd->sample_rate;
  err = snd_pcm_hw_params_set_rate_near (p->handle, p->hwparams, &uval, 0);
  if (err < 0)
    alsa_sound_perror ("Could not set sample rate", err);

  val = sd->channels;
  err = snd_pcm_hw_params_set_channels (p->handle, p->hwparams, val);
  if (err < 0)
    alsa_sound_perror ("Could not set channel count", err);

  err = snd_pcm_hw_params (p->handle, p->hwparams);
  if (err < 0)
    alsa_sound_perror ("Could not set parameters", err);


  err = snd_pcm_hw_params_get_period_size (p->hwparams, &p->period_size, &dir);
  if (err < 0)
    alsa_sound_perror ("Unable to get period size for playback", err);

  err = snd_pcm_hw_params_get_buffer_size (p->hwparams, &buffer_size);
  if (err < 0)
    alsa_sound_perror("Unable to get buffer size for playback", err);

  err = snd_pcm_sw_params_current (p->handle, p->swparams);
  if (err < 0)
    alsa_sound_perror ("Unable to determine current swparams for playback",
                       err);

  /* Start the transfer when the buffer is almost full */
  err = snd_pcm_sw_params_set_start_threshold (p->handle, p->swparams,
                                               (buffer_size / p->period_size)
                                               * p->period_size);
  if (err < 0)
    alsa_sound_perror ("Unable to set start threshold mode for playback", err);

  /* Allow the transfer when at least period_size samples can be processed */
  err = snd_pcm_sw_params_set_avail_min (p->handle, p->swparams, p->period_size);
  if (err < 0)
    alsa_sound_perror ("Unable to set avail min for playback", err);

  err = snd_pcm_sw_params (p->handle, p->swparams);
  if (err < 0)
    alsa_sound_perror ("Unable to set sw params for playback\n", err);

  snd_pcm_hw_params_free (p->hwparams);
  p->hwparams = NULL;
  snd_pcm_sw_params_free (p->swparams);
  p->swparams = NULL;

  err = snd_pcm_prepare (p->handle);
  if (err < 0)
    alsa_sound_perror ("Could not prepare audio interface for use", err);

  if (sd->volume > 0)
    {
      int chn;
      snd_mixer_t *handle;
      snd_mixer_elem_t *e;
      const char *file = sd->file ? sd->file : DEFAULT_ALSA_SOUND_DEVICE;

      if (snd_mixer_open (&handle, 0) >= 0)
        {
          if (snd_mixer_attach (handle, file) >= 0
              && snd_mixer_load (handle) >= 0
              && snd_mixer_selem_register (handle, NULL, NULL) >= 0)
            for (e = snd_mixer_first_elem (handle);
                 e;
                 e = snd_mixer_elem_next (e))
              {
                if (snd_mixer_selem_has_playback_volume (e))
                  {
                    long pmin, pmax, vol;
                    snd_mixer_selem_get_playback_volume_range (e, &pmin, &pmax);
                    vol = pmin + (sd->volume * (pmax - pmin)) / 100;

                    for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++)
                      snd_mixer_selem_set_playback_volume (e, chn, vol);
                  }
              }
          snd_mixer_close(handle);
        }
    }
}
Пример #29
0
static void
gst_alsa_mixer_ensure_track_list (GstAlsaMixer * mixer)
{
  gint i, count;
  snd_mixer_elem_t *element, *master;
  GList *item;

  g_return_if_fail (mixer->handle != NULL);

  if (mixer->tracklist)
    return;

  g_static_rec_mutex_lock (mixer->rec_mutex);

  master = gst_alsa_mixer_find_master_mixer (mixer, mixer->handle);

  count = snd_mixer_get_count (mixer->handle);
  element = snd_mixer_first_elem (mixer->handle);

  /* build track list
   *
   * Some ALSA tracks may have playback and capture capabilities.
   * Here we model them as two separate GStreamer tracks.
   */

  for (i = 0; i < count; i++) {
    GstMixerTrack *play_track = NULL;
    GstMixerTrack *cap_track = NULL;
    const gchar *name;
    GList *item;
    gint samename = 0;

    name = snd_mixer_selem_get_name (element);

    /* prevent dup names */
    for (item = mixer->tracklist; item != NULL; item = item->next) {
      snd_mixer_elem_t *temp;

      if (GST_IS_ALSA_MIXER_OPTIONS (item->data))
        temp = GST_ALSA_MIXER_OPTIONS (item->data)->element;
      else
        temp = GST_ALSA_MIXER_TRACK (item->data)->element;

      if (strcmp (name, snd_mixer_selem_get_name (temp)) == 0)
        samename++;
    }

    GST_LOG ("[%s] probing element #%u, mixer->dir=%u", name, i, mixer->dir);

    if (mixer->dir & GST_ALSA_MIXER_PLAYBACK) {
      gboolean has_playback_switch, has_playback_volume;

      has_playback_switch = snd_mixer_selem_has_playback_switch (element);
      has_playback_volume = snd_mixer_selem_has_playback_volume (element);

      GST_LOG ("[%s] PLAYBACK: has_playback_volume=%d, has_playback_switch=%d"
          "%s", name, has_playback_volume, has_playback_switch,
          (element == master) ? " MASTER" : "");

      if (has_playback_volume) {
        gint flags = GST_MIXER_TRACK_OUTPUT;

        if (element == master)
          flags |= GST_MIXER_TRACK_MASTER;

        play_track = gst_alsa_mixer_track_new (element, samename, i,
            flags, FALSE, NULL, FALSE);

      } else if (has_playback_switch) {
        /* simple mute switch */
        play_track = gst_alsa_mixer_track_new (element, samename, i,
            GST_MIXER_TRACK_OUTPUT, TRUE, NULL, FALSE);
      }

      if (snd_mixer_selem_is_enumerated (element)) {
        GstMixerOptions *opts = gst_alsa_mixer_options_new (element, i);

        GST_LOG ("[%s] is enumerated (%d)", name, i);
        mixer->tracklist = g_list_append (mixer->tracklist, opts);
      }
    }

    if (mixer->dir & GST_ALSA_MIXER_CAPTURE) {
      gboolean has_capture_switch, has_common_switch;
      gboolean has_capture_volume, has_common_volume;

      has_capture_switch = snd_mixer_selem_has_capture_switch (element);
      has_common_switch = snd_mixer_selem_has_common_switch (element);
      has_capture_volume = snd_mixer_selem_has_capture_volume (element);
      has_common_volume = snd_mixer_selem_has_common_volume (element);

      GST_LOG ("[%s] CAPTURE: has_capture_volume=%d, has_common_volume=%d, "
          "has_capture_switch=%d, has_common_switch=%d, play_track=%p", name,
          has_capture_volume, has_common_volume, has_capture_switch,
          has_common_switch, play_track);

      if (has_capture_volume && !(play_track && has_common_volume)) {
        cap_track = gst_alsa_mixer_track_new (element, samename, i,
            GST_MIXER_TRACK_INPUT, FALSE, NULL, play_track != NULL);
      } else if (has_capture_switch && !(play_track && has_common_switch)) {
        cap_track = gst_alsa_mixer_track_new (element, samename, i,
            GST_MIXER_TRACK_INPUT, TRUE, NULL, play_track != NULL);
      }
    }


    if (play_track && cap_track) {
      GST_ALSA_MIXER_TRACK (play_track)->shared_mute =
          GST_ALSA_MIXER_TRACK (cap_track);
      GST_ALSA_MIXER_TRACK (cap_track)->shared_mute =
          GST_ALSA_MIXER_TRACK (play_track);
    }

    if (play_track)
      mixer->tracklist = g_list_append (mixer->tracklist, play_track);

    if (cap_track)
      mixer->tracklist = g_list_append (mixer->tracklist, cap_track);

    element = snd_mixer_elem_next (element);
  }

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

    if (GST_IS_ALSA_MIXER_OPTIONS (item->data))
      temp = GST_ALSA_MIXER_OPTIONS (item->data)->element;
    else
      temp = GST_ALSA_MIXER_TRACK (item->data)->element;

    snd_mixer_elem_set_callback (temp, gst_alsa_mixer_elem_handle_callback);
    snd_mixer_elem_set_callback_private (temp, mixer);
  }

  g_static_rec_mutex_unlock (mixer->rec_mutex);
}
Пример #30
0
static int open_mixer(PxDev *dev, int card, int playback)
{
   snd_mixer_elem_t *elem;
   char name[256];
   int err;
   int i;

   sprintf(name, "hw:%d", card);

   dev->card = card;
   dev->handle = NULL;

   do {
      err = snd_mixer_open(&dev->handle, 0);
      if (err < 0) {
         break;
      }

      err = snd_mixer_attach(dev->handle, name);
      if (err < 0) {
         break;
      }

      err = snd_mixer_selem_register(dev->handle, NULL, NULL);
      if (err < 0) {
         break;
      }

      err = snd_mixer_load(dev->handle);
      if (err < 0) {
         break;
      }

      for (elem = snd_mixer_first_elem(dev->handle);
           elem != NULL;
           elem = snd_mixer_elem_next(elem))
      {
         if (!playback) {
            if (!snd_mixer_selem_has_capture_volume(elem) &&
                !snd_mixer_selem_has_capture_switch(elem) &&
                !snd_mixer_selem_has_common_volume(elem)) {
               continue;
            }
         }
         else {
            if (!snd_mixer_selem_has_playback_volume(elem) &&
                !snd_mixer_selem_has_playback_switch(elem) &&
                !snd_mixer_selem_has_common_volume(elem)) {
               continue;
            }
         }
         dev->numselems++;
      }

      dev->selems = calloc(dev->numselems, sizeof(PxSelem));
      if (dev->selems == NULL) {
         break;
      }

      i = 0;
      for (elem = snd_mixer_first_elem(dev->handle);
           elem != NULL;
           elem = snd_mixer_elem_next(elem))
      {
         if (!playback) {
            if (!snd_mixer_selem_has_capture_volume(elem) &&
                !snd_mixer_selem_has_capture_switch(elem) &&
                !snd_mixer_selem_has_common_volume(elem)) {
               continue;
            }
         }
         else {
            if (!snd_mixer_selem_has_playback_volume(elem) &&
                !snd_mixer_selem_has_playback_switch(elem) &&
                !snd_mixer_selem_has_common_volume(elem)) {
               continue;
            }
         }
               
         if (snd_mixer_selem_id_malloc(&dev->selems[i].sid) < 0) {
            break;
         }

         snd_mixer_selem_get_id(elem, dev->selems[i].sid);
         dev->selems[i].elem = elem;

         snprintf(name,
                  sizeof(name),
                  "%s:%d",
                  snd_mixer_selem_id_get_name(dev->selems[i].sid),
                  snd_mixer_selem_id_get_index(dev->selems[i].sid));

         dev->selems[i].name = strdup(name);
         if (!dev->selems[i].name) {
            break;
         }
         i++;
      }

      if (i == dev->numselems) {
         return TRUE;
      }

   } while (FALSE);

   if (dev->selems) {
      for (i = 0; i < dev->numselems; i++) {
         if (dev->selems[i].sid) {
            snd_mixer_selem_id_free(dev->selems[i].sid);
         }
         if (dev->selems[i].name) {
            free(dev->selems[i].name);
         }
      }
      free(dev->selems);
      dev->selems = NULL;
   }

   if (dev->handle) {
      snd_mixer_close(dev->handle);
      dev->handle = NULL;
   }

   return FALSE;
}