alsa-project/alsa-lib issue #368 was opened from nodemand:
I'm on a RPi5 4GB running Raspberry Pi OS 64bit Bookworm and my application hangs on snd_pcm_readn when I try to read and write to the same device. This occurs on an IQAudio Codec Zero sound card and on a HifiBerry DAC+ADC Pro as well. When I select a USB sound card as the output and one of the others described for input everything works like it should.
Here is my code: ` #include <alsa/asoundlib.h> #include <alsa/control.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <algorithm> #include <iterator>
typedef signed short drwav_int16; typedef signed int drwav_int32;
#define PCM_DEVICE_IN "plughw:Zero,0" #define PCM_DEVICE_OUT "plughw:Zero,0" //"plughw:Device,0"
int err, result, loops, n, t; unsigned int rate, pcm, tmp;
snd_pcm_t *play; snd_pcm_t *record; snd_pcm_hw_params_t *playparams; snd_pcm_hw_params_t *recordparams; snd_pcm_uframes_t frames; snd_pcm_sframes_t recresult; snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; int block = 0;//SND_PCM_NONBLOCK;
int buffer_frames = 1024; int bits_per_frame = 16; const int bits_per_byte = 8; int channels = 2;
int bytesize_per_channel = buffer_frames * bits_per_frame / bits_per_byte;
int main(int argc, char **argv) { if (argc < 3) { printf("Usage: %s <sample_rate> <frames>\n", argv[0]); return -1; }
rate = atoi(argv[1]); buffer_frames = atoi(argv[2]); bytesize_per_channel = buffer_frames * snd_pcm_format_width(format) / bits_per_byte;
drwav_int16 *buffer_in[channels]; /* Open the PCM device in record mode */ if ((pcm = snd_pcm_open(&record, PCM_DEVICE_IN, SND_PCM_STREAM_CAPTURE, block)) < 0) printf("ERROR: Can't open "%s" PCM device. %s\n", PCM_DEVICE_IN, snd_strerror(pcm));
/* Allocate parameters object and fill it with default values*/ if ((pcm = snd_pcm_hw_params_malloc(&recordparams)) < 0) printf("ERROR: Can't allocate hardware parameter structure. %s\n", snd_strerror(pcm));
if ((pcm = snd_pcm_hw_params_any(record, recordparams)) < 0) printf("ERROR: Can't initialize hardware parameter structure. %s\n", snd_strerror(pcm));
/* Set parameters */ if ((pcm = snd_pcm_hw_params_set_access(record, recordparams, SND_PCM_ACCESS_RW_NONINTERLEAVED )) < 0) printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(pcm));
if ((pcm = snd_pcm_hw_params_set_format(record, recordparams, format)) < 0) printf("ERROR: Can't set format. %s\n", snd_strerror(pcm));
if ((pcm = snd_pcm_hw_params_set_channels(record, recordparams, channels)) < 0) printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));
if ((pcm = snd_pcm_hw_params_set_rate_near(record, recordparams, &rate, 0)) < 0) printf("ERROR: Can't set sample rate. %s\n", snd_strerror(pcm));
/* Write parameters */ if ((pcm = snd_pcm_hw_params(record, recordparams)) < 0) printf("ERROR: Can't set hardware parameters. %s\n", snd_strerror(pcm)); if ((pcm = snd_pcm_prepare(record)) < 0) printf("ERROR: Can't prepare audio interface for use. %s\n", snd_strerror(pcm)); if ((pcm = snd_pcm_start(record)) < 0) printf("ERROR: Can't start hardware soundcard. %s\n", snd_strerror(pcm)); /* Resume information */ printf("PCM name: '%s'\n", snd_pcm_name(record));
printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(record)));
snd_pcm_hw_params_get_channels(recordparams, &tmp); printf("channels: %i ", tmp);
if (tmp == 1) printf("(mono)\n"); else if (tmp == 2) printf("(stereo)\n");
snd_pcm_hw_params_get_rate(recordparams, &tmp, 0); printf("sample rate: %d bps\n", tmp); /* Open the PCM device in playback mode */ if ((pcm = snd_pcm_open(&play, PCM_DEVICE_OUT, SND_PCM_STREAM_PLAYBACK, block)) < 0) printf("ERROR: Can't open "%s" PCM device. %s\n", PCM_DEVICE_OUT, snd_strerror(pcm)); if ((pcm = snd_pcm_hw_params_malloc(&playparams)) < 0) printf("ERROR: Can't allocate hardware parameter structure. %s\n", snd_strerror(pcm));
if ((pcm = snd_pcm_hw_params_any(play, playparams)) < 0) printf("ERROR: Can't initialize hardware parameter structure. %s\n", snd_strerror(pcm));
/* Set parameters */ if ((pcm = snd_pcm_hw_params_set_access(play, playparams, SND_PCM_ACCESS_RW_NONINTERLEAVED )) < 0) printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(pcm)); if ((pcm = snd_pcm_hw_params_set_format(play, playparams, format)) < 0) printf("ERROR: Can't set format. %s\n", snd_strerror(pcm));
if ((pcm = snd_pcm_hw_params_set_channels(play, playparams, channels)) < 0) printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));
if ((pcm = snd_pcm_hw_params_set_rate_near(play, playparams, &rate, 0)) < 0) printf("ERROR: Can't set sample rate. %s\n", snd_strerror(pcm));
/* Write parameters */ if ((pcm = snd_pcm_hw_params(play, playparams)) < 0) printf("ERROR: Can't set hardware parameters. %s\n", snd_strerror(pcm)); if ((pcm = snd_pcm_prepare(play)) < 0) printf("ERROR: Can't prepare audio interface for use. %s\n", snd_strerror(pcm)); if ((pcm = snd_pcm_start(play)) < 0) printf("ERROR: Can't start hardware soundcard. %s\n", snd_strerror(pcm)); /* Resume information */ printf("PCM name: '%s'\n", snd_pcm_name(play));
printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(play)));
snd_pcm_hw_params_get_channels(playparams, &tmp); printf("channels: %i ", tmp);
if (tmp == 1) printf("(mono)\n"); else if (tmp == 2) printf("(stereo)\n");
snd_pcm_hw_params_get_rate(playparams, &tmp, 0); printf("sample rate: %d bps\n", tmp); buffer_in[0] = (drwav_int16*) malloc(bytesize_per_channel); buffer_in[1] = (drwav_int16*) malloc(bytesize_per_channel); printf("buffers allocated: %d bytes per channel\n", bytesize_per_channel); for (loops = 0; loops < 25000; loops++) {
if ((recresult = snd_pcm_readn(record, (void**) buffer_in, buffer_frames)) < 0) { printf ("ERROR. Read from audio interface failed. (%s)\n", snd_strerror(recresult)); exit(1); } n = (int) recresult; printf("read %d done, %d frames\n", loops, n); if ((result = snd_pcm_writen(play, (void**) buffer_in, recresult)) == -EPIPE) { printf("XRUN.\n"); snd_pcm_prepare(play); } else if (result < 0) { printf("ERROR. Can't write to playback device. %s\n", snd_strerror(result)); exit(1); } printf("write %d done\n", loops); }
snd_pcm_hw_params_free(playparams); snd_pcm_hw_params_free(recordparams); printf("params freed\n"); snd_pcm_drain(play); snd_pcm_close(play); snd_pcm_drain(record); snd_pcm_close(record); printf("audio interface closed\n"); free(buffer_in[0]); free(buffer_in[1]); printf("buffers freed\n");
return 0; } `
Issue URL : https://github.com/alsa-project/alsa-lib/issues/368 Repository URL: https://github.com/alsa-project/alsa-lib