gpt4 book ai didi

linux - 音频播放期间的帧消耗非常快

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:43:21 26 4
gpt4 key购买 nike

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.

问题:获取失真的噪声并非常快地消耗可用帧

我正在使用以下 api 配置 ALSA。

//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 Hz 如果 ((err = snd_pcm_hw_params_set_rate(rsettings->ppcm_handle, hw_params, 22050, 0 ) ) < 0 ) { 返回-1;

//设置 channel 数为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;
}

我有如下使用 POLLING 的 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 );
}
}
}
}
}

}
}

有人能告诉我哪里错了吗?

最佳答案

轮询以仅使用请求的数据量填充音频单元缓冲区将不起作用。您必须使用音频单元回调例程(操作系统使用延迟较低的实时线程调用)来填充音频缓冲区。

您可以轮询以使用足够数量的音频样本预填充无锁循环 fifo,供音频单元回调从中复制。

关于linux - 音频播放期间的帧消耗非常快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40260536/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com