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