mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-15 18:16:44 +02:00
Add player namespace and player name constants
This commit is contained in:
parent
f254d59832
commit
c880ae2e62
20 changed files with 140 additions and 50 deletions
|
@ -60,7 +60,7 @@ struct ClientSettings
|
||||||
std::string player_name{""};
|
std::string player_name{""};
|
||||||
std::string parameter{""};
|
std::string parameter{""};
|
||||||
int latency{0};
|
int latency{0};
|
||||||
PcmDevice pcm_device;
|
player::PcmDevice pcm_device;
|
||||||
SampleFormat sample_format;
|
SampleFormat sample_format;
|
||||||
SharingMode sharing_mode{SharingMode::unspecified};
|
SharingMode sharing_mode{SharingMode::unspecified};
|
||||||
Mixer mixer;
|
Mixer mixer;
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace player;
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "Controller";
|
static constexpr auto LOG_TAG = "Controller";
|
||||||
static constexpr auto TIME_SYNC_INTERVAL = 1s;
|
static constexpr auto TIME_SYNC_INTERVAL = 1s;
|
||||||
|
@ -92,24 +93,24 @@ std::vector<std::string> Controller::getSupportedPlayerNames()
|
||||||
{
|
{
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
#ifdef HAS_ALSA
|
#ifdef HAS_ALSA
|
||||||
result.emplace_back("alsa");
|
result.emplace_back(player::ALSA);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_PULSE
|
#ifdef HAS_PULSE
|
||||||
result.emplace_back("pulse");
|
result.emplace_back(player::PULSE);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_OBOE
|
#ifdef HAS_OBOE
|
||||||
result.emplace_back("oboe");
|
result.emplace_back(player::OBOE);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_OPENSL
|
#ifdef HAS_OPENSL
|
||||||
result.emplace_back("opensl");
|
result.emplace_back(player::OPENSL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_COREAUDIO
|
#ifdef HAS_COREAUDIO
|
||||||
result.emplace_back("coreaudio");
|
result.emplace_back(player::COREAUDIO);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_WASAPI
|
#ifdef HAS_WASAPI
|
||||||
result.emplace_back("wasapi");
|
result.emplace_back(player::WASAPI);
|
||||||
#endif
|
#endif
|
||||||
result.emplace_back("file");
|
result.emplace_back(player::FILE);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,30 +185,30 @@ void Controller::getNextMessage()
|
||||||
|
|
||||||
#ifdef HAS_ALSA
|
#ifdef HAS_ALSA
|
||||||
if (!player_)
|
if (!player_)
|
||||||
player_ = createPlayer<AlsaPlayer>(settings_.player, "alsa");
|
player_ = createPlayer<AlsaPlayer>(settings_.player, player::ALSA);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_PULSE
|
#ifdef HAS_PULSE
|
||||||
if (!player_)
|
if (!player_)
|
||||||
player_ = createPlayer<PulsePlayer>(settings_.player, "pulse");
|
player_ = createPlayer<PulsePlayer>(settings_.player, player::PULSE);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_OBOE
|
#ifdef HAS_OBOE
|
||||||
if (!player_)
|
if (!player_)
|
||||||
player_ = createPlayer<OboePlayer>(settings_.player, "oboe");
|
player_ = createPlayer<OboePlayer>(settings_.player, player::OBOE);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_OPENSL
|
#ifdef HAS_OPENSL
|
||||||
if (!player_)
|
if (!player_)
|
||||||
player_ = createPlayer<OpenslPlayer>(settings_.player, "opensl");
|
player_ = createPlayer<OpenslPlayer>(settings_.player, player::OPENSL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_COREAUDIO
|
#ifdef HAS_COREAUDIO
|
||||||
if (!player_)
|
if (!player_)
|
||||||
player_ = createPlayer<CoreAudioPlayer>(settings_.player, "coreaudio");
|
player_ = createPlayer<CoreAudioPlayer>(settings_.player, player::COREAUDIO);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_WASAPI
|
#ifdef HAS_WASAPI
|
||||||
if (!player_)
|
if (!player_)
|
||||||
player_ = createPlayer<WASAPIPlayer>(settings_.player, "wasapi");
|
player_ = createPlayer<WASAPIPlayer>(settings_.player, player::WASAPI);
|
||||||
#endif
|
#endif
|
||||||
if (!player_ && (settings_.player.player_name == "file"))
|
if (!player_ && (settings_.player.player_name == player::FILE))
|
||||||
player_ = createPlayer<FilePlayer>(settings_.player, "file");
|
player_ = createPlayer<FilePlayer>(settings_.player, player::FILE);
|
||||||
|
|
||||||
if (!player_)
|
if (!player_)
|
||||||
throw SnapException("No audio player support" + (settings_.player.player_name.empty() ? "" : " for: " + settings_.player.player_name));
|
throw SnapException("No audio player support" + (settings_.player.player_name.empty() ? "" : " for: " + settings_.player.player_name));
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef CONTROLLER_H
|
#ifndef CONTROLLER_HPP
|
||||||
#define CONTROLLER_H
|
#define CONTROLLER_HPP
|
||||||
|
|
||||||
#include "client_connection.hpp"
|
#include "client_connection.hpp"
|
||||||
#include "client_settings.hpp"
|
#include "client_settings.hpp"
|
||||||
|
@ -55,7 +55,7 @@ private:
|
||||||
void browseMdns(const MdnsHandler& handler);
|
void browseMdns(const MdnsHandler& handler);
|
||||||
|
|
||||||
template <typename PlayerType>
|
template <typename PlayerType>
|
||||||
std::unique_ptr<Player> createPlayer(ClientSettings::Player& settings, const std::string& player_name);
|
std::unique_ptr<player::Player> createPlayer(ClientSettings::Player& settings, const std::string& player_name);
|
||||||
|
|
||||||
void getNextMessage();
|
void getNextMessage();
|
||||||
void sendTimeSyncMessage(int quick_syncs);
|
void sendTimeSyncMessage(int quick_syncs);
|
||||||
|
@ -68,7 +68,7 @@ private:
|
||||||
std::unique_ptr<ClientConnection> clientConnection_;
|
std::unique_ptr<ClientConnection> clientConnection_;
|
||||||
std::shared_ptr<Stream> stream_;
|
std::shared_ptr<Stream> stream_;
|
||||||
std::unique_ptr<decoder::Decoder> decoder_;
|
std::unique_ptr<decoder::Decoder> decoder_;
|
||||||
std::unique_ptr<Player> player_;
|
std::unique_ptr<player::Player> player_;
|
||||||
std::unique_ptr<MetadataAdapter> meta_;
|
std::unique_ptr<MetadataAdapter> meta_;
|
||||||
std::unique_ptr<msg::ServerSettings> serverSettings_;
|
std::unique_ptr<msg::ServerSettings> serverSettings_;
|
||||||
std::unique_ptr<msg::CodecHeader> headerChunk_;
|
std::unique_ptr<msg::CodecHeader> headerChunk_;
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms;
|
static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms;
|
||||||
static constexpr int PERIODS = 4;
|
static constexpr int PERIODS = 4;
|
||||||
|
|
||||||
|
@ -642,3 +645,5 @@ vector<PcmDevice> AlsaPlayer::pcm_list()
|
||||||
snd_device_name_free_hint(hints);
|
snd_device_name_free_hint(hints);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef ALSA_PLAYER_H
|
#ifndef ALSA_PLAYER_HPP
|
||||||
#define ALSA_PLAYER_H
|
#define ALSA_PLAYER_HPP
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
|
@ -25,6 +25,11 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
|
static constexpr auto ALSA = "alsa";
|
||||||
|
|
||||||
/// Audio Player
|
/// Audio Player
|
||||||
/**
|
/**
|
||||||
* Audio player implementation using Alsa
|
* Audio player implementation using Alsa
|
||||||
|
@ -81,5 +86,6 @@ private:
|
||||||
unsigned int periods_;
|
unsigned int periods_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
#include "coreaudio_player.hpp"
|
#include "coreaudio_player.hpp"
|
||||||
#include <CoreAudio/CoreAudio.h>
|
#include <CoreAudio/CoreAudio.h>
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
#define NUM_BUFFERS 2
|
#define NUM_BUFFERS 2
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "CoreAudioPlayer";
|
static constexpr auto LOG_TAG = "CoreAudioPlayer";
|
||||||
|
@ -210,3 +213,5 @@ void CoreAudioPlayer::uninitAudioQueue(AudioQueueRef queue)
|
||||||
pubStream_->clearChunks();
|
pubStream_->clearChunks();
|
||||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef CORE_AUDIO_PLAYER_H
|
#ifndef CORE_AUDIO_PLAYER_HPP
|
||||||
#define CORE_AUDIO_PLAYER_H
|
#define CORE_AUDIO_PLAYER_HPP
|
||||||
|
|
||||||
#include <AudioToolbox/AudioQueue.h>
|
#include <AudioToolbox/AudioQueue.h>
|
||||||
#include <CoreAudio/CoreAudioTypes.h>
|
#include <CoreAudio/CoreAudioTypes.h>
|
||||||
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
|
static constexpr auto COREAUDIO = "coreaudio";
|
||||||
|
|
||||||
/// Audio Player
|
/// Audio Player
|
||||||
/**
|
/**
|
||||||
* Audio player implementation using CoreAudio
|
* Audio player implementation using CoreAudio
|
||||||
|
@ -58,5 +63,6 @@ protected:
|
||||||
long lastChunkTick;
|
long lastChunkTick;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "FilePlayer";
|
static constexpr auto LOG_TAG = "FilePlayer";
|
||||||
static constexpr auto kDefaultBuffer = 50ms;
|
static constexpr auto kDefaultBuffer = 50ms;
|
||||||
|
|
||||||
|
@ -128,3 +131,5 @@ void FilePlayer::stop()
|
||||||
LOG(INFO, LOG_TAG) << "Stop\n";
|
LOG(INFO, LOG_TAG) << "Stop\n";
|
||||||
timer_.cancel();
|
timer_.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
|
static constexpr auto FILE = "file";
|
||||||
|
|
||||||
/// File Player
|
/// File Player
|
||||||
/// Used for testing and doesn't even write the received audio to file at the moment,
|
/// Used for testing and doesn't even write the received audio to file at the moment,
|
||||||
/// but just discards it
|
/// but just discards it
|
||||||
|
@ -42,8 +47,9 @@ protected:
|
||||||
boost::asio::steady_timer timer_;
|
boost::asio::steady_timer timer_;
|
||||||
std::vector<char> buffer_;
|
std::vector<char> buffer_;
|
||||||
std::chrono::time_point<std::chrono::steady_clock> next_request_;
|
std::chrono::time_point<std::chrono::steady_clock> next_request_;
|
||||||
std::shared_ptr<FILE> file_;
|
std::shared_ptr<::FILE> file_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "OboePlayer";
|
static constexpr auto LOG_TAG = "OboePlayer";
|
||||||
static constexpr double kDefaultLatency = 50;
|
static constexpr double kDefaultLatency = 50;
|
||||||
|
|
||||||
|
@ -201,3 +204,5 @@ void OboePlayer::stop()
|
||||||
if (result != oboe::Result::OK)
|
if (result != oboe::Result::OK)
|
||||||
LOG(ERROR, LOG_TAG) << "Error in requestStop: " << oboe::convertToText(result) << "\n";
|
LOG(ERROR, LOG_TAG) << "Error in requestStop: " << oboe::convertToText(result) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
|
static constexpr auto OBOE = "oboe";
|
||||||
|
|
||||||
/// Android Oboe Audio Player
|
/// Android Oboe Audio Player
|
||||||
/**
|
/**
|
||||||
|
@ -56,5 +60,6 @@ protected:
|
||||||
std::unique_ptr<oboe::LatencyTuner> mLatencyTuner;
|
std::unique_ptr<oboe::LatencyTuner> mLatencyTuner;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "OpenSlPlayer";
|
static constexpr auto LOG_TAG = "OpenSlPlayer";
|
||||||
|
|
||||||
static constexpr auto kPhaseInit = "Init";
|
static constexpr auto kPhaseInit = "Init";
|
||||||
|
@ -375,3 +378,5 @@ void OpenslPlayer::stop()
|
||||||
(*bqPlayerBufferQueue)->Clear(bqPlayerBufferQueue);
|
(*bqPlayerBufferQueue)->Clear(bqPlayerBufferQueue);
|
||||||
throwUnsuccess(kPhaseStop, "PlayerPlay::SetPlayState", result);
|
throwUnsuccess(kPhaseStop, "PlayerPlay::SetPlayState", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
|
static constexpr auto OPENSL = "opensl";
|
||||||
|
|
||||||
typedef int (*AndroidAudioCallback)(short* buffer, int num_samples);
|
typedef int (*AndroidAudioCallback)(short* buffer, int num_samples);
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,5 +77,6 @@ protected:
|
||||||
std::shared_ptr<Stream> pubStream_;
|
std::shared_ptr<Stream> pubStream_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,11 +16,14 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef PCM_DEVICE_H
|
#ifndef PCM_DEVICE_HPP
|
||||||
#define PCM_DEVICE_H
|
#define PCM_DEVICE_HPP
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
static constexpr char DEFAULT_DEVICE[] = "default";
|
static constexpr char DEFAULT_DEVICE[] = "default";
|
||||||
|
|
||||||
struct PcmDevice
|
struct PcmDevice
|
||||||
|
@ -34,5 +37,6 @@ struct PcmDevice
|
||||||
std::string description;
|
std::string description;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "Player";
|
static constexpr auto LOG_TAG = "Player";
|
||||||
|
|
||||||
Player::Player(boost::asio::io_context& io_context, const ClientSettings::Player& settings, std::shared_ptr<Stream> stream)
|
Player::Player(boost::asio::io_context& io_context, const ClientSettings::Player& settings, std::shared_ptr<Stream> stream)
|
||||||
|
@ -246,3 +249,5 @@ void Player::setVolume(double volume, bool mute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef PLAYER_H
|
#ifndef PLAYER_HPP
|
||||||
#define PLAYER_H
|
#define PLAYER_HPP
|
||||||
|
|
||||||
#include "client_settings.hpp"
|
#include "client_settings.hpp"
|
||||||
#include "common/aixlog.hpp"
|
#include "common/aixlog.hpp"
|
||||||
|
@ -32,6 +32,8 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
/// Audio Player
|
/// Audio Player
|
||||||
/**
|
/**
|
||||||
|
@ -112,5 +114,6 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms;
|
static constexpr std::chrono::milliseconds BUFFER_TIME = 80ms;
|
||||||
|
|
||||||
static constexpr auto LOG_TAG = "PulsePlayer";
|
static constexpr auto LOG_TAG = "PulsePlayer";
|
||||||
|
@ -405,7 +408,7 @@ void PulsePlayer::start()
|
||||||
bufattr_.tlength = pa_usec_to_bytes(latency_.count(), &pa_ss_);
|
bufattr_.tlength = pa_usec_to_bytes(latency_.count(), &pa_ss_);
|
||||||
|
|
||||||
const char* device = nullptr;
|
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();
|
device = settings_.pcm_device.name.c_str();
|
||||||
|
|
||||||
int result = pa_stream_connect_playback(
|
int result = pa_stream_connect_playback(
|
||||||
|
@ -459,3 +462,5 @@ void PulsePlayer::stop()
|
||||||
playstream_ = nullptr;
|
playstream_ = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <pulse/pulseaudio.h>
|
#include <pulse/pulseaudio.h>
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
|
static constexpr auto PULSE = "pulse";
|
||||||
|
|
||||||
/// File Player
|
/// File Player
|
||||||
/// Used for testing and doesn't even write the received audio to file at the moment,
|
/// Used for testing and doesn't even write the received audio to file at the moment,
|
||||||
/// but just discards it
|
/// but just discards it
|
||||||
|
@ -71,5 +76,6 @@ protected:
|
||||||
std::chrono::time_point<std::chrono::steady_clock> last_change_;
|
std::chrono::time_point<std::chrono::steady_clock> last_change_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#include <audiopolicy.h>
|
#include <audiopolicy.h>
|
||||||
#include <endpointvolume.h>
|
#include <endpointvolume.h>
|
||||||
|
|
||||||
|
namespace player
|
||||||
|
{
|
||||||
|
|
||||||
class AudioSessionEventListener : public IAudioSessionEvents
|
class AudioSessionEventListener : public IAudioSessionEvents
|
||||||
{
|
{
|
||||||
LONG _cRef;
|
LONG _cRef;
|
||||||
|
@ -169,6 +172,8 @@ public:
|
||||||
HRESULT STDMETHODCALLTYPE OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify);
|
HRESULT STDMETHODCALLTYPE OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr auto WASAPI = "wasapi";
|
||||||
|
|
||||||
class WASAPIPlayer : public Player
|
class WASAPIPlayer : public Player
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -192,4 +197,6 @@ private:
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
} // namespace player
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#ifdef HAS_WASAPI
|
#ifdef HAS_WASAPI
|
||||||
#include "player/wasapi_player.hpp"
|
#include "player/wasapi_player.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
#include "player/file_player.hpp"
|
||||||
#ifdef HAS_DAEMON
|
#ifdef HAS_DAEMON
|
||||||
#include "common/daemon.hpp"
|
#include "common/daemon.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace popl;
|
using namespace popl;
|
||||||
|
using namespace player;
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
@ -58,14 +60,15 @@ PcmDevice getPcmDevice(const std::string& player, const std::string& soundcard)
|
||||||
#if defined(HAS_ALSA) || defined(HAS_PULSE) || defined(HAS_WASAPI)
|
#if defined(HAS_ALSA) || defined(HAS_PULSE) || defined(HAS_WASAPI)
|
||||||
vector<PcmDevice> pcm_devices;
|
vector<PcmDevice> pcm_devices;
|
||||||
#if defined(HAS_ALSA)
|
#if defined(HAS_ALSA)
|
||||||
if (player == "alsa")
|
if (player == player::ALSA)
|
||||||
pcm_devices = AlsaPlayer::pcm_list();
|
pcm_devices = AlsaPlayer::pcm_list();
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAS_PULSE)
|
#if defined(HAS_PULSE)
|
||||||
if (player == "pulse")
|
if (player == player::PULSE)
|
||||||
pcm_devices = PulsePlayer::pcm_list();
|
pcm_devices = PulsePlayer::pcm_list();
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAS_WASAPI)
|
#if defined(HAS_WASAPI)
|
||||||
|
if (player == player::WASAPI)
|
||||||
pcm_devices = WASAPIPlayer::pcm_list();
|
pcm_devices = WASAPIPlayer::pcm_list();
|
||||||
#endif
|
#endif
|
||||||
try
|
try
|
||||||
|
@ -120,7 +123,7 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
string meta_script("");
|
string meta_script("");
|
||||||
ClientSettings settings;
|
ClientSettings settings;
|
||||||
string pcm_device(DEFAULT_DEVICE);
|
string pcm_device(player::DEFAULT_DEVICE);
|
||||||
|
|
||||||
OptionParser op("Allowed options");
|
OptionParser op("Allowed options");
|
||||||
auto helpSwitch = op.add<Switch>("", "help", "produce help message");
|
auto helpSwitch = op.add<Switch>("", "help", "produce help message");
|
||||||
|
@ -132,7 +135,7 @@ int main(int argc, char** argv)
|
||||||
op.add<Value<string>>("", "hostID", "unique host id, default is MAC address", "", &settings.host_id);
|
op.add<Value<string>>("", "hostID", "unique host id, default is MAC address", "", &settings.host_id);
|
||||||
|
|
||||||
// PCM device specific
|
// PCM device specific
|
||||||
#if defined(HAS_ALSA) || defined(HAS_WASAPI)
|
#if defined(HAS_ALSA) || defined(HAS_PULSE) || defined(HAS_WASAPI)
|
||||||
auto listSwitch = op.add<Switch>("l", "list", "list PCM devices");
|
auto listSwitch = op.add<Switch>("l", "list", "list PCM devices");
|
||||||
/*auto soundcardValue =*/op.add<Value<string>>("s", "soundcard", "index or name of the pcm device", pcm_device, &pcm_device);
|
/*auto soundcardValue =*/op.add<Value<string>>("s", "soundcard", "index or name of the pcm device", pcm_device, &pcm_device);
|
||||||
#endif
|
#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);
|
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())
|
if (listSwitch->is_set())
|
||||||
{
|
{
|
||||||
vector<PcmDevice> pcmDevices;
|
vector<PcmDevice> pcm_devices;
|
||||||
#if defined(HAS_PULSE)
|
|
||||||
if (settings.player.player_name == "pulse")
|
|
||||||
pcmDevices = PulsePlayer::pcm_list();
|
|
||||||
#endif
|
|
||||||
#if defined(HAS_ALSA)
|
#if defined(HAS_ALSA)
|
||||||
if (settings.player.player_name == "alsa")
|
if (settings.player.player_name == player::ALSA)
|
||||||
pcmDevices = AlsaPlayer::pcm_list();
|
pcm_devices = AlsaPlayer::pcm_list();
|
||||||
|
#endif
|
||||||
|
#if defined(HAS_PULSE)
|
||||||
|
if (settings.player.player_name == player::PULSE)
|
||||||
|
pcm_devices = PulsePlayer::pcm_list();
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAS_WASAPI)
|
#if defined(HAS_WASAPI)
|
||||||
pcmDevices = WASAPIPlayer::pcm_list();
|
if (settings.player.player_name == player::WASAPI)
|
||||||
|
pcm_devices = WASAPIPlayer::pcm_list();
|
||||||
#endif
|
#endif
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
// Set console code page to UTF-8 so console known how to interpret string data
|
// 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
|
// Enable buffering to prevent VS from chopping up UTF-8 byte sequences
|
||||||
setvbuf(stdout, nullptr, _IOFBF, 1000);
|
setvbuf(stdout, nullptr, _IOFBF, 1000);
|
||||||
#endif
|
#endif
|
||||||
for (auto dev : pcmDevices)
|
for (const auto& dev : pcm_devices)
|
||||||
{
|
|
||||||
cout << dev.idx << ": " << dev.name << "\n" << dev.description << "\n\n";
|
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);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -346,18 +351,18 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
if (settings.player.parameter == "?")
|
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"
|
cout << "Options are a comma separated list of:\n"
|
||||||
<< " \"filename=<filename>\" - with <filename> = \"stdout\", \"stderr\", \"null\" or a filename\n"
|
<< " \"filename=<filename>\" - with <filename> = \"stdout\", \"stderr\", \"null\" or a filename\n"
|
||||||
<< " \"mode=[w|a]\" - w: write (discarding the content), a: append (keeping the content)\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"
|
cout << "Options are a comma separated list of:\n"
|
||||||
<< " \"buffer_time=<buffer size [ms]>\" - default 80, min 10\n";
|
<< " \"buffer_time=<buffer size [ms]>\" - 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"
|
cout << "Options are a comma separated list of:\n"
|
||||||
<< " \"buffer_time=<total buffer size [ms]>\" - default 80, min 10\n"
|
<< " \"buffer_time=<total buffer size [ms]>\" - default 80, min 10\n"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue