Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Homann <jh@janhomann.de>
To: Clemens Ladisch <clemens@ladisch.de>, alsa-devel@alsa-project.org
Subject: Re: Too many snd_pcm_mmap_readi calls
Date: Tue, 13 May 2014 09:25:01 +0200	[thread overview]
Message-ID: <5371C8CD.6030606@janhomann.de> (raw)
In-Reply-To: <536A2E13.9070900@ladisch.de>

Am 07.05.2014 14:58, schrieb Clemens Ladisch:
> Jan Homann wrote:
>> In my opinion mmap_begin just tells the alsa-lib that someone is about
>> to access the buffer.
> With mmap_begin, you ask the device how many frames are available in the
> buffer (and get a pointer to them).  With mmap_commit, you tell the
> device how many frames you actually read.
>
>> I am using mmap because of its good performance.
> Using mmap makes sense only when you are accessing the samples in the
> buffer directly.  If you just copy the frames into your own buffer,
> there is *no* difference whatsoever to snd_pcm_readi.
>
>> Under normal condition with snd_pcm_mmap_readi my program uses about
>> 1% of cpu-time where snd_pcm_readi uses about 75%.
> It's likely that you do not correctly wait for frames being available
> in your real program.
>
>> Do you know a good tutorial about using mmap_readi?
> This: use snd_pcm_readi instead.
>
>
> Regards,
> Clemens
>

Thank you for your explanation.
Obviously, there was an error in my initialization which caused the high
cpu-load while using snd_pcm_readi.
After fixing this my programm is running nice and quiet. For almost 8
minutes.
After this time the cpu-load goes up again. The alsa buffer should
contain 480 samples but contains something between 1920 and 6720 samples.
The debug output prints several timestamps. The time for one cycle
through the while-loop is captured in looptime. Under normal
circumstances this one is around 10ms as I expect.
After about 46.500 loops (which is something like 7.75minutes) the
looptime is up to 120ms. The time is used not at the snd_pcm_wait but at
the snd_pcm_readi.
My ARM-Device is running a Preempt Linux Kernel 2.6.35-8 and Arch Linux.

Any hints would be kindly appreciated.

Thanks in advance,
Jan Homann



P.S.: i appended the while-loop which is just in fact doing nothing then
waiting and reading. The above described behaviour occures even when
doing nothing with the captured pcm-data. The debug-output appears never
in my log-files.

    while(1) {

        cnt++;

        err = snd_pcm_wait( sound_handler, 20 );
        switch( err ) {
            case 1:
                //normal operation
                break;
            case 0:
                //timeout occurred - go on with a new loop
                if( global.debug ) printf("%s:%u snd_pcm_wait timeout
(%s), error-code: %d\n", __FILE__, __LINE__, snd_strerror(err), err);
                continue;
                break;
            case -EPIPE:
                if( global.debug ) printf("%s:%u snd_pcm_wait XRUN (%s),
error-code: %d\n", __FILE__, __LINE__, snd_strerror(err), err);
                break;
            case -ESTRPIPE:
                if( global.debug ) printf("%s:%u snd_pcm_wait suspended
(%s), error-code: %d\n", __FILE__, __LINE__, snd_strerror(err), err);
                break;
            default:
                if( global.debug ) printf("%s:%u snd_pcm_wait error
(%s), error-code: %d\n", __FILE__, __LINE__, snd_strerror(err), err);
                break;
        }

        if( global.debug ) gettimeofday(&time2,NULL);
        //time needed for alsa wait
        testtime1 = (time2.tv_usec - time1.tv_usec + (time2.tv_sec -
time1.tv_sec) * 1000000);

        //get the frames out of the soundcardbuffer
        memset( alsa_out_pcm_bytes_U8, 0, sizeof(alsa_out_pcm_bytes_U8) );

        frames_to_deliver = snd_pcm_avail_update(sound_handler);

        frames_to_deliver = min(frames_to_deliver, 480);
        network_data.read_frames = snd_pcm_readi( sound_handler,
alsa_out_pcm_bytes_U8, frames_to_deliver );


        if( network_data.read_frames < 0 ) {
            switch( network_data.read_frames ) {
                case -EAGAIN:
                    //there is no data in driverbuffer available - wait
again by starting the main loop again
                    if( global.debug ) printf("%s:%u EAGAIN on reading -
driverbuffer empty! (%s), error-code: %ld\n", __FILE__, __LINE__,\
                        snd_strerror(network_data.read_frames),
network_data.read_frames);
                    continue;
                    break;
                case -EPIPE:
                    if( global.debug ) printf("<<<<<<<<<<<<<<< Buffer
READ Overrun >>>>>>>>>>>>>>>\n");
                    if( global.debug ) printf("%s:%u (%s), error-code:
%ld\n",__FILE__, __LINE__,\
                        snd_strerror(network_data.read_frames),
network_data.read_frames);
                    continue;
                    break;
                default:
                    if( global.debug ) printf("%s:%u error reading (%s),
error-code: %ld\n", __FILE__, __LINE__,\
                        snd_strerror(network_data.read_frames),
network_data.read_frames);
                    continue;
                    break;
            }
        }

        if( global.debug ) {

            gettimeofday(&time3,NULL);
            //time needed for read
            testtime2 = (time3.tv_usec - time2.tv_usec + (time3.tv_sec -
time2.tv_sec) * 1000000);

            //sum of times for one cycle
            looptime = (time3.tv_usec - time1.tv_usec + (time3.tv_sec -
time1.tv_sec) * 1000000);

            //looptime:  Time for one cycle
            //testtime1: Time for alsa wait
            //testtime2: Time for alsa read
            printf("%06d L:%05d T1:%05d T2:%05d %ld %ld %d\n", \
                    cnt, \
                    looptime, testtime1,testtime2, \
                    network_data.read_frames, frames_to_deliver, err);
           
            if (looptime > 15000){
                printf("ERR %06d L:%05d T1:%05d T2:%05d %ld %ld %d\n", \
                    cnt, \
                    looptime, testtime1,testtime2, \
                    network_data.read_frames, frames_to_deliver, err);
            }
           
            if( global.debug )
gettimeofday(&time1,NULL);                       
        }
    }
}

      reply	other threads:[~2014-05-13  7:25 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-07  7:18 Too many snd_pcm_mmap_readi calls Jan Homann
2014-05-07  9:01 ` Clemens Ladisch
2014-05-07  9:52   ` Jan Homann
2014-05-07 10:29     ` Jaroslav Kysela
2014-05-07 12:58     ` Clemens Ladisch
2014-05-13  7:25       ` Jan Homann [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5371C8CD.6030606@janhomann.de \
    --to=jh@janhomann.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=clemens@ladisch.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox