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

Reply via email to