On Wed, 17 Oct 2001, Paul Davis wrote: > In message <[EMAIL PROTECTED]>you write: > >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! */ > > well, it depends on what you do with the playback stream. there isn't > much evidence that you do anything to it, which would cause poll(2) to > return endlessly. perhaps gst_alsa_release_channel_addresses() does > the right thing, i don't know.
I'm not doing anything with a playback stream. This loop is used for both capture and playback elements; this->stream determines which kind it is. If I have the following pipeline: alsasrc ! ladspa_foo ! alsasink there are two of these loops running separately, one for each element, with separate handles, etc. I was thinking for some reason that snd_pcm_update_avail would block until avail_min frames were available, but that's not the case. If I run the following pipeline, I get: $ tools/gstreamer-launch alsasrc ! fakesink INFO (19046:-1) Initializing GStreamer Core Library INFO (19046:-1) CPU features: (808009bf) MMX 3DNOW RUNNING pipeline Opening alsa device "default" for capture... Preparing channel: S16_LE 44100Hz, 1 channels Plug PCM: Hardware PCM card 0 'Ensoniq AudioPCI' device 0 subdevice -1 Its setup is: stream : CAPTURE access : MMAP_INTERLEAVED format : S16_LE subformat : STD channels : 1 rate : 44100 exact rate : 44100 (1411200/32) msbits : 16 buffer_size : 1024 period_size : 256 period_time : 5804 tick_time : 10000 tstamp_mode : NONE period_step : 1 sleep_min : 0 avail_min : 256 xfer_align : 256 start_threshold : -1 stop_threshold : -1 silence_threshold: 0 silence_size : 1024 boundary : 1073741824 fakesink: chain ******* (fakesink0:sink)< (512 bytes, 0) 0x808d4d0 fakesink: chain ******* (fakesink0:sink)< (992 bytes, 0) 0x808d4d0 fakesink: chain ******* (fakesink0:sink)< (544 bytes, 0) 0x808d4d0 fakesink: chain ******* (fakesink0:sink)< (992 bytes, 0) 0x808d4d0 fakesink: chain ******* (fakesink0:sink)< (512 bytes, 0) 0x808d4d0 fakesink: chain ******* (fakesink0:sink)< (512 bytes, 0) 0x808d4d0 fakesink: chain ******* (fakesink0:sink)< (32 bytes, 0) 0x808d4d0 fakesink: chain ******* (fakesink0:sink)< (992 bytes, 0) 0x808d4d0 the byte counts referring to how much data I could read. 32 is a little funny. This gets back to my other point, that I left the mmap code out of the last email Here they are: static gboolean gst_alsa_get_channel_addresses (GstAlsa *this) { guint32 err, n; const snd_pcm_channel_area_t *a; g_return_val_if_fail (this->access_addr[0] == NULL, FALSE); // G_BREAKPOINT(); GST_DEBUG(0, "getting mmap'd data region\n"); if ((err = snd_pcm_mmap_begin (this->handle, &this->mmap_areas, &this->offset, &this->avail)) < 0) { g_warning("gstalsa: mmap failed: %s", snd_strerror(err)); return FALSE; } GST_DEBUG(0, "got %d frames\n", this->avail); for (n = 0; n < this->channels; n++) { a = &this->mmap_areas[n]; this->access_addr[n] = (char *) a->addr + ((a->first + a->step * this->offset) / 8); } return TRUE; } static void gst_alsa_release_channel_addresses (GstAlsa *this) { guint32 err, n; g_return_if_fail (this->access_addr[0] != NULL); // G_BREAKPOINT(); GST_DEBUG(0, "releasing mmap'd data region: %d frames\n", this->avail); if ((err = snd_pcm_mmap_commit (this->handle, this->offset, this->avail)) < 0) { g_warning("gstalsa: mmap commit failed: %s", snd_strerror(err)); return; } for (n = 0; n < this->channels; n++) { this->access_addr[n] = NULL; } this->avail=0; } > your code also seems to be assuming that `avail' for the playback > stream is the same as for the capture stream. not a good assumption, > not good at all. playback and capture are not using the same pcm handle or loop, so this isn't relevant. Thanks very much for your help. wingo. _______________________________________________ Alsa-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-devel