要解决ALSA PCM在停止播放时出现点击/爆音的问题,可以尝试以下方法:
snd_pcm_hw_params_t *params;
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_hw_params_any(handle, params);
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(handle, params, channels);
snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0);
snd_pcm_hw_params_set_buffer_size(handle, params, buffer_size);
snd_pcm_hw_params(handle, params);
snd_pcm_sw_params_t *swparams;
snd_pcm_sw_params_alloca(&swparams);
snd_pcm_sw_params_current(handle, swparams);
snd_pcm_sw_params_set_avail_min(handle, swparams, frames);
snd_pcm_sw_params_set_start_threshold(handle, swparams, 0);
snd_pcm_sw_params_set_stop_threshold(handle, swparams, frames);
snd_pcm_sw_params(handle, swparams);
// 停止播放前逐渐减小音量
for (int i = 0; i < frames; i++) {
for (int ch = 0; ch < channels; ch++) {
buffer[i * channels + ch] *= (frames - i) / frames;
}
}
// 在停止播放前,将剩余的音频数据写入缓冲区
snd_pcm_sframes_t avail = snd_pcm_avail(handle);
if (avail > 0) {
snd_pcm_writei(handle, buffer, avail);
}
以上是一些常见的解决方法,具体的解决方案可能因环境和使用情况而异。