mirror of
https://github.com/badaix/snapcast.git
synced 2025-07-31 07:09:44 +02:00
Make buffer time and fragments configurable
This commit is contained in:
parent
2e64e53b5d
commit
c1a5a52bc6
5 changed files with 48 additions and 18 deletions
|
@ -22,11 +22,14 @@
|
||||||
#include "common/str_compat.hpp"
|
#include "common/str_compat.hpp"
|
||||||
#include "common/utils/string_utils.hpp"
|
#include "common/utils/string_utils.hpp"
|
||||||
|
|
||||||
//#define BUFFER_TIME 120000
|
using namespace std::chrono_literals;
|
||||||
#define PERIOD_TIME 30000
|
using namespace std;
|
||||||
|
|
||||||
|
static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms;
|
||||||
|
static constexpr int PERIODS = 4;
|
||||||
|
|
||||||
#define exp10(x) (exp((x)*log(10)))
|
#define exp10(x) (exp((x)*log(10)))
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "Alsa";
|
static constexpr auto LOG_TAG = "Alsa";
|
||||||
static constexpr auto DEFAULT_MIXER = "PCM";
|
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";
|
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)
|
if ((err = snd_pcm_hw_params_set_rate_near(handle_, params, &rate, nullptr)) < 0)
|
||||||
throw SnapException("Can't set rate: " + string(snd_strerror(err)));
|
throw SnapException("Can't set rate: " + string(snd_strerror(err)));
|
||||||
|
|
||||||
unsigned int period_time;
|
unsigned int buffer_time = buffer_time_.count();
|
||||||
snd_pcm_hw_params_get_period_time_max(params, &period_time, nullptr);
|
if ((err = snd_pcm_hw_params_set_buffer_time_near(handle_, params, &buffer_time, nullptr)) < 0)
|
||||||
if (period_time > PERIOD_TIME)
|
throw SnapException("Can't set buffer time: " + string(snd_strerror(err)));
|
||||||
period_time = PERIOD_TIME;
|
|
||||||
|
|
||||||
unsigned int buffer_time = 4 * period_time;
|
if ((err = snd_pcm_hw_params_set_periods(handle_, params, periods_, 0)) < 0)
|
||||||
|
throw SnapException("Can't set periods: " + string(snd_strerror(err)));
|
||||||
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);
|
|
||||||
|
|
||||||
// long unsigned int periodsize = stream_->format.msRate() * 50;//2*rate/50;
|
// 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)
|
// 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);
|
snd_pcm_hw_params_get_period_size(params, &frames_, nullptr);
|
||||||
LOG(DEBUG, LOG_TAG) << "frames: " << frames_ << "\n";
|
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);
|
snd_pcm_hw_params_get_period_time(params, &tmp, nullptr);
|
||||||
LOG(DEBUG, LOG_TAG) << "period time: " << tmp << "\n";
|
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_t* swparams;
|
||||||
snd_pcm_sw_params_alloca(&swparams);
|
snd_pcm_sw_params_alloca(&swparams);
|
||||||
snd_pcm_sw_params_current(handle_, swparams);
|
snd_pcm_sw_params_current(handle_, swparams);
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
#define ALSA_PLAYER_H
|
#define ALSA_PLAYER_H
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
|
||||||
/// Audio Player
|
/// Audio Player
|
||||||
|
@ -73,6 +75,9 @@ private:
|
||||||
std::chrono::time_point<std::chrono::steady_clock> last_change_;
|
std::chrono::time_point<std::chrono::steady_clock> last_change_;
|
||||||
std::recursive_mutex mutex_;
|
std::recursive_mutex mutex_;
|
||||||
boost::asio::steady_timer timer_;
|
boost::asio::steady_timer timer_;
|
||||||
|
|
||||||
|
std::chrono::microseconds buffer_time_;
|
||||||
|
unsigned int periods_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,11 @@
|
||||||
#include "common/utils/string_utils.hpp"
|
#include "common/utils/string_utils.hpp"
|
||||||
#include "pulse_player.hpp"
|
#include "pulse_player.hpp"
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms;
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "PulsePlayer";
|
static constexpr auto LOG_TAG = "PulsePlayer";
|
||||||
|
|
||||||
// Example code:
|
// 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)
|
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, ',', '=');
|
auto params = utils::string::split_pairs(settings.parameter, ',', '=');
|
||||||
if (params.find("latency") != params.end())
|
if (params.find("buffer_time") != params.end())
|
||||||
{
|
latency_ = std::chrono::milliseconds(std::max(cpt::stoi(params["buffer_time"]), 10));
|
||||||
latency_ = std::chrono::milliseconds(std::max(cpt::stoi(params["latency"]), 10));
|
|
||||||
}
|
LOG(INFO, LOG_TAG) << "Using buffer_time: " << latency_.count() / 1000 << " ms\n";
|
||||||
LOG(INFO, LOG_TAG) << "Using latency: " << latency_.count() / 1000 << " ms\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define PULSE_PLAYER_HPP
|
#define PULSE_PLAYER_HPP
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <pulse/pulseaudio.h>
|
#include <pulse/pulseaudio.h>
|
||||||
|
|
|
@ -335,7 +335,13 @@ int main(int argc, char** argv)
|
||||||
else if (settings.player.player_name == "pulse")
|
else if (settings.player.player_name == "pulse")
|
||||||
{
|
{
|
||||||
cout << "Options are a comma separated list of:\n"
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue