2016-10-26 9 views
1
My requirement is to play 16 bit, 22KHz linear PCM data to audioout using alsa API. I have added 2 section of code which i have written to configure ALSA and audioout wrapper which writes 2048 frames using write API. 

Проблема: Получение искаженного шума и потребляя доступные кадры очень быстрокадров во время воспроизведения аудио потребляется очень быстро

Я настройке ALSA, используя ниже API.

//opening audio handle 

    if ((err = snd_pcm_open (&rsettings->ppcm_handle, name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) 
{ 
     return -1; 
} 


if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) 
{ 
     return -1; 
} 

if ((err = snd_pcm_hw_params_any (rsettings->ppcm_handle, hw_params)) < 0) 
{ 
     return -1; 
} 

//setting interleaved mode 
if ((err = snd_pcm_hw_params_set_access (rsettings->ppcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) 
{ 
     return -1; 
} 
//setting bit depth to 2 byte 
if ((err = snd_pcm_hw_params_set_format (rsettings->ppcm_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) 
{ 
     return -1; 
} 

// Установка частоты дискретизации до 22050 Гц , если ((ERR = snd_pcm_hw_params_set_rate (rsettings-> ppcm_handle, hw_params, 22050, 0)) < 0) { возврата -1; }

// установка количества каналов до 1
, если ((ERR = snd_pcm_hw_params_set_channels (rsettings-> ppcm_handle, hw_params, 1)) < 0) { возврата -1; }

snd_pcm_uframes_t frame_size = 1024; 

    if((err = snd_pcm_hw_params_set_period_size_near(rsettings->ppcm_handle, hw_params, &frame_size, 0)) < 0) 
{ 
      printf("\n cannot set size"); 
      return -1; 
} 


// setting number of period to 1 
if ((err = snd_pcm_hw_params_set_periods(rsettings->ppcm_handle, hw_params, 1, 1)) < 0) 
{ 
     return -1; 
} 


frame_size = 2048; 
//setting buffer size to 2048 
if ((err = snd_pcm_hw_params_set_buffer_size_near(rsettings->ppcm_handle, hw_params, &frame_size)) < 0) 
{ 
     return -1; 
} 

if ((err = snd_pcm_nonblock (rsettings->ppcm_handle, 0)) < 0) 
{ 
     return -1; 
} 

if ((err = snd_pcm_hw_params (rsettings->ppcm_handle, hw_params)) < 0) 
{ 
     return -1; 
} 

snd_pcm_hw_params_free (hw_params); 

if ((err = snd_pcm_prepare (rsettings->ppcm_handle)) < 0) 
{ 
     return -1; 
} 

У меня есть audioout API, используя ПОЛЛИНГ ниже

noOfFrames = 2024 

    while(noOfFrames > 0) 
    {  
     if(0 > (poll(descriptors, pollDescriptorCount, 500))) 
     { 
      printf("error polling for data"); 

     } 
     else 
     { 
      printf("\nPoll Unblocked"); 

      if(0 > (retVal = snd_pcm_poll_descriptors_revents(rsettings->ppcm_handle, descriptors, pollDescriptorCount, &pollEvent))) 
      { 
       printf("\nError getting poll events, return value : %d", retVal); 
       break; 
      } 
      else 
      { 
       frames = snd_pcm_avail_update(rsettings->ppcm_handle); 
       printf("\nAvailable channel frames = %d",frames); 
       if(frames < 0) 
       { 
        if(frames == -EPIPE) 
        { 
         snd_pcm_prepare(rsettings->ppcm_handle); 
        } 
        else if(frames == -ESTRPIPE) 
        { 
         while (-EAGAIN == snd_pcm_resume(rsettings->ppcm_handle)) 
          usleep(2000); 
        } 
        else 
        { 
         snd_pcm_prepare(rsettings->ppcm_handle); 
        } 
       } 
       else 
       { 
        if(frames >= noOfFrames) 
        { 
         if ((framesWritten = snd_pcm_writei(rsettings->ppcm_handle, &pBuffer, noOfFrames)) > 0) 
         { 
          printf("\nNo of frames written : %d",framesWritten); 
          noOfFrames = noOfFrames - framesWritten; 
          free(descriptors); 

         } 

         else if(framesWritten < 0) 
         { 
          if(framesWritten == -EPIPE) 
          { 
           snd_pcm_prepare(rsettings->ppcm_handle); 
          } 
          else if(framesWritten == -ESTRPIPE) 
          { 
           while (-EAGAIN == snd_pcm_resume(rsettings->ppcm_handle)) 
            usleep(2000); 
          } 
          else 
          { 
           snd_pcm_prepare(rsettings->ppcm_handle); 
          } 
         } 
        } 
        else 
        { 
         if ((framesWritten = snd_pcm_writei(rsettings->ppcm_handle, &pBuffer, frames)) > 0) 
         { 
          printf("\nNo of frames written : %d",framesWritten); 
          noOfFrames = noOfFrames - framesWritten; 
          free(descriptors); 


         } 

         else if(framesWritten < 0) 
         { 
          if(framesWritten == -EPIPE) 
          { 
           snd_pcm_prepare(rsettings->ppcm_handle); 
          } 
          else if(framesWritten == -ESTRPIPE) 
          { 
           while (-EAGAIN == snd_pcm_resume(rsettings->ppcm_handle)) 
            usleep(2000); 
          } 
          else 
          { 
           snd_pcm_prepare(rsettings->ppcm_handle); 
          } 
         } 
        } 
       } 
      } 

     } 
    } 

Может кто-нибудь сказать, где я буду неправильно.

+0

Эти 'бесплатные (дескрипторы);' вызовы выглядят подозрительными. –

+0

Работает ли 'aplay'? –

+0

Да aplay works – Shrinock

ответ

1

Опрос для заполнения буферов Audio Unit с запрошенным объемом данных не будет работать. Для заполнения звуковых буферов вы должны использовать процедуры обратного вызова Audio Unit (которые вызываются ОС с использованием потока с меньшей задержкой в ​​реальном времени).

Вы можете опросить, чтобы предварительно заполнить замкнутый круглый fifo с достаточным количеством образцов звука для обратных вызовов Audio Unit для копирования.