I can use alsa command
# 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
and I can aplay to use wav file.
# aplay -D hw:0,0 /root/C_Code/audiotest/test1.wav
Playing WAVE '/root/C_Code/audiotest/test1.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo
but I cant initialize on c code.
my code is here.
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);
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]
what should I do?
I can use alsa command
and I can aplay to use wav file.
but I cant initialize on c code.
my code is here.
This code said
what should I do?