Question

When I compile ALSA's pcm_min.c example with

gcc -Wall -lasound pcm_min.c -o pcm_min

Everything is fine, but running it, I get the white noise as expected, but I also get this warning/error:

Short write (expected 16384, wrote 7616)

Which comes from the last if-statement.

#include <alsa/asoundlib.h>

static char *device = "default";                        /* playback device */

snd_output_t *output = NULL;
unsigned char buffer[16*1024];                          /* some random data */

int main(void)
{
        int err;
        unsigned int i;
        snd_pcm_t *handle;
        snd_pcm_sframes_t frames;

        for (i = 0; i < sizeof(buffer); i++)
                buffer[i] = random() & 0xff;

        if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
                printf("Playback open error: %s\n", snd_strerror(err));
                exit(EXIT_FAILURE);
        }
        if ((err = snd_pcm_set_params(handle,
                                      SND_PCM_FORMAT_U8,
                                      SND_PCM_ACCESS_RW_INTERLEAVED,
                                      1,
                                      48000,
                                      1,
                                      500000)) < 0) {   /* 0.5sec */
                printf("Playback open error: %s\n", snd_strerror(err));
                exit(EXIT_FAILURE);
        }

        for (i = 0; i < 16; i++) {
                frames = snd_pcm_writei(handle, buffer, sizeof(buffer));
                if (frames < 0)
                        frames = snd_pcm_recover(handle, frames, 0);
                if (frames < 0) {
                        printf("snd_pcm_writei failed: %s\n", snd_strerror(err));
                        break;
                }
                if (frames > 0 && frames < (long)sizeof(buffer))
                        printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames);
        }

        snd_pcm_close(handle);
        return 0;
}

Can someone see why this warning/error occur?

Hugs, Louise

Was it helpful?

Solution

The snd_pcm_writei() function might return less than sizeof(buffer) when there's either a signal received or an underrun. In your case, it seems that you're mixing bytes and frames. The last parameter of the call is the number of frames that you have in your buffer. Since you're passing the number of bytes in your buffer instead, you're seeing an underrun.

OTHER TIPS

I was also having some problems with this example. I modified it a bit and now it works.

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>

static char *device = "default"; /* playback device */
snd_output_t *output = NULL;
unsigned char buffer[16*1024]; /* some random data */

int main(void)
{
    int err;
    unsigned int i;
    snd_pcm_t *handle;
    snd_pcm_sframes_t frames;
    snd_pcm_uframes_t bufferSize, periodSize;

    for (i = 0; i < sizeof(buffer); i++)
        buffer[i] = random() & 0xff;

    if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
        printf("Playback open error: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    if ((err = snd_pcm_set_params(handle,
                                  SND_PCM_FORMAT_S16_LE,
                                  SND_PCM_ACCESS_RW_INTERLEAVED,
                                  1, //channels
                                  44100, //sample rate
                                  1, //allow resampling
                                  500000) //required latency in us
          ) < 0) {
        printf("Playback open error: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }

    if ((err = snd_pcm_prepare(handle)) < 0) {
        printf("Pcm prepare error: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }

    if ((err = snd_pcm_get_params( handle, &bufferSize, &periodSize )) < 0) {
        printf("Pcm get params error: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    printf("Buffer size:%d, Period size:%d\n", (int)bufferSize, (int)periodSize);

    for (i = 0; i < 16; i++) {
        frames = snd_pcm_writei(handle, buffer, periodSize);
        if (frames < 0)
            frames = snd_pcm_recover(handle, frames, 0);
        if (frames < 0) {
            printf("snd_pcm_writei failed: %s\n", snd_strerror(err));
            break;
        }
        if (frames > 0 && frames < (long)periodSize)
            printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames);
    }
    snd_pcm_close(handle);
    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top