-2

this funtion is to play audio data use alsa libs in linux.but have a question,the send data is less than set params.

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

the period_time=21333 frames=940,so (1000000/21333)*940*4=176252bytes
but params is 44100*4=176400bytes
so we need to discard some bytes every sencond.
how to send more bytes?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
yanlm
  • 1

1 Answers1

0

You are using the default configuration with dmix, which requires resampling from 44.1 kHz to 48 kHz. ALSA's internal resampler always works on entire periods, so the period size you are forced to use is 1024*44.1/48 = 940 (rounded down).

To force a period size of 941, use a frequency of 44110.

If you want to avoid resampling, if possible, open the device plughw:0 instead of default, but then you lose the multi-client mixing capability. (And then you should configure buffer/period sizes according to your requirements.)

CL.
  • 173,858
  • 17
  • 217
  • 259