I bought raspberry pi 5
and I want to implement loopback using the alsa library in pi5.
but I cant that.
my c source code is here.
this code said
alsa start
alsa open capture handle
alsa open playback handle
alsa pcm hw param alloc
alsa capture_handle set start
snd_pcm_hw_params_set_buffer_size_near cant set hw params. [Invalid argument]
and then, this is the code I rewritten.this code said
alsa start
alsa open capture handle
alsa open playback handle
alsa pcm hw param alloc
alsa capture_handle set start
alsa playback_handle set start
alsa playback_handle set success
alsa buf malloc
main loop start
Capture read error[-5]: Input/output error
and I checked alsa library
what should I do?
my audio hardware is here
https://www.hifiberry.com/shop/0-develo ... pment-kit/
and datasheet is here
https://www.hifiberry.com/docs/data-she ... adc-stage/
and I want to implement loopback using the alsa library in pi5.
but I cant that.
my c source code is here.
Code:
printf("alsa start\n"); int err; snd_pcm_t *capture_handle, *playback_handle; snd_pcm_hw_params_t *hw_params; unsigned char *buffer; int sample_rate = SAMPLE_RATE; int dir; snd_pcm_uframes_t frames = 32; snd_pcm_uframes_t bufferSize, periodSize; double x_prev = 0.0; double y_prev = 0.0; double b0 = 1.0; double b1 = -0.8; double a1 = 0.0; printf("alsa open capture handle\n"); err = snd_pcm_open(&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0); if(err < 0) { fprintf(stderr, "Capture open error: %s\n", snd_strerror(err)); exit(1); } printf("alsa open playback handle\n"); err = snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if(err < 0) { fprintf(stderr, "Playback open error: %s\n", snd_strerror(err)); exit(1); } printf("alsa pcm hw param alloc\n"); snd_pcm_hw_params_alloca(&hw_params); printf("alsa capture_handle set start\n"); err = snd_pcm_hw_params_any(capture_handle, hw_params); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_any cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_access cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S16_LE); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_format cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, NUM_CHANNELS); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_channels cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &sample_rate, &dir); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_rate_near cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_buffer_size_near(capture_handle, hw_params, &bufferSize); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_buffer_size_near cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_period_size_near(capture_handle, hw_params, &periodSize, &dir); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_period_size_near cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params(capture_handle, hw_params); if (err < 0) { fprintf(stderr, "alsa cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } snd_pcm_hw_params_get_buffer_size(hw_params, &bufferSize); snd_pcm_hw_params_get_period_size(hw_params, &periodSize, &dir); printf("Buffer size: %lu frames\n", bufferSize); printf("Period size: %lu frames\n", periodSize); printf("alsa playback_handle set start\n"); snd_pcm_hw_params_any(playback_handle, hw_params); snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(playback_handle, hw_params, NUM_CHANNELS); snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &sample_rate, 0); snd_pcm_hw_params(playback_handle, hw_params); printf("alsa playback_handle set success\n"); printf("alsa buf malloc\n"); buffer = (unsigned char*)malloc(BUFFER_SIZE*NUM_CHANNELS*2); while(1) { printf("main loop start\n"); err = snd_pcm_readi(capture_handle, buffer, BUFFER_SIZE); if(err<0) { fprintf(stderr, "Capture read error[%d]: %s\n", err, snd_strerror(err)); break; } for(int i = 0; i < BUFFER_SIZE * NUM_CHANNELS * 2; i += 2) { short sample = ((short)buffer[i + 1] << 8) | buffer[i]; double x = (double)sample / 32768.0; double y = b0 * x + b1 * x_prev + a1 * y_prev; x_prev = x; y_prev = y; short filter_sample = (short)(y * 32768.0); buffer[i] = (unsigned char)(filter_sample & 0xFF); buffer[i+1] = (unsigned char)((filter_sample >> 8) & 0xFF); } err = snd_pcm_writei(playback_handle, buffer, BUFFER_SIZE); if(err < 0) { fprintf(stderr, "Playback write error: %s\n", snd_strerror(err)); break; } } free(buffer); snd_pcm_close(capture_handle); snd_pcm_close(playback_handle); exit(0);
alsa start
alsa open capture handle
alsa open playback handle
alsa pcm hw param alloc
alsa capture_handle set start
snd_pcm_hw_params_set_buffer_size_near cant set hw params. [Invalid argument]
and then, this is the code I rewritten.
Code:
printf("alsa start\n"); int err; snd_pcm_t *capture_handle, *playback_handle; snd_pcm_hw_params_t *hw_params; unsigned char *buffer; int sample_rate = SAMPLE_RATE; double x_prev = 0.0; double y_prev = 0.0; double b0 = 1.0; double b1 = -0.8; double a1 = 0.0; printf("alsa open capture handle\n"); err = snd_pcm_open(&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0); if(err < 0) { fprintf(stderr, "Capture open error: %s\n", snd_strerror(err)); exit(1); } printf("alsa open playback handle\n"); err = snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if(err < 0) { fprintf(stderr, "Playback open error: %s\n", snd_strerror(err)); exit(1); } printf("alsa pcm hw param alloc\n"); snd_pcm_hw_params_alloca(&hw_params); printf("alsa capture_handle set start\n"); err = snd_pcm_hw_params_any(capture_handle, hw_params); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_any cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_access cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S16_LE); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_format cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, NUM_CHANNELS); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_channels cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &sample_rate, 0); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_rate_near cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params(capture_handle, hw_params); if (err < 0) { fprintf(stderr, "alsa cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } printf("alsa playback_handle set start\n"); err = snd_pcm_hw_params_any(playback_handle, hw_params); if (err < 0) { fprintf(stderr, "playback_handle cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_access cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_S16_LE); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_format cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_channels(playback_handle, hw_params, NUM_CHANNELS); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_channels cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &sample_rate, 0); if (err < 0) { fprintf(stderr, "snd_pcm_hw_params_set_rate_near cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } err = snd_pcm_hw_params(playback_handle, hw_params); if (err < 0) { fprintf(stderr, "alsa cant set hw params. [%s]\n", snd_strerror(err)); exit(1); } printf("alsa playback_handle set success\n"); printf("alsa buf malloc\n"); buffer = (unsigned char*)malloc(BUFFER_SIZE*NUM_CHANNELS*2); while(1) { printf("main loop start\n"); err = snd_pcm_readi(capture_handle, buffer, BUFFER_SIZE); if(err<0) { fprintf(stderr, "Capture read error[%d]: %s\n", err, snd_strerror(err)); break; } for(int i = 0; i < BUFFER_SIZE * NUM_CHANNELS * 2; i += 2) { short sample = ((short)buffer[i + 1] << 8) | buffer[i]; double x = (double)sample / 32768.0; double y = b0 * x + b1 * x_prev + a1 * y_prev; x_prev = x; y_prev = y; short filter_sample = (short)(y * 32768.0); buffer[i] = (unsigned char)(filter_sample & 0xFF); buffer[i+1] = (unsigned char)((filter_sample >> 8) & 0xFF); } err = snd_pcm_writei(playback_handle, buffer, BUFFER_SIZE); if(err < 0) { fprintf(stderr, "Playback write error: %s\n", snd_strerror(err)); break; } } free(buffer); snd_pcm_close(capture_handle); snd_pcm_close(playback_handle); exit(0);
alsa start
alsa open capture handle
alsa open playback handle
alsa pcm hw param alloc
alsa capture_handle set start
alsa playback_handle set start
alsa playback_handle set success
alsa buf malloc
main loop start
Capture read error[-5]: Input/output error
and I checked alsa library
Code:
# aplay -l**** List of PLAYBACK Hardware Devices ****card 0: sndrpihifiberry [snd_rpi_hifiberry_dacplusadcpro], device 0: HiFiBerry DAC+ADC Pro HiFi multicodec-0 [HiFiBerry DAC+ADC Pro HiFi multicodec-0] Subdevices: 1/1 Subdevice #0: subdevice #0# arecord -l**** List of CAPTURE Hardware Devices ****card 0: sndrpihifiberry [snd_rpi_hifiberry_dacplusadcpro], device 0: HiFiBerry DAC+ADC Pro HiFi multicodec-0 [HiFiBerry DAC+ADC Pro HiFi multicodec-0] Subdevices: 1/1 Subdevice #0: subdevice #0
my audio hardware is here
https://www.hifiberry.com/shop/0-develo ... pment-kit/
and datasheet is here
https://www.hifiberry.com/docs/data-she ... adc-stage/
Statistics: Posted by seoyyung — Fri Mar 01, 2024 12:40 pm