c - 每秒发送数据数小于params,如何每秒发送更多数据?

标签 c alsa

这个功能是在linux下使用alsa库播放音频数据。但是有一个问题,发送的数据小于设置的参数。

    int main()   
    {   
    int rc = 0;  
    snd_pcm_t *handle;  
    snd_pcm_hw_params_t *params;  
    int dir = 0;  
    char *buffer;  
    int size=0;  
    int val = 0;  
    int frames = 0;  
    int min,max;  
    int period_time;  
    snd_pcm_sframes_t delay,buffer_size,period_size,avail; 
    //through kill signal to statistics the number of send data
    signal(SIGUSR1, sigproc_status);  
    rc = snd_pcm_open(&handle,"default",SND_PCM_STREAM_PLAYBACK,0);  
    if(rc < 0)  
    {  
            printf("unable to open pcm device\n");  
            return -1;  
    }  
    snd_pcm_hw_params_alloca(&params);  
    snd_pcm_hw_params_any(handle,params);  
  snd_pcm_hw_params_set_access(handle,params,SND_PCM_ACCESS_RW_INTERLEAVED);  
    //set 16bit
    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
    //set two channels
    snd_pcm_hw_params_set_channels(handle,params,2);  
    val = 44100;  
    //set rate is 44.1k
    snd_pcm_hw_params_set_rate_near(handle,params,&val,&dir);
    rc = snd_pcm_hw_params(handle,params);  
    if(rc < 0)  
    {  
            printf("unable to set params\n");  
            return -1;  
    }  
    snd_pcm_hw_params_current(handle,params);
    snd_pcm_hw_params_get_period_time(params, &period_time,NULL);  
    frames = 32;  
    snd_pcm_hw_params_get_period_size(params,&frames,&dir); 
    size = frames*4;   
    buffer = (char *)malloc(size);   
    while(1)  
    {    
            len = len + size;  
            rc = snd_pcm_writei(handle,buffer,frames);    
            if(rc == -EPIPE)    
            {     
                    printf("underrun occur\n");   
                    snd_pcm_prepare(handle);   
            }   
    }  
    }

period_time=21333 帧=940,所以 (1000000/21333)*940*4=176252bytes
但参数是 44100*4=176400bytes
所以我们需要每秒丢弃一些字节。
如何发送更多字节?

最佳答案

您正在使用 dmix 的默认配置,这需要从 44.1 kHz 重新采样到 48 kHz。 ALSA 的内部重采样器始终适用于整个周期,因此您必须使用的周期大小为 1024*44.1/48 = 940(向下舍入)。

要强制周期大小为 941,请使用频率 44110。

如果您想避免重新采样,如果可能的话,请打开设备 plughw:0 而不是 default,但这样您就会失去多客户端混合功能。 (然后您应该根据您的要求配置缓冲区/周期大小。)

关于c - 每秒发送数据数小于params,如何每秒发送更多数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52308469/

相关文章:

c++ - 哪个更快 : x<<1 or x<<10?

java - 左倾树+符号表

linux - 阿尔萨。如何以编程方式更改设备 ID?

linux - ALSA 的 snd_pcm_delay() 究竟返回什么?

c - C 中的优先级队列实现 - 将字符更改为整数

c - _GNU_、_attribute_ 和 pragma 扩展和指令的含义是什么

linux - Linux 中的实时音频分析

c++ - Linux,C++ 音频捕获(只是麦克风)库

android - ALSA - 取消设备静音?

c - 显示窗口时 GtkTreeView 返回错误,其他 GtkTreeView 不显示