diff --git a/client/client_settings.hpp b/client/client_settings.hpp index 7900cc1b..2e12cb01 100644 --- a/client/client_settings.hpp +++ b/client/client_settings.hpp @@ -60,7 +60,7 @@ struct ClientSettings std::string player_name{""}; std::string parameter{""}; int latency{0}; - PcmDevice pcm_device; + player::PcmDevice pcm_device; SampleFormat sample_format; SharingMode sharing_mode{SharingMode::unspecified}; Mixer mixer; diff --git a/client/controller.cpp b/client/controller.cpp index 7e9eef13..eeba91f1 100644 --- a/client/controller.cpp +++ b/client/controller.cpp @@ -66,6 +66,7 @@ #include using namespace std; +using namespace player; static constexpr auto LOG_TAG = "Controller"; static constexpr auto TIME_SYNC_INTERVAL = 1s; @@ -92,24 +93,24 @@ std::vector Controller::getSupportedPlayerNames() { std::vector result; #ifdef HAS_ALSA - result.emplace_back("alsa"); + result.emplace_back(player::ALSA); #endif #ifdef HAS_PULSE - result.emplace_back("pulse"); + result.emplace_back(player::PULSE); #endif #ifdef HAS_OBOE - result.emplace_back("oboe"); + result.emplace_back(player::OBOE); #endif #ifdef HAS_OPENSL - result.emplace_back("opensl"); + result.emplace_back(player::OPENSL); #endif #ifdef HAS_COREAUDIO - result.emplace_back("coreaudio"); + result.emplace_back(player::COREAUDIO); #endif #ifdef HAS_WASAPI - result.emplace_back("wasapi"); + result.emplace_back(player::WASAPI); #endif - result.emplace_back("file"); + result.emplace_back(player::FILE); return result; } @@ -184,30 +185,30 @@ void Controller::getNextMessage() #ifdef HAS_ALSA if (!player_) - player_ = createPlayer(settings_.player, "alsa"); + player_ = createPlayer(settings_.player, player::ALSA); #endif #ifdef HAS_PULSE if (!player_) - player_ = createPlayer(settings_.player, "pulse"); + player_ = createPlayer(settings_.player, player::PULSE); #endif #ifdef HAS_OBOE if (!player_) - player_ = createPlayer(settings_.player, "oboe"); + player_ = createPlayer(settings_.player, player::OBOE); #endif #ifdef HAS_OPENSL if (!player_) - player_ = createPlayer(settings_.player, "opensl"); + player_ = createPlayer(settings_.player, player::OPENSL); #endif #ifdef HAS_COREAUDIO if (!player_) - player_ = createPlayer(settings_.player, "coreaudio"); + player_ = createPlayer(settings_.player, player::COREAUDIO); #endif #ifdef HAS_WASAPI if (!player_) - player_ = createPlayer(settings_.player, "wasapi"); + player_ = createPlayer(settings_.player, player::WASAPI); #endif - if (!player_ && (settings_.player.player_name == "file")) - player_ = createPlayer(settings_.player, "file"); + if (!player_ && (settings_.player.player_name == player::FILE)) + player_ = createPlayer(settings_.player, player::FILE); if (!player_) throw SnapException("No audio player support" + (settings_.player.player_name.empty() ? "" : " for: " + settings_.player.player_name)); diff --git a/client/controller.hpp b/client/controller.hpp index 494ec4e9..8564e2b7 100644 --- a/client/controller.hpp +++ b/client/controller.hpp @@ -16,8 +16,8 @@ along with this program. If not, see . ***/ -#ifndef CONTROLLER_H -#define CONTROLLER_H +#ifndef CONTROLLER_HPP +#define CONTROLLER_HPP #include "client_connection.hpp" #include "client_settings.hpp" @@ -55,7 +55,7 @@ private: void browseMdns(const MdnsHandler& handler); template - std::unique_ptr createPlayer(ClientSettings::Player& settings, const std::string& player_name); + std::unique_ptr createPlayer(ClientSettings::Player& settings, const std::string& player_name); void getNextMessage(); void sendTimeSyncMessage(int quick_syncs); @@ -68,7 +68,7 @@ private: std::unique_ptr clientConnection_; std::shared_ptr stream_; std::unique_ptr decoder_; - std::unique_ptr player_; + std::unique_ptr player_; std::unique_ptr meta_; std::unique_ptr serverSettings_; std::unique_ptr headerChunk_; diff --git a/client/player/alsa_player.cpp b/client/player/alsa_player.cpp index b379956d..bc7d0f07 100644 --- a/client/player/alsa_player.cpp +++ b/client/player/alsa_player.cpp @@ -25,6 +25,9 @@ using namespace std::chrono_literals; using namespace std; +namespace player +{ + static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms; static constexpr int PERIODS = 4; @@ -642,3 +645,5 @@ vector AlsaPlayer::pcm_list() snd_device_name_free_hint(hints); return result; } + +} // namespace player diff --git a/client/player/alsa_player.hpp b/client/player/alsa_player.hpp index 15d68f09..32219f89 100644 --- a/client/player/alsa_player.hpp +++ b/client/player/alsa_player.hpp @@ -16,8 +16,8 @@ along with this program. If not, see . ***/ -#ifndef ALSA_PLAYER_H -#define ALSA_PLAYER_H +#ifndef ALSA_PLAYER_HPP +#define ALSA_PLAYER_HPP #include "player.hpp" @@ -25,6 +25,11 @@ #include +namespace player +{ + +static constexpr auto ALSA = "alsa"; + /// Audio Player /** * Audio player implementation using Alsa @@ -81,5 +86,6 @@ private: unsigned int periods_; }; +} // namespace player #endif diff --git a/client/player/coreaudio_player.cpp b/client/player/coreaudio_player.cpp index 54bffed7..bf521265 100644 --- a/client/player/coreaudio_player.cpp +++ b/client/player/coreaudio_player.cpp @@ -19,6 +19,9 @@ #include "coreaudio_player.hpp" #include +namespace player +{ + #define NUM_BUFFERS 2 static constexpr auto LOG_TAG = "CoreAudioPlayer"; @@ -210,3 +213,5 @@ void CoreAudioPlayer::uninitAudioQueue(AudioQueueRef queue) pubStream_->clearChunks(); CFRunLoopStop(CFRunLoopGetCurrent()); } + +} // namespace player diff --git a/client/player/coreaudio_player.hpp b/client/player/coreaudio_player.hpp index aaaf27be..f42f1c5a 100644 --- a/client/player/coreaudio_player.hpp +++ b/client/player/coreaudio_player.hpp @@ -16,8 +16,8 @@ along with this program. If not, see . ***/ -#ifndef CORE_AUDIO_PLAYER_H -#define CORE_AUDIO_PLAYER_H +#ifndef CORE_AUDIO_PLAYER_HPP +#define CORE_AUDIO_PLAYER_HPP #include #include @@ -25,6 +25,11 @@ #include "player.hpp" +namespace player +{ + +static constexpr auto COREAUDIO = "coreaudio"; + /// Audio Player /** * Audio player implementation using CoreAudio @@ -58,5 +63,6 @@ protected: long lastChunkTick; }; +} // namespace player #endif diff --git a/client/player/file_player.cpp b/client/player/file_player.cpp index 9c11db3f..b2d11830 100644 --- a/client/player/file_player.cpp +++ b/client/player/file_player.cpp @@ -27,6 +27,9 @@ using namespace std; +namespace player +{ + static constexpr auto LOG_TAG = "FilePlayer"; static constexpr auto kDefaultBuffer = 50ms; @@ -128,3 +131,5 @@ void FilePlayer::stop() LOG(INFO, LOG_TAG) << "Stop\n"; timer_.cancel(); } + +} // namespace player diff --git a/client/player/file_player.hpp b/client/player/file_player.hpp index e73691e2..fb2a7f85 100644 --- a/client/player/file_player.hpp +++ b/client/player/file_player.hpp @@ -23,6 +23,11 @@ #include #include +namespace player +{ + +static constexpr auto FILE = "file"; + /// File Player /// Used for testing and doesn't even write the received audio to file at the moment, /// but just discards it @@ -42,8 +47,9 @@ protected: boost::asio::steady_timer timer_; std::vector buffer_; std::chrono::time_point next_request_; - std::shared_ptr file_; + std::shared_ptr<::FILE> file_; }; +} // namespace player #endif diff --git a/client/player/oboe_player.cpp b/client/player/oboe_player.cpp index 7cd8f959..6a4b8e03 100644 --- a/client/player/oboe_player.cpp +++ b/client/player/oboe_player.cpp @@ -26,6 +26,9 @@ using namespace std; +namespace player +{ + static constexpr auto LOG_TAG = "OboePlayer"; static constexpr double kDefaultLatency = 50; @@ -201,3 +204,5 @@ void OboePlayer::stop() if (result != oboe::Result::OK) LOG(ERROR, LOG_TAG) << "Error in requestStop: " << oboe::convertToText(result) << "\n"; } + +} // namespace player diff --git a/client/player/oboe_player.hpp b/client/player/oboe_player.hpp index ee463ac7..22bb407d 100644 --- a/client/player/oboe_player.hpp +++ b/client/player/oboe_player.hpp @@ -24,6 +24,10 @@ #include "player.hpp" +namespace player +{ + +static constexpr auto OBOE = "oboe"; /// Android Oboe Audio Player /** @@ -56,5 +60,6 @@ protected: std::unique_ptr mLatencyTuner; }; +} // namespace player #endif diff --git a/client/player/opensl_player.cpp b/client/player/opensl_player.cpp index d2d79cb7..00d1c29f 100644 --- a/client/player/opensl_player.cpp +++ b/client/player/opensl_player.cpp @@ -26,6 +26,9 @@ using namespace std; +namespace player +{ + static constexpr auto LOG_TAG = "OpenSlPlayer"; static constexpr auto kPhaseInit = "Init"; @@ -375,3 +378,5 @@ void OpenslPlayer::stop() (*bqPlayerBufferQueue)->Clear(bqPlayerBufferQueue); throwUnsuccess(kPhaseStop, "PlayerPlay::SetPlayState", result); } + +} // namespace player diff --git a/client/player/opensl_player.hpp b/client/player/opensl_player.hpp index c1479d4f..8854a83a 100644 --- a/client/player/opensl_player.hpp +++ b/client/player/opensl_player.hpp @@ -25,6 +25,11 @@ #include "player.hpp" +namespace player +{ + +static constexpr auto OPENSL = "opensl"; + typedef int (*AndroidAudioCallback)(short* buffer, int num_samples); @@ -72,5 +77,6 @@ protected: std::shared_ptr pubStream_; }; +} // namespace player #endif diff --git a/client/player/pcm_device.hpp b/client/player/pcm_device.hpp index a466c26b..0cb6af6d 100644 --- a/client/player/pcm_device.hpp +++ b/client/player/pcm_device.hpp @@ -16,11 +16,14 @@ along with this program. If not, see . ***/ -#ifndef PCM_DEVICE_H -#define PCM_DEVICE_H +#ifndef PCM_DEVICE_HPP +#define PCM_DEVICE_HPP #include +namespace player +{ + static constexpr char DEFAULT_DEVICE[] = "default"; struct PcmDevice @@ -34,5 +37,6 @@ struct PcmDevice std::string description; }; +} // namespace player #endif diff --git a/client/player/player.cpp b/client/player/player.cpp index a694af2e..778bdd6b 100644 --- a/client/player/player.cpp +++ b/client/player/player.cpp @@ -41,6 +41,9 @@ using namespace std; +namespace player +{ + static constexpr auto LOG_TAG = "Player"; Player::Player(boost::asio::io_context& io_context, const ClientSettings::Player& settings, std::shared_ptr stream) @@ -246,3 +249,5 @@ void Player::setVolume(double volume, bool mute) } } } + +} // namespace player diff --git a/client/player/player.hpp b/client/player/player.hpp index fc2fb30e..df9e04e2 100644 --- a/client/player/player.hpp +++ b/client/player/player.hpp @@ -16,8 +16,8 @@ along with this program. If not, see . ***/ -#ifndef PLAYER_H -#define PLAYER_H +#ifndef PLAYER_HPP +#define PLAYER_HPP #include "client_settings.hpp" #include "common/aixlog.hpp" @@ -32,6 +32,8 @@ #include #include +namespace player +{ /// Audio Player /** @@ -112,5 +114,6 @@ private: } }; +} // namespace player #endif diff --git a/client/player/pulse_player.cpp b/client/player/pulse_player.cpp index 0b245272..d91863b2 100644 --- a/client/player/pulse_player.cpp +++ b/client/player/pulse_player.cpp @@ -28,6 +28,9 @@ using namespace std::chrono_literals; using namespace std; +namespace player +{ + static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms; static constexpr auto LOG_TAG = "PulsePlayer"; @@ -405,7 +408,7 @@ void PulsePlayer::start() bufattr_.tlength = pa_usec_to_bytes(latency_.count(), &pa_ss_); const char* device = nullptr; - if (settings_.pcm_device.name.compare(DEFAULT_DEVICE) != 0) + if (settings_.pcm_device.name == DEFAULT_DEVICE) device = settings_.pcm_device.name.c_str(); int result = pa_stream_connect_playback( @@ -459,3 +462,5 @@ void PulsePlayer::stop() playstream_ = nullptr; } } + +} // namespace player diff --git a/client/player/pulse_player.hpp b/client/player/pulse_player.hpp index 00d2b549..8bf4a5b0 100644 --- a/client/player/pulse_player.hpp +++ b/client/player/pulse_player.hpp @@ -26,6 +26,11 @@ #include #include +namespace player +{ + +static constexpr auto PULSE = "pulse"; + /// File Player /// Used for testing and doesn't even write the received audio to file at the moment, /// but just discards it @@ -71,5 +76,6 @@ protected: std::chrono::time_point last_change_; }; +} // namespace player #endif diff --git a/client/player/wasapi_player.hpp b/client/player/wasapi_player.hpp index 0d2584f9..09fcd862 100644 --- a/client/player/wasapi_player.hpp +++ b/client/player/wasapi_player.hpp @@ -26,6 +26,9 @@ #include #include +namespace player +{ + class AudioSessionEventListener : public IAudioSessionEvents { LONG _cRef; @@ -169,6 +172,8 @@ public: HRESULT STDMETHODCALLTYPE OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify); }; +static constexpr auto WASAPI = "wasapi"; + class WASAPIPlayer : public Player { public: @@ -192,4 +197,6 @@ private: #pragma warning(pop) +} // namespace player + #endif diff --git a/client/snapclient.cpp b/client/snapclient.cpp index 575e9959..1a72934e 100644 --- a/client/snapclient.cpp +++ b/client/snapclient.cpp @@ -35,6 +35,7 @@ #ifdef HAS_WASAPI #include "player/wasapi_player.hpp" #endif +#include "player/file_player.hpp" #ifdef HAS_DAEMON #include "common/daemon.hpp" #endif @@ -48,6 +49,7 @@ using namespace std; using namespace popl; +using namespace player; using namespace std::chrono_literals; @@ -58,15 +60,16 @@ PcmDevice getPcmDevice(const std::string& player, const std::string& soundcard) #if defined(HAS_ALSA) || defined(HAS_PULSE) || defined(HAS_WASAPI) vector pcm_devices; #if defined(HAS_ALSA) - if (player == "alsa") + if (player == player::ALSA) pcm_devices = AlsaPlayer::pcm_list(); #endif #if defined(HAS_PULSE) - if (player == "pulse") + if (player == player::PULSE) pcm_devices = PulsePlayer::pcm_list(); #endif #if defined(HAS_WASAPI) - pcm_devices = WASAPIPlayer::pcm_list(); + if (player == player::WASAPI) + pcm_devices = WASAPIPlayer::pcm_list(); #endif try { @@ -120,7 +123,7 @@ int main(int argc, char** argv) { string meta_script(""); ClientSettings settings; - string pcm_device(DEFAULT_DEVICE); + string pcm_device(player::DEFAULT_DEVICE); OptionParser op("Allowed options"); auto helpSwitch = op.add("", "help", "produce help message"); @@ -132,7 +135,7 @@ int main(int argc, char** argv) op.add>("", "hostID", "unique host id, default is MAC address", "", &settings.host_id); // PCM device specific -#if defined(HAS_ALSA) || defined(HAS_WASAPI) +#if defined(HAS_ALSA) || defined(HAS_PULSE) || defined(HAS_WASAPI) auto listSwitch = op.add("l", "list", "list PCM devices"); /*auto soundcardValue =*/op.add>("s", "soundcard", "index or name of the pcm device", pcm_device, &pcm_device); #endif @@ -202,20 +205,21 @@ int main(int argc, char** argv) settings.player.player_name = utils::string::split_left(settings.player.player_name, ':', settings.player.parameter); -#if defined(HAS_ALSA) || defined(HAS_WASAPI) || defined(HAS_PULSE) +#if defined(HAS_ALSA) || defined(HAS_PULSE) || defined(HAS_WASAPI) if (listSwitch->is_set()) { - vector pcmDevices; -#if defined(HAS_PULSE) - if (settings.player.player_name == "pulse") - pcmDevices = PulsePlayer::pcm_list(); -#endif + vector pcm_devices; #if defined(HAS_ALSA) - if (settings.player.player_name == "alsa") - pcmDevices = AlsaPlayer::pcm_list(); + if (settings.player.player_name == player::ALSA) + pcm_devices = AlsaPlayer::pcm_list(); +#endif +#if defined(HAS_PULSE) + if (settings.player.player_name == player::PULSE) + pcm_devices = PulsePlayer::pcm_list(); #endif #if defined(HAS_WASAPI) - pcmDevices = WASAPIPlayer::pcm_list(); + if (settings.player.player_name == player::WASAPI) + pcm_devices = WASAPIPlayer::pcm_list(); #endif #ifdef WINDOWS // Set console code page to UTF-8 so console known how to interpret string data @@ -223,10 +227,11 @@ int main(int argc, char** argv) // Enable buffering to prevent VS from chopping up UTF-8 byte sequences setvbuf(stdout, nullptr, _IOFBF, 1000); #endif - for (auto dev : pcmDevices) - { + for (const auto& dev : pcm_devices) cout << dev.idx << ": " << dev.name << "\n" << dev.description << "\n\n"; - } + + if (pcm_devices.empty()) + cout << "No PCM device available for audio backend \"" << settings.player.player_name << "\"\n"; exit(EXIT_SUCCESS); } #endif @@ -346,18 +351,18 @@ int main(int argc, char** argv) if (settings.player.parameter == "?") { - if (settings.player.player_name == "file") + if (settings.player.player_name == player::FILE) { cout << "Options are a comma separated list of:\n" << " \"filename=\" - with = \"stdout\", \"stderr\", \"null\" or a filename\n" << " \"mode=[w|a]\" - w: write (discarding the content), a: append (keeping the content)\n"; } - else if (settings.player.player_name == "pulse") + else if (settings.player.player_name == player::PULSE) { cout << "Options are a comma separated list of:\n" << " \"buffer_time=\" - default 80, min 10\n"; } - else if (settings.player.player_name == "alsa") + else if (settings.player.player_name == player::ALSA) { cout << "Options are a comma separated list of:\n" << " \"buffer_time=\" - default 80, min 10\n"