static MSSndCard * alsa_card_new(int id) { MSSndCard * obj; char *name=NULL; AlsaData *ad; int err; if (id!=-1){ err=snd_card_get_name(id,&name); if (err<0) { return NULL; } } obj=ms_snd_card_new(&alsa_card_desc); ad=(AlsaData*)obj->data; if (id==-1) { /* the default pcm device */ obj->name=ms_strdup("default device"); ad->pcmdev=ms_strdup("default"); ad->mixdev=ms_strdup("default"); }else{ /* remove trailing spaces from card name */ char *pos1, *pos2; pos1=ms_strdup(name); pos2=pos1+strlen(pos1)-1; for (; pos2>pos1 && *pos2==' '; pos2--) *pos2='\0'; obj->name=pos1; ad->pcmdev=ms_strdup_printf("default:%i",id); ad->mixdev=ms_strdup_printf("default:%i",id); { snd_mixer_t *mixer; mixer = alsa_mixer_open(ad->mixdev); if (mixer==NULL) { ms_free(ad->mixdev); ad->mixdev=ms_strdup_printf("hw:%i",id); } else { alsa_mixer_close(mixer); } } } /*check card capabilities: */ obj->capabilities=get_card_capabilities(ad->pcmdev); if (obj->capabilities==0){ ms_warning("Strange, sound card %s does not seems to be capable of anything, retrying with plughw...",obj->name); /*retry with plughw: this workarounds an alsa bug*/ ms_free(ad->pcmdev); ad->pcmdev=ms_strdup_printf("plughw:%i",id); obj->capabilities=get_card_capabilities(ad->pcmdev); if (obj->capabilities==0){ ms_warning("Strange, sound card %s seems totally unusable.",obj->name); } } free(name); /*ms_message("alsa device %s found",obj->name);*/ return obj; }
static void alsa_card_set_source(MSSndCard *obj,MSSndCardCapture source) { snd_mixer_t *mixer; AlsaData *ad=(AlsaData*)obj->data; mixer=alsa_mixer_open(ad->mixdev); if (mixer==NULL) return; switch (source){ case MS_SND_CARD_MIC: set_mixer_element(mixer,"Mic",1,CAPTURE_SWITCH); set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH); break; case MS_SND_CARD_LINE: set_mixer_element(mixer,"Line",1,CAPTURE_SWITCH); set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH); break; } alsa_mixer_close(mixer); }
static void alsa_card_set_level(MSSndCard *obj,MSSndCardMixerElem e,int a) { snd_mixer_t *mixer; AlsaData *ad=(AlsaData*)obj->data; mixer=alsa_mixer_open(ad->mixdev); if (mixer==NULL) return ; switch(e){ case MS_SND_CARD_MASTER: set_mixer_element(mixer,"Master",a,PLAYBACK); break; case MS_SND_CARD_CAPTURE: set_mixer_element(mixer,"Capture",a,CAPTURE); break; case MS_SND_CARD_PLAYBACK: set_mixer_element(mixer,"PCM",a,PLAYBACK); break; default: ms_warning("alsa_card_set_level: unsupported command."); } alsa_mixer_close(mixer); }
static bool alsa_mixer_open(struct mixer *data, GError **error_r) { struct alsa_mixer *am = (struct alsa_mixer *)data; int err; snd_mixer_elem_t *elem; am->volume_set = -1; err = snd_mixer_open(&am->handle, 0); if (err < 0) { g_set_error(error_r, alsa_mixer_quark(), err, "snd_mixer_open() failed: %s", snd_strerror(err)); return false; } if ((err = snd_mixer_attach(am->handle, am->device)) < 0) { alsa_mixer_close(data); g_set_error(error_r, alsa_mixer_quark(), err, "failed to attach to %s: %s", am->device, snd_strerror(err)); return false; } if ((err = snd_mixer_selem_register(am->handle, NULL, NULL)) < 0) { alsa_mixer_close(data); g_set_error(error_r, alsa_mixer_quark(), err, "snd_mixer_selem_register() failed: %s", snd_strerror(err)); return false; } if ((err = snd_mixer_load(am->handle)) < 0) { alsa_mixer_close(data); g_set_error(error_r, alsa_mixer_quark(), err, "snd_mixer_load() failed: %s\n", snd_strerror(err)); return false; } elem = snd_mixer_first_elem(am->handle); while (elem) { if (snd_mixer_elem_get_type(elem) == SND_MIXER_ELEM_SIMPLE) { if ((g_ascii_strcasecmp(am->control, snd_mixer_selem_get_name(elem)) == 0) && (am->index == snd_mixer_selem_get_index(elem))) { break; } } elem = snd_mixer_elem_next(elem); } if (elem) { am->elem = elem; snd_mixer_selem_get_playback_volume_range(am->elem, &am->volume_min, &am->volume_max); return true; } alsa_mixer_close(data); g_set_error(error_r, alsa_mixer_quark(), 0, "no such mixer control: %s", am->control); return false; }