예제 #1
0
void alsa_volume(const Arg *a) {
	long vol = a->i;
	
	snd_mixer_handle_events(alsa.handle);
	vol += volume_get();
	volume_set(vol);
}
예제 #2
0
파일: alsa.c 프로젝트: ecthiender/mocp-git
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);
	}
}
예제 #3
0
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);
}
예제 #4
0
파일: gtkalsamixer.c 프로젝트: wuruxu/golc
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
void LapsusAlsaMixer::alsaEvent()
{
	if (!_fds || _count < 1) return;

	snd_mixer_handle_events(_handle);

	// Those functions will emit any signals needed
	getVolume();
	mixerIsMuted();
}
예제 #8
0
파일: dwmst.c 프로젝트: Theta91/dwmst
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);
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
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);
    }
}
예제 #12
0
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;
}
예제 #13
0
파일: sys_alsa.c 프로젝트: haxworx/Enform
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;
}
예제 #14
0
파일: lamixer.c 프로젝트: metsger/lamixer
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;
	}
}
예제 #15
0
파일: alsa.c 프로젝트: aarizkuren/pnmixer
/**
 * 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;
}
예제 #16
0
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);
    }
}
예제 #17
0
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;
}
예제 #18
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;
}
예제 #19
0
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);
	}
}
예제 #20
0
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);
}
예제 #21
0
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;
}
예제 #22
0
파일: mixer.c 프로젝트: pzanoni/tray
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;
}
예제 #23
0
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;
}
예제 #24
0
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;
}
예제 #25
0
파일: dwmstatus.c 프로젝트: Mariappan/dwm
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);
}
예제 #26
0
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);
}
예제 #27
0
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);
}
예제 #28
0
void alsa_mute_toggle(const Arg *a) {
	snd_mixer_handle_events(alsa.handle);
	mute_set(!mute_get());
}
예제 #29
0
파일: alsa.c 프로젝트: mjheagle8/status
/**
 * alsa_refresh
 * handle pending mixer events
 */
void
alsa_refresh()
{
        snd_mixer_handle_events(alsa);
}
예제 #30
0
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);
}