snd_pcm_delay doesn't work with softvol + rate conversion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm trying to run a program that uses ALSA on a system with a HDA
VIA VT82xx sound card (built into the motherboard).  This useless
piece of hardware doesn't support sample rate conversion, and
doesn't have it's own volume control.  When I use ALSA's "default"
device on this system, I can change the volume with alsamixer,
and the program accepts non-native sample rates.

The problem is that when software SRC and volume control is
combined, snd_pcm_delay doesn't work as it should.  What happens
is that the reported delay never decreases, even though audio _is_
playing, and the buffer is draining.  That is, every time I write
audio into the sound card with snd_pcm_writei, the number returned
by snd_pcm_delay increases as it should, but when I wait for the
sound to play out, it doesn't decrease.

I have created a simple program that demonstrates this bug:  It
fills the sound card buffer, and then calls snd_pcm_delay until
it returns zero while printing every returned value.

When this program is run with my sound card's native sample rate
(48000 Hz), the numbers quickly drop to zero and the program
terminates.  When run with any other rate, it simply loops forever
in the snd_pcm_delay loop, printing the same value forever.

My system is:

CPU: Athlon64 3500+
RAM: 1 GB DDR2 (Corsair Value Select PC5300)
Motherboard: Asus M2V (VIA K8T890 northbridge, VT8237A south)
Audio codec: Realtek ALC 660 (built into the motherboard)
Linux distro: Fedora Core 6
ALSA packages: alsa-lib-1.0.14-0.1.rc1.fc6
               alsa-lib-devel-1.0.14-0.1.rc1.fc6
               alsa-utils-1.0.14-0.2.rc1.fc6
Kernel: 2.6.20-1.2962.fc6
Other: glibc-2.5-18.fc6 and gcc-4.1.2-13.fc6

I am unable to reproduce this bug on a system that has an SB Live 5.1
so it might just be reproducible on the sound card integrated
into the above system, but I'd appreciate it if someone could test
it on a system with an equally crappy sound card. :-)

Finally, here's the program that demonstrates the bug:

/*******************************************************************/

#include <alsa/asoundlib.h>

int main(int argc, char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "usage: %s SAMPLE-RATE\n", argv[0]);
        exit(1);
    }

    snd_pcm_t *pcm_handle;
    if (snd_pcm_open
        (&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK,
         SND_PCM_NONBLOCK) < 0) {
        fprintf(stderr, "Error opening PCM device\n");
        exit(1);
    }

    snd_pcm_hw_params_t *hwparams;
    snd_pcm_hw_params_alloca(&hwparams);
    if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
        fprintf(stderr, "Can not configure this PCM device\n");
        exit(1);
    }

    if (snd_pcm_hw_params_set_access
        (pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
        fprintf(stderr, "Error setting access\n");
        exit(1);
    }

    if (snd_pcm_hw_params_set_format
        (pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE) < 0) {
        fprintf(stderr, "Error setting format\n");
        exit(1);
    }

    if (snd_pcm_hw_params_set_rate
        (pcm_handle, hwparams, atoi(argv[1]), 0) < 0) {
        fprintf(stderr, "Error setting rate\n");
        exit(1);
    }

    if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) < 0) {
        fprintf(stderr, "Error setting channels\n");
        exit(1);
    }

    snd_pcm_uframes_t frames;
    snd_pcm_hw_params_get_buffer_size_max(hwparams, &frames);
    if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, frames) <
        0) {
        fprintf(stderr, "Error setting buffer size\n");
        exit(1);
    }

    if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) {
        fprintf(stderr, "Error setting HW params\n");
        exit(1);
    }

    char buf[4096] = { };
    // Uncomment the below lines to hear some sound that confirms that the
    // buffer is draining despite what snd_pcm_delay is saying.
    //int i;
    //for (i = 0; i < 4096; i++) {
    //    buf[i] = i & 0xff;
    //}
    while (snd_pcm_writei(pcm_handle, buf, sizeof(buf) / 4) > 0);

    snd_pcm_sframes_t delay;
    do {
        while (snd_pcm_delay(pcm_handle, &delay) == -EPIPE) {
            snd_pcm_prepare(pcm_handle);
        }
        fprintf(stderr, "%d\n", (int) delay);
    } while (delay > 0);

    exit(0);
}

/*******************************************************************/

-- 
 Haakon

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Alsa-user mailing list
Alsa-user@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-user

[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux