tags:

views:

83

answers:

1

Dear developers,

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

+2  A: 

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.

Gonzalo
I don't understand what you would like me to try. Can you explain it a little more?
Louise
I edited my answer since you're passing the number of bytes instead of the number of frames.
Gonzalo
Very cool. Now my own implementation doesn't crash =) But I still get the same warning/error. Btw. how can it be, that I don't hear any sound, if I remove the for-loop (and of course keeping its content)?
Louise
I'd say it's because the amount of data you provided results in a very short-lived sound...
Gonzalo
Even if I give it several seconds, I don't hear anything. If I put the for-loop back on, I hear the "several seconds long" 16 times.
Louise
When I have the loop, it writes 253376 "frames" that play for ~4.2s. That means that you need ~60kB to play 1s. One single iteration of the loop is ~1/4 -> ~250ms. The minimum number of iterations I had to do to get a sound out of that code is 3.
Gonzalo