void alsa_volume(const Arg *a) { long vol = a->i; snd_mixer_handle_events(alsa.handle); vol += volume_get(); volume_set(vol); }
static void handle_mixer_events (snd_mixer_t *mixer_handle) { int count; if ((count = snd_mixer_poll_descriptors_count(mixer_handle)) < 0) logit ("snd_mixer_poll_descriptors_count() failed: %s", snd_strerror(count)); else { struct pollfd *fds; int err; fds = xcalloc (count, sizeof(struct pollfd)); if ((err = snd_mixer_poll_descriptors(mixer_handle, fds, count)) < 0) logit ("snd_mixer_poll_descriptors() failed: %s", snd_strerror(count)); else { err = poll (fds, count, 0); if (err < 0) error ("poll() failed: %s", strerror(errno)); else if (err > 0) { debug ("Mixer event"); if ((err = snd_mixer_handle_events(mixer_handle) ) < 0) logit ("snd_mixer_handle_events() " "failed: %s", snd_strerror(err)); } } free (fds); } }
static void laudio_alsa_set_volume(int vol) { int pcm_vol; if (!mixer_hdl || !vol_elem) return; snd_mixer_handle_events(mixer_hdl); if (!snd_mixer_selem_is_active(vol_elem)) return; switch (vol) { case 0: pcm_vol = vol_min; break; case 100: pcm_vol = vol_max; break; default: pcm_vol = vol_min + (vol * (vol_max - vol_min)) / 100; break; } DPRINTF(E_DBG, L_LAUDIO, "Setting PCM volume to %d (%d)\n", pcm_vol, vol); snd_mixer_selem_set_playback_volume_all(vol_elem, pcm_vol); }
static gboolean on_mixer_channel_event(GIOChannel *source, GIOCondition cond, gpointer data) { alsa_mixer_t *mixer = (alsa_mixer_t *)data; if(mixer->handle) snd_mixer_handle_events(mixer->handle); return TRUE; }
static gboolean asound_poll_cb(GIOChannel * source, GIOCondition condition, gpointer data) { int retval = snd_mixer_handle_events(m_mixer); if(retval < 0) { fprintf(stderr, "snd_mixer_handle_events: %s\n", snd_strerror(retval)); return FALSE; } return TRUE; }
int AlsaMixer::get_volume() { int value; long left, right; snd_mixer_handle_events(this->handle); snd_mixer_selem_get_playback_volume(this->active_elem, LEFT, &left); snd_mixer_selem_get_playback_volume(this->active_elem, RIGHT, &right); value = (int)(((left + (right - left)/2)*100) / (this->max - this->min)); return value; }
void LapsusAlsaMixer::alsaEvent() { if (!_fds || _count < 1) return; snd_mixer_handle_events(_handle); // Those functions will emit any signals needed getVolume(); mixerIsMuted(); }
char * get_vol(snd_mixer_t *handle, snd_mixer_elem_t *elem) { int mute = 0; long vol, max, min; snd_mixer_handle_events(handle); snd_mixer_selem_get_playback_volume_range(elem, &min, &max); snd_mixer_selem_get_playback_volume(elem, 0, &vol); snd_mixer_selem_get_playback_switch(elem, 0, &mute); return smprintf(mute == 0 ? VOL_MUTE : VOL, (vol * 100) / max); }
int AmeSystemSound::volume() { if (!mixer_element) return 0; long l, r; snd_mixer_handle_events(mixer); snd_mixer_selem_get_playback_volume(mixer_element, SND_MIXER_SCHN_FRONT_LEFT, &l); snd_mixer_selem_get_playback_volume(mixer_element, SND_MIXER_SCHN_FRONT_RIGHT, &r); return (l+r)/2; }
static int alsa_mixer_get_volume(int *l, int *r) { long lv, rv; if (mixer_elem == NULL) return -1; snd_mixer_handle_events(alsa_mixer_handle); snd_mixer_selem_get_playback_volume(mixer_elem, SND_MIXER_SCHN_FRONT_LEFT, &lv); snd_mixer_selem_get_playback_volume(mixer_elem, SND_MIXER_SCHN_FRONT_RIGHT, &rv); *l = lv - mixer_vol_min; *r = rv - mixer_vol_min; return 0; }
void AlsaMixer::unmute_volume() { if (!snd_mixer_selem_has_playback_switch(this->active_elem)) { this->set_volume(this->muted_volume); } else { snd_mixer_handle_events(this->handle); // TODO: write actual playback switch logic snd_mixer_selem_set_playback_switch(this->active_elem, LEFT, 1); snd_mixer_selem_set_playback_switch(this->active_elem, RIGHT, 1); } }
VolumeSettings VolumeALSA::volume() const { VolumeSettings vol; if(pcm_element) { long value = 0; snd_mixer_handle_events(m_mixer); snd_mixer_selem_get_playback_volume(pcm_element, SND_MIXER_SCHN_FRONT_LEFT, &value); vol.left = value; snd_mixer_selem_get_playback_volume(pcm_element, SND_MIXER_SCHN_FRONT_RIGHT, &value); vol.right = value; } return vol; }
static Eina_Bool _cb_dispatch(void *data) { struct e_mixer_callback_desc *desc; int r; desc = data; snd_mixer_handle_events(desc->self); r = desc->func(desc->data, desc->self); desc->idler = NULL; if (!r) _mixer_callback_del(desc->self, desc); /* desc is invalid then. */ return ECORE_CALLBACK_CANCEL; }
static gboolean lamixer_volbox_alsa_io(GIOChannel *chan, GIOCondition condition, gpointer data) { //FIXME: Do we realy need G_IO_ERR G_IO_HUP G_IO_NVAL ? switch(condition) { case G_IO_OUT: case G_IO_IN: case G_IO_PRI: snd_mixer_handle_events(mixer_handle); return TRUE; case G_IO_ERR: case G_IO_HUP: case G_IO_NVAL: default: g_warning("ALSA mixer polling error"); return FALSE; } }
/** * Callback function for external volume changes, * set in set_io_watch(). * * @param source the GIOChannel event source * @param condition the condition which has been satisfied * @param data user data set inb g_io_add_watch() or g_io_add_watch_full() * @return FALSE if the event source should be removed */ static gboolean poll_cb(GIOChannel *source, GIOCondition condition, gpointer data) { snd_mixer_handle_events(handle); if (condition == G_IO_ERR) { /* This happens when the file descriptor we're watching disappeared. * For example, if the USB soundcard has been unplugged. * In this case, reloading alsa is the nice thing to do, it will * cause PNMixer to select the first card available. */ do_notify_text(_("Soundcard disconnected"), _("Soundcard has been disconnected, reloading Alsa...")); g_idle_add(idle_alsa_reinit, NULL); return FALSE; } sread = 1; while (sread) { /* This handles the case where alsa_cb doesn't read all the data on * source. If we don't clear it out we'll go into an infinite * callback loop since there will be data on the channel forever. */ GIOStatus stat = g_io_channel_read_chars(source, sbuf, 256, &sread, (GError **) & serr); if (serr) { g_error_free((GError *) serr); serr = NULL; } // normal, means alsa_cb cleared out the channel if (stat == G_IO_STATUS_AGAIN) continue; // actually bad, alsa failed to clear channel else if (stat == G_IO_STATUS_NORMAL) warn_sound_conn_lost(); else if (stat == G_IO_STATUS_ERROR || stat == G_IO_STATUS_EOF) report_error("Error: GIO error has occured. Won't respond to " "external volume changes anymore."); else report_error("Error: Unknown status from " "g_io_channel_read_chars."); return TRUE; } return TRUE; }
bool AlsaMixer::get_mute() { if (snd_mixer_selem_has_playback_switch(this->active_elem)) { int muted; snd_mixer_handle_events(this->handle); // TODO: write actual playback switch logic if (snd_mixer_selem_get_playback_switch(this->active_elem, UNKN, &muted) < 0) snd_mixer_selem_get_playback_switch(this->active_elem, LEFT, &muted); return !(bool)muted; } else { return (this->get_volume() == 0 ? true : false); } }
static int gst_alsa_mixer_handle_callback (snd_mixer_t * handle, unsigned int mask, snd_mixer_elem_t * elem) { GstAlsaMixer *mixer = (GstAlsaMixer *) snd_mixer_get_callback_private (handle); GST_LOG ("ALSA cb"); g_return_val_if_fail (mixer != NULL, 1); /* Hopefully won't be call recursively and will handle pending elem events */ snd_mixer_handle_events (mixer->handle); gst_alsa_mixer_update (mixer, elem); return 0; }
/* alsa_get_mixer_volume: * Return mixer volume (0-255) */ static int alsa_get_mixer_volume(void) { if (alsa_mixer && alsa_mixer_elem) { long vol1, vol2; snd_mixer_handle_events(alsa_mixer); if (snd_mixer_selem_get_playback_volume(alsa_mixer_elem, 0, &vol1) < 0) return -1; if (snd_mixer_selem_get_playback_volume(alsa_mixer_elem, 1, &vol2) < 0) return -1; vol1 /= alsa_mixer_allegro_ratio; vol2 /= alsa_mixer_allegro_ratio; return (vol1 + vol2) / 2; } return -1; }
void indicator_music_update(Indicator *indicator) { long int i, vol; char *ic; check_bus(); snd_mixer_handle_events(alsa.handle); if(mute_get()) sprintf(indicator->text, " \uf35a %li%% ", volume_get()); else { vol = volume_get(); ic = "\uf357"; for(i = 0; i < sizeof(icon)/sizeof(Icon); i++) { if(vol < icon[i].percentage) { ic = icon[i].str; break; } } sprintf(indicator->text, " %s %li%% ", ic, vol); } }
static void task_monitor_alsa (gpointer data) { struct pollfd *pfds; unsigned int nfds, rnfds; unsigned short revents; GstAlsaMixer *mixer = (GstAlsaMixer *) data; g_static_rec_mutex_lock (mixer->rec_mutex); nfds = snd_mixer_poll_descriptors_count (mixer->handle); if (nfds <= 0) { GST_ERROR ("snd_mixer_poll_descriptors_count <= 0: %d", nfds); /* FIXME: sleep ? stop monitoring ? */ return; } pfds = g_newa (struct pollfd, nfds + 1); rnfds = snd_mixer_poll_descriptors (mixer->handle, pfds, nfds); g_assert (rnfds <= nfds); pfds[rnfds].fd = mixer->pfd[0]; pfds[rnfds].events = POLLIN | POLLPRI | POLLHUP | POLLERR; pfds[rnfds].revents = 0; g_static_rec_mutex_unlock (mixer->rec_mutex); GST_LOG ("task loop"); poll (pfds, rnfds + 1, -1); g_static_rec_mutex_lock (mixer->rec_mutex); snd_mixer_poll_descriptors_revents (mixer->handle, pfds, nfds, &revents); if (revents & POLLIN || revents & POLLPRI) { GST_DEBUG ("Handling events"); snd_mixer_handle_events (mixer->handle); } g_static_rec_mutex_unlock (mixer->rec_mutex); }
static gboolean io_func (GIOChannel *source, GIOCondition condition, MokoAlsaVolumeControl *self) { switch (condition) { case G_IO_IN : { MokoAlsaVolumeControlPrivate *priv = ALSA_VOLUME_CONTROL_PRIVATE (self); snd_mixer_handle_events (priv->mixer_handle); break; } case G_IO_ERR : case G_IO_NVAL : g_warning ("Encountered an error, stopping IO watch"); return FALSE; default : g_warning ("Unhandled IO condition"); break; } return TRUE; }
static gboolean on_mixer_event(GIOChannel* channel, GIOCondition cond, void *ud) { if (mixer_evt_idle == 0) { mixer_evt_idle = g_idle_add_full(G_PRIORITY_DEFAULT, (GSourceFunc) reset_mixer_evt_idle, NULL, NULL); snd_mixer_handle_events (mixer); } if (cond & G_IO_IN) { /* update mixer status */ update_gui(&ch[0]); update_gui(&ch[1]); } if (cond & G_IO_HUP) { /* FIXME: This means there're some problems with alsa. */ return FALSE; } return TRUE; }
static int alsa_mixer_get_volume(struct mixer *mixer, GError **error_r) { struct alsa_mixer *am = (struct alsa_mixer *)mixer; int err; int ret; long level; assert(am->handle != NULL); err = snd_mixer_handle_events(am->handle); if (err < 0) { g_set_error(error_r, alsa_mixer_quark(), err, "snd_mixer_handle_events() failed: %s", snd_strerror(err)); return false; } err = snd_mixer_selem_get_playback_volume(am->elem, SND_MIXER_SCHN_FRONT_LEFT, &level); if (err < 0) { g_set_error(error_r, alsa_mixer_quark(), err, "failed to read ALSA volume: %s", snd_strerror(err)); return false; } ret = ((am->volume_set / 100.0) * (am->volume_max - am->volume_min) + am->volume_min) + 0.5; if (am->volume_set > 0 && ret == level) { ret = am->volume_set; } else { ret = (int)(100 * (((float)(level - am->volume_min)) / (am->volume_max - am->volume_min)) + 0.5); } return ret; }
float getvolume(snd_mixer_t *handle, const char* vol_ch) { int mute = 0; long vol = 0, max = 0, min = 0; snd_mixer_elem_t *pcm_mixer, *max_mixer; snd_mixer_selem_id_t *vol_info, *mute_info; /*ToDo: maybe move all this to main?*/ snd_mixer_handle_events(handle); snd_mixer_selem_id_malloc(&vol_info); snd_mixer_selem_id_malloc(&mute_info); snd_mixer_selem_id_set_name(vol_info, vol_ch); snd_mixer_selem_id_set_name(mute_info, vol_ch); pcm_mixer = snd_mixer_find_selem(handle, vol_info); max_mixer = snd_mixer_find_selem(handle, mute_info); snd_mixer_selem_get_playback_volume_range(pcm_mixer, &min, &max); snd_mixer_selem_get_playback_volume(pcm_mixer, 0, &vol); snd_mixer_selem_get_playback_switch(max_mixer, 0, &mute); snd_mixer_selem_id_free(vol_info); snd_mixer_selem_id_free(mute_info); return ((float)vol/(float)max)*100; }
char * get_volume(void) { snd_mixer_t *handle; snd_mixer_elem_t *elem; snd_mixer_selem_id_t *s_elem; snd_mixer_open(&handle, 0); snd_mixer_attach(handle, "default"); snd_mixer_selem_register(handle, NULL, NULL); snd_mixer_load(handle); snd_mixer_selem_id_malloc(&s_elem); snd_mixer_selem_id_set_name(s_elem, "Master"); elem = snd_mixer_find_selem(handle, s_elem); if (elem == NULL) { snd_mixer_selem_id_free(s_elem); snd_mixer_close(handle); exit(EXIT_FAILURE); } long int vol, max, min, percent; snd_mixer_handle_events(handle); snd_mixer_selem_get_playback_volume_range(elem, &min, &max); snd_mixer_selem_get_playback_volume(elem, 0, &vol); percent = (vol * 100) / max; snd_mixer_selem_id_free(s_elem); snd_mixer_close(handle); return smprintf("\x05\uf028 %d",percent); }
void indicator_music_expose(Indicator *indicator, Window window) { int i; int y=0, sliderw=menu.w-10*2; struct MEDIAPLAYER *mp; if(window!=menu.window) return; snd_mixer_handle_events(alsa.handle); indicator_draw_text(menu.window, menu.gc, 0, 0, menu.w, bh, menu.selected==0?dc.sel:dc.norm, mute_get()?"Unmute":"Mute", False); XSetForeground(dpy, menu.gc, (menu.selected==1?dc.sel:dc.norm)[ColBG]); XFillRectangle(dpy, window, menu.gc, 0, bh, menu.w, bh); XSetForeground(dpy, menu.gc, (menu.selected==1?dc.sel:dc.norm)[ColFG]); XDrawLine(dpy, window, menu.gc, 8, bh+bh/2, menu.w-8, bh+bh/2); XFillRectangle(dpy, window, menu.gc, 10-2+sliderw*volume_get()/100, bh+2, 4, bh-4); for(mp=mediaplayer, y=2*bh, i=2; mp; mp=mp->next, y+=bh*5, i+=5) { struct TRACK track=mediaplayer_get_track(mp->id); enum PLAYBACK_STATUS status=mediaplayer_get_status(mp->id); indicator_draw_text(menu.window, menu.gc, 0, y, menu.w, bh, i==menu.selected?dc.sel:dc.norm, mp->name?mp->name:mp->id, False); if(status==PLAYBACK_STATUS_STOPPED) { XSetForeground(dpy, menu.gc, dc.norm[ColBG]); XFillRectangle(dpy, window, menu.gc, 0, y+bh, menu.w, bh*3); indicator_draw_text(menu.window, menu.gc, 8, y+bh*2, menu.w, bh, dc.norm, "Playback stopped", False); } else { indicator_draw_text(menu.window, menu.gc, 8, y+bh, menu.w, bh, dc.norm, track.title, False); indicator_draw_text(menu.window, menu.gc, 8, y+bh*2, menu.w, bh, dc.norm, track.artist, False); indicator_draw_text(menu.window, menu.gc, 8, y+bh*3, menu.w, bh, dc.norm, track.album, False); } indicator_draw_text(menu.window, menu.gc, menu.w/2-BUTTON_W/2-BUTTON_W, y+bh*4, BUTTON_W, bh, i+4==menu.selected&&menu.button==0?dc.sel:dc.norm, "▮◀", False); indicator_draw_text(menu.window, menu.gc, menu.w/2-BUTTON_W/2, y+bh*4, BUTTON_W, bh, i+4==menu.selected&&menu.button==1?dc.sel:dc.norm, status==PLAYBACK_STATUS_PLAYING?"▮▮":" ▶", False); indicator_draw_text(menu.window, menu.gc, menu.w/2-BUTTON_W/2+BUTTON_W, y+bh*4, BUTTON_W, bh, i+4==menu.selected&&menu.button==2?dc.sel:dc.norm, "▶▮", False); } XFlush(dpy); }
void indicator_music_mouse(Indicator *indicator, XButtonPressedEvent *ev) { if(ev->type != ButtonPress) { Window w; int tmp; int x, y; unsigned int mask; XQueryPointer(dpy, menu.window, &w, &w, &tmp, &tmp, &x, &y, &mask); menu.selected=-1; if(x>=0&&y>=0&&x<menu.w&&y<menu.h) { if(mask&0x100&&y/bh==1) { int sliderw=menu.w-10*2; snd_mixer_handle_events(alsa.handle); volume_set(100*(x-10)/sliderw); } menu.selected=y/bh; menu.button=x>=menu.w/2-BUTTON_W*3/2&&x<menu.w/2+BUTTON_W*2/2?(x-(menu.w/2-BUTTON_W*3/2))/BUTTON_W:-1; } indicator_music_expose(indicator, menu.window); return; } if(ev->window==menu.window) { int sliderw=menu.w-10*2; int item=ev->y/bh; struct MEDIAPLAYER *mp; if(item==0) { snd_mixer_handle_events(alsa.handle); mute_set(!mute_get()); } else if(item==1) { if(ev->x>=10&&ev->x<menu.w-10) { snd_mixer_handle_events(alsa.handle); volume_set(100*(ev->x-10)/sliderw); } } else { int i; for(mp=mediaplayer, i=2; mp; mp=mp->next, i+=5) if(item==i) { mediaplayer_raise(mp->id); indicator->active=False; menu_close(); break; } else if(item==i+4&&menu.button>=0) { mediaplayer_action(mp->id, menu.button); indicator_music_expose(indicator, ev->window); } return; } indicator_music_expose(indicator, ev->window); return; } switch(ev->button) { case Button1: case Button3: if((indicator->active=!indicator->active)) menu_open(indicator); else menu_close(); return; case Button4: snd_mixer_handle_events(alsa.handle); volume_set(volume_get()+6); break; case Button5: snd_mixer_handle_events(alsa.handle); volume_set(volume_get()-4); break; } if(indicator->active) indicator_music_expose(indicator, menu.window); }
void alsa_mute_toggle(const Arg *a) { snd_mixer_handle_events(alsa.handle); mute_set(!mute_get()); }
/** * alsa_refresh * handle pending mixer events */ void alsa_refresh() { snd_mixer_handle_events(alsa); }
static void task_monitor_alsa (gpointer data) { struct pollfd *pfds; unsigned int nfds, rnfds; unsigned short revents; GstAlsaMixer *mixer = (GstAlsaMixer *) data; gint ret; g_static_rec_mutex_lock (mixer->rec_mutex); nfds = snd_mixer_poll_descriptors_count (mixer->handle); if (nfds <= 0) { GST_ERROR ("snd_mixer_poll_descriptors_count <= 0: %d", nfds); /* FIXME: sleep ? stop monitoring ? */ g_static_rec_mutex_unlock (mixer->rec_mutex); return; } pfds = g_newa (struct pollfd, nfds + 1); rnfds = snd_mixer_poll_descriptors (mixer->handle, pfds, nfds); g_assert (rnfds <= nfds); if (rnfds < 0) { GST_ELEMENT_ERROR (mixer, RESOURCE, READ, (NULL), ("alsa error: %s", snd_strerror (rnfds))); gst_task_pause (mixer->task); g_static_rec_mutex_unlock (mixer->rec_mutex); return; } pfds[rnfds].fd = mixer->pfd[0]; pfds[rnfds].events = POLLIN | POLLPRI | POLLHUP | POLLERR; pfds[rnfds].revents = 0; g_static_rec_mutex_unlock (mixer->rec_mutex); GST_LOG ("task loop"); ret = poll (pfds, rnfds + 1, -1); if (ret < 0) { GST_ELEMENT_ERROR (mixer, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); gst_task_pause (mixer->task); return; } g_static_rec_mutex_lock (mixer->rec_mutex); ret = snd_mixer_poll_descriptors_revents (mixer->handle, pfds, nfds, &revents); if (ret < 0) { GST_ELEMENT_ERROR (mixer, RESOURCE, READ, (NULL), ("alsa error: %s", snd_strerror (ret))); gst_task_pause (mixer->task); } else if (revents & (POLLIN | POLLPRI)) { GST_DEBUG ("Handling events"); snd_mixer_handle_events (mixer->handle); } else if (revents & (POLLERR | POLLNVAL | POLLHUP)) { GST_ELEMENT_ERROR (mixer, RESOURCE, READ, (NULL), (NULL)); gst_task_pause (mixer->task); } g_static_rec_mutex_unlock (mixer->rec_mutex); }