X-Git-Url: https://git.sesse.net/?p=nageru;a=blobdiff_plain;f=alsa_output.cpp;h=7dd10244b094d83b9f93c65af0b8e87dc4e5a5c6;hp=52f4936924f7a84570b92aa168af9a79321a735d;hb=refs%2Fheads%2Fmultichannel_audio;hpb=194872611b21bb070f4dfcf5beda6c36d25459ea diff --git a/alsa_output.cpp b/alsa_output.cpp index 52f4936..7dd1024 100644 --- a/alsa_output.cpp +++ b/alsa_output.cpp @@ -1,5 +1,9 @@ #include "alsa_output.h" +#include +#include +#include +#include #include using namespace std; @@ -17,7 +21,7 @@ void die_on_error(const char *func_name, int err) } // namespace ALSAOutput::ALSAOutput(int sample_rate, int num_channels) - : num_channels(num_channels) + : sample_rate(sample_rate), num_channels(num_channels) { die_on_error("snd_pcm_open()", snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0)); @@ -31,17 +35,24 @@ ALSAOutput::ALSAOutput(int sample_rate, int num_channels) die_on_error("snd_pcm_hw_params_set_channels", snd_pcm_hw_params_set_channels(pcm_handle, hw_params, num_channels)); // Fragment size of 512 samples. (A frame at 60 fps/48 kHz is 800 samples.) - // We ask for four such periods. - unsigned int num_periods = 4; + // We ask for 16 such periods (~170 ms buffer). + unsigned int num_periods = 16; int dir = 0; - die_on_error("snd_pcm_hw_params_set_periods_near", snd_pcm_hw_params_set_periods_near(pcm_handle, hw_params, &num_periods, &dir)); + die_on_error("snd_pcm_hw_params_set_periods_near()", snd_pcm_hw_params_set_periods_near(pcm_handle, hw_params, &num_periods, &dir)); period_size = 512; dir = 0; - die_on_error("snd_pcm_hw_params_set_period_size_near", snd_pcm_hw_params_set_period_size_near(pcm_handle, hw_params, &period_size, &dir)); - die_on_error("snd_pcm_hw_params", snd_pcm_hw_params(pcm_handle, hw_params)); + die_on_error("snd_pcm_hw_params_set_period_size_near()", snd_pcm_hw_params_set_period_size_near(pcm_handle, hw_params, &period_size, &dir)); + die_on_error("snd_pcm_hw_params()", snd_pcm_hw_params(pcm_handle, hw_params)); //snd_pcm_hw_params_free(hw_params); + snd_pcm_sw_params_t *sw_params; + snd_pcm_sw_params_alloca(&sw_params); + die_on_error("snd_pcm_sw_params_current()", snd_pcm_sw_params_current(pcm_handle, sw_params)); + die_on_error("snd_pcm_sw_params_set_start_threshold", snd_pcm_sw_params_set_start_threshold(pcm_handle, sw_params, num_periods * period_size / 2)); + die_on_error("snd_pcm_sw_params()", snd_pcm_sw_params(pcm_handle, sw_params)); + die_on_error("snd_pcm_nonblock", snd_pcm_nonblock(pcm_handle, 1)); + die_on_error("snd_pcm_prepare()", snd_pcm_prepare(pcm_handle)); } void ALSAOutput::write(const vector &samples) @@ -72,7 +83,8 @@ try_again: if (ret == 0) { if (buffer.size() >= period_size * num_channels * 8) { // OK, almost 100 ms. Giving up. - fprintf(stderr, "warning: ALSA overrun, dropping some audio\n"); + fprintf(stderr, "warning: ALSA overrun, dropping some audio (%d ms)\n", + int(buffer.size() * 1000 / (num_channels * sample_rate))); buffer.clear(); } } else if (ret > 0) {