Partition: pass configuration as struct

This commit is contained in:
Max Kellermann 2021-12-03 20:22:52 +01:00
parent 2384a240e0
commit 95a155b10d
15 changed files with 230 additions and 105 deletions

View File

@ -279,6 +279,8 @@ sources = [
'src/command/PartitionCommands.cxx',
'src/command/OtherCommands.cxx',
'src/command/CommandListBuilder.cxx',
'src/config/PartitionConfig.cxx',
'src/config/PlayerConfig.cxx',
'src/Idle.cxx',
'src/IdleFlags.cxx',
'src/decoder/Thread.cxx',

View File

@ -32,7 +32,6 @@
#include "command/AllCommands.hxx"
#include "Partition.hxx"
#include "tag/Config.hxx"
#include "ReplayGainGlobal.hxx"
#include "IdleFlags.hxx"
#include "Log.hxx"
#include "LogInit.hxx"
@ -46,7 +45,6 @@
#include "playlist/PlaylistRegistry.hxx"
#include "zeroconf/Glue.hxx"
#include "decoder/DecoderList.hxx"
#include "pcm/AudioParser.hxx"
#include "pcm/Convert.hxx"
#include "unix/SignalHandlers.hxx"
#include "thread/Slack.hxx"
@ -60,6 +58,7 @@
#include "config/Option.hxx"
#include "config/Domain.hxx"
#include "config/Parser.hxx"
#include "config/PartitionConfig.hxx"
#include "util/RuntimeError.hxx"
#include "util/ScopeExit.hxx"
@ -116,15 +115,6 @@
#include <clocale>
#endif
static constexpr size_t KILOBYTE = 1024;
static constexpr size_t MEGABYTE = 1024 * KILOBYTE;
static constexpr size_t DEFAULT_BUFFER_SIZE = 4 * MEGABYTE;
static constexpr
size_t MIN_BUFFER_SIZE = std::max(CHUNK_SIZE * 32,
64 * KILOBYTE);
#ifdef ANDROID
Context *context;
LogListener *logListener;
@ -132,13 +122,6 @@ LogListener *logListener;
Instance *global_instance;
struct Config {
ReplayGainConfig replay_gain;
explicit Config(const ConfigData &raw)
:replay_gain(LoadReplayGainConfig(raw)) {}
};
#ifdef ENABLE_DAEMON
static void
@ -293,53 +276,11 @@ glue_state_file_init(Instance &instance, const ConfigData &raw_config)
static void
initialize_decoder_and_player(Instance &instance,
const ConfigData &config,
const ReplayGainConfig &replay_gain_config)
const PartitionConfig &partition_config)
{
const ConfigParam *param;
size_t buffer_size;
param = config.GetParam(ConfigOption::AUDIO_BUFFER_SIZE);
if (param != nullptr) {
buffer_size = param->With([](const char *s){
size_t result = ParseSize(s, KILOBYTE);
if (result <= 0)
throw FormatRuntimeError("buffer size \"%s\" is not a "
"positive integer", s);
if (result < MIN_BUFFER_SIZE) {
FmtWarning(config_domain, "buffer size {} is too small, using {} bytes instead",
result, MIN_BUFFER_SIZE);
result = MIN_BUFFER_SIZE;
}
return result;
});
} else
buffer_size = DEFAULT_BUFFER_SIZE;
const unsigned buffered_chunks = buffer_size / CHUNK_SIZE;
if (buffered_chunks >= 1 << 15)
throw FormatRuntimeError("buffer size \"%lu\" is too big",
(unsigned long)buffer_size);
const unsigned max_length =
config.GetPositive(ConfigOption::MAX_PLAYLIST_LENGTH,
DEFAULT_PLAYLIST_MAX_LENGTH);
AudioFormat configured_audio_format = config.With(ConfigOption::AUDIO_OUTPUT_FORMAT, [](const char *s){
if (s == nullptr)
return AudioFormat::Undefined();
return ParseAudioFormat(s, true);
});
instance.partitions.emplace_back(instance,
"default",
max_length,
buffered_chunks,
configured_audio_format,
replay_gain_config);
partition_config);
auto &partition = instance.partitions.back();
partition.replay_gain_mode = config.With(ConfigOption::REPLAYGAIN, [](const char *s){
@ -392,7 +333,7 @@ MainConfigured(const CommandLineOptions &options,
#endif
InitPathParser(raw_config);
const Config config(raw_config);
const PartitionConfig partition_config{raw_config};
#ifdef ENABLE_DAEMON
glue_daemonize_init(options, raw_config);
@ -426,7 +367,7 @@ MainConfigured(const CommandLineOptions &options,
}
initialize_decoder_and_player(instance,
raw_config, config.replay_gain);
raw_config, partition_config);
listen_global_init(raw_config, *instance.partitions.front().listener);
@ -465,7 +406,7 @@ MainConfigured(const CommandLineOptions &options,
partition.outputs.Configure(instance.io_thread.GetEventLoop(),
instance.rtio_thread.GetEventLoop(),
raw_config,
config.replay_gain);
partition_config.player.replay_gain);
partition.UpdateEffectiveReplayGainMode();
}

View File

@ -21,6 +21,7 @@
#include "Partition.hxx"
#include "Instance.hxx"
#include "Log.hxx"
#include "config/PartitionConfig.hxx"
#include "lib/fmt/ExceptionFormatter.hxx"
#include "song/DetachedSong.hxx"
#include "mixer/Volume.hxx"
@ -34,21 +35,18 @@ static constexpr Domain cache_domain("cache");
Partition::Partition(Instance &_instance,
const char *_name,
unsigned max_length,
unsigned buffer_chunks,
AudioFormat configured_audio_format,
const ReplayGainConfig &replay_gain_config) noexcept
const PartitionConfig &_config) noexcept
:instance(_instance),
name(_name),
config(_config),
listener(new ClientListener(instance.event_loop, *this)),
idle_monitor(instance.event_loop, BIND_THIS_METHOD(OnIdleMonitor)),
global_events(instance.event_loop, BIND_THIS_METHOD(OnGlobalEvent)),
playlist(max_length, *this),
playlist(config.queue.max_length, *this),
outputs(pc, *this),
pc(*this, outputs,
instance.input_cache.get(),
buffer_chunks,
configured_audio_format, replay_gain_config)
config.player)
{
UpdateEffectiveReplayGainMode();
}

View File

@ -38,6 +38,7 @@
#include <string>
#include <memory>
struct PartitionConfig;
struct Instance;
struct RangeArg;
class MultipleOutputs;
@ -58,6 +59,8 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
const std::string name;
const PartitionConfig &config;
std::unique_ptr<ClientListener> listener;
boost::intrusive::list<Client,
@ -82,10 +85,7 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
Partition(Instance &_instance,
const char *_name,
unsigned max_length,
unsigned buffer_chunks,
AudioFormat configured_audio_format,
const ReplayGainConfig &replay_gain_config) noexcept;
const PartitionConfig &_config) noexcept;
~Partition() noexcept;

View File

@ -33,6 +33,7 @@
#include "config/Data.hxx"
#include "config/Option.hxx"
#include "config/Defaults.hxx"
#include "config/QueueConfig.hxx"
#include "Idle.hxx"
#include "fs/Limits.hxx"
#include "fs/Traits.hxx"
@ -55,7 +56,7 @@ spl_global_init(const ConfigData &config)
{
playlist_max_length =
config.GetPositive(ConfigOption::MAX_PLAYLIST_LENGTH,
DEFAULT_PLAYLIST_MAX_LENGTH);
QueueConfig::DEFAULT_MAX_LENGTH);
playlist_saveAbsolutePaths =
config.GetBool(ConfigOption::SAVE_ABSOLUTE_PATHS,

View File

@ -101,11 +101,7 @@ handle_newpartition(Client &client, Request request, Response &response)
}
instance.partitions.emplace_back(instance, name,
// TODO: use real configuration
16384,
1024,
AudioFormat::Undefined(),
ReplayGainConfig());
client.GetPartition().config);
auto &partition = instance.partitions.back();
partition.UpdateEffectiveReplayGainMode();

View File

@ -20,7 +20,6 @@
#ifndef MPD_CONFIG_DEFAULTS_HXX
#define MPD_CONFIG_DEFAULTS_HXX
static constexpr unsigned DEFAULT_PLAYLIST_MAX_LENGTH = 16 * 1024;
static constexpr bool DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS = false;
#endif

View File

@ -0,0 +1,29 @@
/*
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "PartitionConfig.hxx"
#include "Data.hxx"
PartitionConfig::PartitionConfig(const ConfigData &config)
:player(config)
{
queue.max_length =
config.GetPositive(ConfigOption::MAX_PLAYLIST_LENGTH,
QueueConfig::DEFAULT_MAX_LENGTH);
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#include "QueueConfig.hxx"
#include "PlayerConfig.hxx"
struct PartitionConfig {
QueueConfig queue;
PlayerConfig player;
PartitionConfig() = default;
explicit PartitionConfig(const ConfigData &config);
};

View File

@ -0,0 +1,67 @@
/*
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "PartitionConfig.hxx"
#include "Data.hxx"
#include "Domain.hxx"
#include "Parser.hxx"
#include "pcm/AudioParser.hxx"
#include "util/RuntimeError.hxx"
#include "Log.hxx"
#include "MusicChunk.hxx"
#include "ReplayGainGlobal.hxx"
static constexpr
size_t MIN_BUFFER_SIZE = std::max(CHUNK_SIZE * 32,
64 * KILOBYTE);
PlayerConfig::PlayerConfig(const ConfigData &config)
{
size_t buffer_size = PlayerConfig::DEFAULT_BUFFER_SIZE;
if (auto *param = config.GetParam(ConfigOption::AUDIO_BUFFER_SIZE)) {
buffer_size = param->With([](const char *s){
size_t result = ParseSize(s, KILOBYTE);
if (result <= 0)
throw FormatRuntimeError("buffer size \"%s\" is not a "
"positive integer", s);
if (result < MIN_BUFFER_SIZE) {
FmtWarning(config_domain, "buffer size {} is too small, using {} bytes instead",
result, MIN_BUFFER_SIZE);
result = MIN_BUFFER_SIZE;
}
return result;
});
}
buffer_chunks = buffer_size / CHUNK_SIZE;
if (buffer_chunks >= 1 << 15)
throw FormatRuntimeError("buffer size \"%lu\" is too big",
(unsigned long)buffer_size);
audio_format = config.With(ConfigOption::AUDIO_OUTPUT_FORMAT, [](const char *s){
if (s == nullptr)
return AudioFormat::Undefined();
return ParseAudioFormat(s, true);
});
replay_gain = LoadReplayGainConfig(config);
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#include "pcm/AudioFormat.hxx"
#include "ReplayGainConfig.hxx"
struct ConfigData;
static constexpr size_t KILOBYTE = 1024;
static constexpr size_t MEGABYTE = 1024 * KILOBYTE;
struct PlayerConfig {
static constexpr size_t DEFAULT_BUFFER_SIZE = 4 * MEGABYTE;
unsigned buffer_chunks = DEFAULT_BUFFER_SIZE;
/**
* The "audio_output_format" setting.
*/
AudioFormat audio_format = AudioFormat::Undefined();
ReplayGainConfig replay_gain;
PlayerConfig() = default;
explicit PlayerConfig(const ConfigData &config);
};

View File

@ -0,0 +1,26 @@
/*
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
struct QueueConfig {
static constexpr unsigned DEFAULT_MAX_LENGTH = 16 * 1024;
unsigned max_length = DEFAULT_MAX_LENGTH;
};

View File

@ -28,15 +28,12 @@
PlayerControl::PlayerControl(PlayerListener &_listener,
PlayerOutputs &_outputs,
InputCacheManager *_input_cache,
unsigned _buffer_chunks,
AudioFormat _configured_audio_format,
const ReplayGainConfig &_replay_gain_config) noexcept
const PlayerConfig &_config) noexcept
:listener(_listener), outputs(_outputs),
input_cache(_input_cache),
buffer_chunks(_buffer_chunks),
configured_audio_format(_configured_audio_format),
thread(BIND_THIS_METHOD(RunThread)),
replay_gain_config(_replay_gain_config)
config(_config),
thread(BIND_THIS_METHOD(RunThread))
{
}

View File

@ -21,13 +21,13 @@
#define MPD_PLAYER_CONTROL_HXX
#include "output/Client.hxx"
#include "config/PlayerConfig.hxx"
#include "pcm/AudioFormat.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "thread/Thread.hxx"
#include "CrossFade.hxx"
#include "Chrono.hxx"
#include "ReplayGainConfig.hxx"
#include "ReplayGainMode.hxx"
#include "MusicChunkPtr.hxx"
@ -36,6 +36,7 @@
#include <memory>
struct Tag;
struct PlayerConfig;
class PlayerListener;
class PlayerOutputs;
class InputCacheManager;
@ -118,12 +119,7 @@ class PlayerControl final : public AudioOutputClient {
InputCacheManager *const input_cache;
const unsigned buffer_chunks;
/**
* The "audio_output_format" setting.
*/
const AudioFormat configured_audio_format;
const PlayerConfig config;
/**
* The handle of the player thread.
@ -229,17 +225,13 @@ class PlayerControl final : public AudioOutputClient {
CrossFadeSettings cross_fade;
const ReplayGainConfig replay_gain_config;
FloatDuration total_play_time = FloatDuration::zero();
public:
PlayerControl(PlayerListener &_listener,
PlayerOutputs &_outputs,
InputCacheManager *_input_cache,
unsigned buffer_chunks,
AudioFormat _configured_audio_format,
const ReplayGainConfig &_replay_gain_config) noexcept;
const PlayerConfig &_config) noexcept;
~PlayerControl() noexcept;
void Kill() noexcept;

View File

@ -1165,11 +1165,11 @@ try {
DecoderControl dc(mutex, cond,
input_cache,
configured_audio_format,
replay_gain_config);
config.audio_format,
config.replay_gain);
dc.StartThread();
MusicBuffer buffer(buffer_chunks);
MusicBuffer buffer{config.buffer_chunks};
std::unique_lock<Mutex> lock(mutex);