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; }
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); } } }
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 }
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; }
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; }
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); }
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; }
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); }
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; } }
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 ; }
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; } }
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; }
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; }
/* * 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 ; }
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; }
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); }
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); }
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; }
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; }
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); } }
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())); }
/** * 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; }
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); }
/* 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."); }
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); } } }
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); }
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; }