如何在ALSA中设置周期大小,再次讨论

如何在ALSA中设置周期大小,再次讨论,alsa,Alsa,这似乎回答了我的问题:但我有一个不起作用的例子 frames = 1024; int dir; snd_pcm_hw_params_set_period_size_near(pcm_handle, params, &frames, &dir); snd_pcm_hw_params(pcm_handle, params); snd_pcm_hw_params_get_period_size(params, &frames, 0); printf("Frames: %

这似乎回答了我的问题:但我有一个不起作用的例子

frames = 1024;
int dir;

snd_pcm_hw_params_set_period_size_near(pcm_handle, params, &frames, &dir);

snd_pcm_hw_params(pcm_handle, params);

snd_pcm_hw_params_get_period_size(params, &frames, 0);

printf("Frames: %zd\n", frames);
无论帧是高还是低,当我使用snd_pcm_hw_params_get_period_size()获取实际设置的帧时,它总是显示512帧

我知道我试图设定的确切数字可能不可用。但是,它不应该将其设置为与我请求的值最接近的值吗

我希望它至少在我要求更高的数字时增加,或者在我要求更低的数字时降低,而不是保持完全相同

“硬件”设备的硬件参数c输出:

“默认”设备的硬件参数c输出:

最小可重复性示例,其中我尝试设置缓冲区大小的周期:

/**
 * Attempting to set some parameters.
 *
 * Using the template from: http://equalarea.com/paul/alsa-audio.html
 *
 **/

#include <alsa/asoundlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>

#define PCM_DEVICE "default"

int main(int argc, char **argv)
{
    unsigned int pcm;
    snd_pcm_t *pcm_handle;
    snd_pcm_hw_params_t *params;

    /* Open the PCM device in playback mode */
    if(pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        printf("ERROR: Can't open \"%s\" PCM device. %s\n", PCM_DEVICE, snd_strerror(pcm));

        return 1;
    }

    /* Allocate parameters object and fill it with default values*/
    snd_pcm_hw_params_alloca(&params);

    snd_pcm_hw_params_any(pcm_handle, params);

    /* Set parameters */
    if(pcm = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
        printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(pcm));

        return 1;
    }

    if(pcm = snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_FLOAT) < 0) {
        printf("ERROR: Can't set format. %s\n", snd_strerror(pcm));

        return 1;
    }

    int channels = 2;
    if(pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, channels) < 0) {
        printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));

        return 1;
    }

    int rate = 44100;
    if(pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0) < 0) {
        printf("ERROR: Can't set rate. %s\n", snd_strerror(pcm));

        return 1;
    }

    /* Write parameters */
    if(pcm = snd_pcm_hw_params(pcm_handle, params) < 0) {
        printf("ERROR: Can't set harware parameters. %s\n", snd_strerror(pcm));

        return 1;
    }

    printf("PCM name: '%s'\n", snd_pcm_name(pcm_handle));
    printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));

    int ch;
    snd_pcm_hw_params_get_channels(params, &ch);

    if(ch > 1) {
        printf("Channels: %i, stereo\n", ch);
    }
    else if(ch == 1) {
        printf("Channels: %i, mono\n", ch);
    }

    snd_pcm_hw_params_get_rate(params, &ch, 0);
    printf("Rate: %d bps\n", ch);

    int dir;
    snd_pcm_uframes_t frames = 1024;

    printf("Attempting to set frames to %d\n", frames);

    snd_pcm_hw_params_set_period_size_near(pcm_handle, params, &frames, &dir);

    snd_pcm_hw_params(pcm_handle, params);

    snd_pcm_hw_params_get_period_size(params, &frames, 0);

    printf("Frames is now: %zd\n", frames);

    snd_pcm_hw_params_get_period_time(params, &ch, NULL);

    int buffer_size = 52430;

    printf("Attempting to set the buffer size to: %d\n", buffer_size);

    snd_pcm_hw_params_set_buffer_size(pcm_handle, params, buffer_size);

    snd_pcm_hw_params(pcm_handle, params);

    snd_pcm_uframes_t temp;

    snd_pcm_hw_params_get_buffer_size(params, &temp);

    printf("Buffer size is now: %d\n", temp);

    return 0;
}

调用
snd_pcm_hw_params()
后,所有参数都是固定的。在第一次(也是唯一一次)调用
snd\u pcm\u hw\u params\u set\u period\u size\u near()之前,您必须调用
snd\u pcm\u hw\u params()

默认
设备的输出是什么?@CL我已经用这些信息更新了我的问题。谢谢。hw_params.c的输出不是针对
hw
,而是针对
default
设备?啊,很抱歉。我再次更新了问题,以反映“默认”设备的输出。看起来像PulseAudio。但这也允许不同的周期大小;您的程序实际使用的设备名称是什么?
Device: default (type: IOPLUG)
Access types: RW_INTERLEAVED
Formats: U8 S16_LE S16_BE S24_LE S24_BE S32_LE S32_BE FLOAT_LE FLOAT_BE MU_LAW A_LAW S24_3LE S24_3BE
Channels: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
Sample rates: 1-192000
Interrupt interval: 5-4294967295 us
Buffer size: 15-4294967295 us
/**
 * Attempting to set some parameters.
 *
 * Using the template from: http://equalarea.com/paul/alsa-audio.html
 *
 **/

#include <alsa/asoundlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>

#define PCM_DEVICE "default"

int main(int argc, char **argv)
{
    unsigned int pcm;
    snd_pcm_t *pcm_handle;
    snd_pcm_hw_params_t *params;

    /* Open the PCM device in playback mode */
    if(pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        printf("ERROR: Can't open \"%s\" PCM device. %s\n", PCM_DEVICE, snd_strerror(pcm));

        return 1;
    }

    /* Allocate parameters object and fill it with default values*/
    snd_pcm_hw_params_alloca(&params);

    snd_pcm_hw_params_any(pcm_handle, params);

    /* Set parameters */
    if(pcm = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
        printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(pcm));

        return 1;
    }

    if(pcm = snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_FLOAT) < 0) {
        printf("ERROR: Can't set format. %s\n", snd_strerror(pcm));

        return 1;
    }

    int channels = 2;
    if(pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, channels) < 0) {
        printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));

        return 1;
    }

    int rate = 44100;
    if(pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0) < 0) {
        printf("ERROR: Can't set rate. %s\n", snd_strerror(pcm));

        return 1;
    }

    /* Write parameters */
    if(pcm = snd_pcm_hw_params(pcm_handle, params) < 0) {
        printf("ERROR: Can't set harware parameters. %s\n", snd_strerror(pcm));

        return 1;
    }

    printf("PCM name: '%s'\n", snd_pcm_name(pcm_handle));
    printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));

    int ch;
    snd_pcm_hw_params_get_channels(params, &ch);

    if(ch > 1) {
        printf("Channels: %i, stereo\n", ch);
    }
    else if(ch == 1) {
        printf("Channels: %i, mono\n", ch);
    }

    snd_pcm_hw_params_get_rate(params, &ch, 0);
    printf("Rate: %d bps\n", ch);

    int dir;
    snd_pcm_uframes_t frames = 1024;

    printf("Attempting to set frames to %d\n", frames);

    snd_pcm_hw_params_set_period_size_near(pcm_handle, params, &frames, &dir);

    snd_pcm_hw_params(pcm_handle, params);

    snd_pcm_hw_params_get_period_size(params, &frames, 0);

    printf("Frames is now: %zd\n", frames);

    snd_pcm_hw_params_get_period_time(params, &ch, NULL);

    int buffer_size = 52430;

    printf("Attempting to set the buffer size to: %d\n", buffer_size);

    snd_pcm_hw_params_set_buffer_size(pcm_handle, params, buffer_size);

    snd_pcm_hw_params(pcm_handle, params);

    snd_pcm_uframes_t temp;

    snd_pcm_hw_params_get_buffer_size(params, &temp);

    printf("Buffer size is now: %d\n", temp);

    return 0;
}
PCM name: 'default'
PCM state: PREPARED
Channels: 2, stereo
Rate: 44100 bps
Attempting to set frames to 1024
Frames is now: 512
Attempting to set the buffer size to: 52430
Buffer size is now: 524288