Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

alsa cant initialize on raspberry pi 5 #386

Open
sy-project opened this issue Feb 29, 2024 · 2 comments
Open

alsa cant initialize on raspberry pi 5 #386

sy-project opened this issue Feb 29, 2024 · 2 comments

Comments

@sy-project
Copy link

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?

@sy-project
Copy link
Author

and I use this code.
but this code has error, too.

    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);

terminal

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

@z-s-e
Copy link
Contributor

z-s-e commented Mar 7, 2024

I believe this bug tracker is not the right place to ask for code reviews. Alsa is clearly working on your raspi, as you verified that with aplay yourself, so there must be bugs in your own code. For the first error it seems you do not initialize bufferSize or periodSize with reasonable values, it even tells you that in the error.

Whenever your code is not working, I generally recommend comparing your code very carefully to working code or examples such as this one and try to find the problematic places yourself first before asking for help - that is also a good way to learn finding and fixing bugs by yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants