Make buffer time and fragments configurable

This commit is contained in:
badaix 2020-11-23 13:51:19 +01:00
parent 2e64e53b5d
commit c1a5a52bc6
5 changed files with 48 additions and 18 deletions

View file

@ -22,11 +22,14 @@
#include "common/str_compat.hpp"
#include "common/utils/string_utils.hpp"
//#define BUFFER_TIME 120000
#define PERIOD_TIME 30000
using namespace std::chrono_literals;
using namespace std;
static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms;
static constexpr int PERIODS = 4;
#define exp10(x) (exp((x)*log(10)))
using namespace std;
static constexpr auto LOG_TAG = "Alsa";
static constexpr auto DEFAULT_MIXER = "PCM";
@ -61,6 +64,16 @@ AlsaPlayer::AlsaPlayer(boost::asio::io_context& io_context, const ClientSettings
LOG(DEBUG, LOG_TAG) << "Mixer: " << mixer_name_ << ", device: " << mixer_device_ << "\n";
}
buffer_time_ = BUFFER_TIME;
periods_ = PERIODS;
auto params = utils::string::split_pairs(settings.parameter, ',', '=');
if (params.find("buffer_time") != params.end())
buffer_time_ = std::chrono::milliseconds(std::max(cpt::stoi(params["buffer_time"]), 10));
if (params.find("fragments") != params.end())
periods_ = std::max(cpt::stoi(params["fragments"]), 2);
LOG(INFO, LOG_TAG) << "Using buffer_time: " << buffer_time_.count() / 1000 << " ms, fragments: " << periods_ << "\n";
}
@ -334,15 +347,12 @@ void AlsaPlayer::initAlsa()
if ((err = snd_pcm_hw_params_set_rate_near(handle_, params, &rate, nullptr)) < 0)
throw SnapException("Can't set rate: " + string(snd_strerror(err)));
unsigned int period_time;
snd_pcm_hw_params_get_period_time_max(params, &period_time, nullptr);
if (period_time > PERIOD_TIME)
period_time = PERIOD_TIME;
unsigned int buffer_time = buffer_time_.count();
if ((err = snd_pcm_hw_params_set_buffer_time_near(handle_, params, &buffer_time, nullptr)) < 0)
throw SnapException("Can't set buffer time: " + string(snd_strerror(err)));
unsigned int buffer_time = 4 * period_time;
snd_pcm_hw_params_set_period_time_near(handle_, params, &period_time, nullptr);
snd_pcm_hw_params_set_buffer_time_near(handle_, params, &buffer_time, nullptr);
if ((err = snd_pcm_hw_params_set_periods(handle_, params, periods_, 0)) < 0)
throw SnapException("Can't set periods: " + string(snd_strerror(err)));
// long unsigned int periodsize = stream_->format.msRate() * 50;//2*rate/50;
// if ((pcm = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, params, &periodsize)) < 0)
@ -365,9 +375,15 @@ void AlsaPlayer::initAlsa()
snd_pcm_hw_params_get_period_size(params, &frames_, nullptr);
LOG(DEBUG, LOG_TAG) << "frames: " << frames_ << "\n";
snd_pcm_hw_params_get_buffer_time(params, &tmp, nullptr);
LOG(DEBUG, LOG_TAG) << "buffer time: " << tmp << "\n";
snd_pcm_hw_params_get_period_time(params, &tmp, nullptr);
LOG(DEBUG, LOG_TAG) << "period time: " << tmp << "\n";
snd_pcm_hw_params_get_periods(params, &tmp, nullptr);
LOG(DEBUG, LOG_TAG) << "periods: " << tmp << "\n";
snd_pcm_sw_params_t* swparams;
snd_pcm_sw_params_alloca(&swparams);
snd_pcm_sw_params_current(handle_, swparams);

View file

@ -20,7 +20,9 @@
#define ALSA_PLAYER_H
#include "player.hpp"
#include <alsa/asoundlib.h>
#include <chrono>
/// Audio Player
@ -73,6 +75,9 @@ private:
std::chrono::time_point<std::chrono::steady_clock> last_change_;
std::recursive_mutex mutex_;
boost::asio::steady_timer timer_;
std::chrono::microseconds buffer_time_;
unsigned int periods_;
};

View file

@ -25,8 +25,11 @@
#include "common/utils/string_utils.hpp"
#include "pulse_player.hpp"
using namespace std::chrono_literals;
using namespace std;
static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms;
static constexpr auto LOG_TAG = "PulsePlayer";
// Example code:
@ -36,14 +39,13 @@ static constexpr auto LOG_TAG = "PulsePlayer";
PulsePlayer::PulsePlayer(boost::asio::io_context& io_context, const ClientSettings::Player& settings, std::shared_ptr<Stream> stream)
: Player(io_context, settings, stream), latency_(100ms), pa_ml_(nullptr), pa_ctx_(nullptr), playstream_(nullptr)
: Player(io_context, settings, stream), latency_(BUFFER_TIME), pa_ml_(nullptr), pa_ctx_(nullptr), playstream_(nullptr)
{
auto params = utils::string::split_pairs(settings.parameter, ',', '=');
if (params.find("latency") != params.end())
{
latency_ = std::chrono::milliseconds(std::max(cpt::stoi(params["latency"]), 10));
}
LOG(INFO, LOG_TAG) << "Using latency: " << latency_.count() / 1000 << " ms\n";
if (params.find("buffer_time") != params.end())
latency_ = std::chrono::milliseconds(std::max(cpt::stoi(params["buffer_time"]), 10));
LOG(INFO, LOG_TAG) << "Using buffer_time: " << latency_.count() / 1000 << " ms\n";
}

View file

@ -20,6 +20,7 @@
#define PULSE_PLAYER_HPP
#include "player.hpp"
#include <cstdio>
#include <memory>
#include <pulse/pulseaudio.h>

View file

@ -335,7 +335,13 @@ int main(int argc, char** argv)
else if (settings.player.player_name == "pulse")
{
cout << "Options are a comma separated list of:\n"
<< " \"latency=<device latency [ms]>\" - default 100, min 10\n";
<< " \"buffer_time=<buffer size [ms]>\" - default 80, min 10\n";
}
else if (settings.player.player_name == "alsa")
{
cout << "Options are a comma separated list of:\n"
<< " \"buffer_time=<total buffer size [ms]>\" - default 80, min 10\n"
<< " \"fragments=<number of buffers>\" - default 4, min 2\n";
}
else
{