Hi. I'm writing the alsa plugin for gstreamer. When I go to capture audio, my loop eats the entire cpu. I set avail_min but still sometimes get out 32 frame avail values. Here's the relevant portion:
/* shamelessly stolen from pbd's audioengine. thanks, paul! */ static void gst_alsa_loop (GstElement *element) { struct pollfd pfd; gboolean xrun_detected; guint32 x; GstAlsa *this = (GstAlsa*) element; g_return_if_fail(this != NULL); if (this->stream == SND_PCM_STREAM_PLAYBACK) { snd_pcm_poll_descriptors (this->handle, &pfd, 1); pfd.events = POLLOUT | POLLERR; } do { if (this->stream == SND_PCM_STREAM_PLAYBACK) { if (poll (&pfd, 1, 1000) < 0) { if (errno == EINTR) { // this happens mostly when run // under gdb, or when exiting due to a signal continue; } g_warning("poll call failed (%s)", strerror(errno)); return; } if (pfd.revents & POLLERR) { g_warning("alsa: poll reports error."); return; } if (pfd.revents == 0) { // timed out, such as when the device is paused continue; } } xrun_detected = FALSE; this->avail = snd_pcm_avail_update (this->handle); while (this->avail < this->period_frames) { if (this->avail < 0) { if (this->avail == -EPIPE) { xrun_detected = TRUE; } else { g_warning("unknown ALSA avail_update return value (%d)", (int)this->avail); return; } } else { snd_pcm_wait(this->handle, 1000); } this->avail = snd_pcm_avail_update (this->handle); } if (xrun_detected) g_warning ("xrun detected"); if (!gst_alsa_get_channel_addresses (this) < 0) { g_error("could not get channels"); return; } if (this->mute && this->stream == SND_PCM_STREAM_PLAYBACK) { for (x = 0; x < this->channels; x++) { if (this->mute & (1<<x)) { gst_alsa_sink_silence_on_channel (this, x, this->buffer_frames); } } // silence_pending = 0; } // channels_not_done = channel_done_bits; // prefold_all_channels (contiguous); if (!this->process(this, this->avail)) { g_warning("alsa: something happened while processing audio"); return; } // if (channels_not_done) { // silence_untouched_channels (contiguous); // } gst_alsa_release_channel_addresses(this); } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); // clean up bytestreams } // this is one of the possible functions for this->process on a capture device static gboolean gst_alsa_src_interleaved_process (GstAlsa *this, snd_pcm_uframes_t frames) { GstBuffer *buf; gint len; g_return_val_if_fail(this->pad != NULL, FALSE); len = frames * this->sample_bytes * this->channels; buf = gst_buffer_new(); GST_BUFFER_DATA(buf) = g_malloc(len); GST_BUFFER_SIZE(buf) = len; GST_BUFFER_MAXSIZE(buf) = len; memcpy(GST_BUFFER_DATA(buf), this->access_addr[0], len); gst_pad_push(this->pad, buf); return TRUE; } For the record, playback works quite well now. Thanks to all who helped! wingo _______________________________________________ Alsa-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-devel