URY playd
C++ minimalist audio player
Player Class Reference

A Player contains a loaded audio file and a command API for manipulating it. More...

#include <player.hpp>

+ Collaboration diagram for Player:

Public Types

using SinkFn = std::function< std::unique_ptr< AudioSink >(const AudioSource &, int)>
 Type for functions that construct sinks.
 
using SourceFn = std::function< std::unique_ptr< AudioSource >(const std::string &)>
 Type for functions that construct sources.
 

Public Member Functions

 Player (int device_id, SinkFn sink, std::map< std::string, SourceFn > sources)
 Constructs a Player. More...
 
 Player (const Player &)=delete
 Deleted copy constructor.
 
Playeroperator= (const Player &)=delete
 Deleted copy-assignment constructor.
 
void SetIo (ResponseSink &io)
 Sets the ResponseSink to which this Player shall send responses. More...
 
bool Update ()
 Instructs the Player to perform a cycle of work. More...
 
Response SetPlaying (const std::string &tag, bool playing)
 Tells the audio file to start or stop playing. More...
 
Response Dump (size_t id, const std::string &tag) const
 Dumps the current player state to the given ID. More...
 
Response Eject (const std::string &tag)
 Ejects the current loaded song, if any. More...
 
Response End (const std::string &tag)
 Ends a file, stopping and rewinding. More...
 
Response Load (const std::string &tag, const std::string &path)
 Loads a file. More...
 
Response Pos (const std::string &tag, const std::string &pos_str)
 Seeks to a given position in the current file. More...
 
Response Quit (const std::string &tag)
 Quits playd. More...
 

Private Member Functions

void PosRaw (const std::string &tag, std::uint64_t pos)
 Performs an actual seek. More...
 
void DumpState (size_t id, const std::string &tag) const
 Emits a response for the current audio state to the sink. More...
 
void Respond (int id, Response rs) const
 Outputs a response, if there is a ResponseSink attached. More...
 
bool CanAnnounceTime (std::uint64_t micros)
 Determines whether we can broadcast a POS response. More...
 
std::unique_ptr< AudioLoadRaw (const std::string &path) const
 Loads a file, creating an Audio for it. More...
 
std::unique_ptr< AudioSourceLoadSource (const std::string &path) const
 Loads a file, creating an AudioSource. More...
 

Static Private Member Functions

static std::uint64_t PosParse (const std::string &pos_str)
 Parses pos_str as a seek timestamp. More...
 

Private Attributes

int device_id
 The sink's device ID.
 
SinkFn sink
 The sink create function.
 
std::map< std::string, SourceFnsources
 The file formats map.
 
std::unique_ptr< Audiofile
 The loaded audio file.
 
bool dead
 Whether the Player is closing.
 
const ResponseSinkio
 The sink for responses.
 
std::uint64_t last_pos
 The last-sent position.
 

Detailed Description

A Player contains a loaded audio file and a command API for manipulating it.

See also
Audio
AudioSystem

Definition at line 31 of file player.hpp.

Constructor & Destructor Documentation

§ Player()

Player::Player ( int  device_id,
SinkFn  sink,
std::map< std::string, SourceFn sources 
)

Constructs a Player.

Parameters
device_idThe device ID to which sinks shall output.
sinkThe function to be used for building sinks.
sourcesThe map of file extensions to functions used for building sources.

Definition at line 25 of file player.cpp.

27  sink(std::move(sink)),
28  sources(std::move(sources)),
29  file(std::make_unique<NoAudio>()),
30  dead(false),
31  io(nullptr),
32  last_pos(0)
33 {
34 }
const ResponseSink * io
The sink for responses.
Definition: player.hpp:146
bool dead
Whether the Player is closing.
Definition: player.hpp:145
int device_id
The sink&#39;s device ID.
Definition: player.hpp:141
SinkFn sink
The sink create function.
Definition: player.hpp:142
std::map< std::string, SourceFn > sources
The file formats map.
Definition: player.hpp:143
std::uint64_t last_pos
The last-sent position.
Definition: player.hpp:147
std::unique_ptr< Audio > file
The loaded audio file.
Definition: player.hpp:144

Member Function Documentation

§ CanAnnounceTime()

bool Player::CanAnnounceTime ( std::uint64_t  micros)
private

Determines whether we can broadcast a POS response.

To prevent spewing massive amounts of POS responses, we only send a broadcast if the number of seconds has changed since the last time CanAnnounceTime() was called.

This is not idempotent. A CanAnnounceTime(x) less than one second before a CanAnnounceTime(x) will always be false.

Parameters
microsThe value of the POS response, in microseconds.
Returns
Whether it is polite to broadcast POS.

Definition at line 295 of file player.cpp.

References last_pos.

Referenced by Update().

296 {
297  std::uint64_t secs = micros / 1000 / 1000;
298 
299  // We can announce if the last announced pos was in a previous second.
300  bool announce = this->last_pos < secs;
301  if (announce) this->last_pos = secs;
302 
303  return announce;
304 }
std::uint64_t last_pos
The last-sent position.
Definition: player.hpp:147

§ Dump()

Response Player::Dump ( size_t  id,
const std::string &  tag 
) const

Dumps the current player state to the given ID.

Parameters
idThe ID of the connection to which the Player should route any responses. For broadcasts, use 0.
tagThe tag of the request calling this command. For unsolicited dumps, use Response::NOREQUEST.
Returns
The result of dumping, which is always success.

Definition at line 65 of file player.cpp.

References dead, DumpState(), Response::Failure(), file, Response::FLOAD, MSG_CMD_PLAYER_CLOSING, Audio::NONE, Response::POS, Respond(), and Response::Success().

Referenced by Load(), and Connection::RunCommand().

66 {
67  if (this->dead) return Response::Failure(tag, MSG_CMD_PLAYER_CLOSING);
68 
69  this->DumpState(id, tag);
70 
71  // This information won't exist if there is no file.
72  if (this->file->CurrentState() != Audio::State::NONE) {
73  auto file = this->file->File();
74  this->Respond(
75  id, Response(tag, Response::Code::FLOAD).AddArg(file));
76 
77  auto pos = this->file->Position();
78  this->Respond(id, Response(tag, Response::Code::POS)
79  .AddArg(std::to_string(pos)));
80  }
81 
82  return Response::Success(tag);
83 }
A response.
Definition: response.hpp:23
void Respond(int id, Response rs) const
Outputs a response, if there is a ResponseSink attached.
Definition: player.cpp:290
const std::string MSG_CMD_PLAYER_CLOSING
Message shown when a command is sent to a closing Player.
Definition: messages.h:57
static Response Success(const std::string &tag)
Shortcut for constructing a final response to a successful request.
Definition: response.cpp:49
There is no Audio.
bool dead
Whether the Player is closing.
Definition: player.hpp:145
The loaded file just changed.
static Response Failure(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a failed request.
Definition: response.cpp:62
void DumpState(size_t id, const std::string &tag) const
Emits a response for the current audio state to the sink.
Definition: player.cpp:265
std::unique_ptr< Audio > file
The loaded audio file.
Definition: player.hpp:144
Server sending current song time.

§ DumpState()

void Player::DumpState ( size_t  id,
const std::string &  tag 
) const
private

Emits a response for the current audio state to the sink.

Parameters
idThe ID of the connection to which the Player should route any responses. For broadcasts, use 0.
tagThe tag of the request calling this command. For unsolicited dumps, use Response::NOREQUEST.
See also
DumpRaw

Definition at line 265 of file player.cpp.

References Audio::AT_END, Response::EJECT, Response::END, file, Audio::NONE, Response::PLAY, Audio::PLAYING, Respond(), Response::STOP, and Audio::STOPPED.

Referenced by Dump(), Eject(), and SetPlaying().

266 {
268 
269  switch (this->file->CurrentState()) {
271  code = Response::Code::END;
272  break;
273  case Audio::State::NONE:
274  code = Response::Code::EJECT;
275  break;
277  code = Response::Code::PLAY;
278  break;
280  code = Response::Code::STOP;
281  break;
282  default:
283  // Just don't dump anything in this case.
284  return;
285  }
286 
287  this->Respond(id, Response(tag, code));
288 }
The Audio is currently playing.
A response.
Definition: response.hpp:23
The Audio has ended and can&#39;t play without a seek.
void Respond(int id, Response rs) const
Outputs a response, if there is a ResponseSink attached.
Definition: player.cpp:290
There is no Audio.
The loaded file is playing.
The loaded file just ended.
The loaded file just ejected.
std::unique_ptr< Audio > file
The loaded audio file.
Definition: player.hpp:144
Code
Enumeration of all possible response codes.
Definition: response.hpp:35
The loaded file has stopped.
The Audio has been stopped, or not yet played.

§ Eject()

Response Player::Eject ( const std::string &  tag)

Ejects the current loaded song, if any.

Parameters
tagThe tag of the request calling this command. For unsolicited ejects, use Response::NOREQUEST.
Returns
Whether the ejection succeeded.

Definition at line 85 of file player.cpp.

References dead, DumpState(), Response::Failure(), file, MSG_CMD_PLAYER_CLOSING, Audio::NONE, and Response::Success().

Referenced by Load(), Quit(), and Connection::RunCommand().

86 {
87  if (this->dead) return Response::Failure(tag, MSG_CMD_PLAYER_CLOSING);
88 
89  // Silently ignore ejects on ejected files.
90  // Concurrently speaking, this should be fine, as we are the only
91  // thread that can eject or un-eject files.
92  if (this->file->CurrentState() == Audio::State::NONE) {
93  return Response::Success(tag);
94  }
95 
96  assert(this->file != nullptr);
97  this->file = std::make_unique<NoAudio>();
98 
99  this->DumpState(0, tag);
100 
101  return Response::Success(tag);
102 }
const std::string MSG_CMD_PLAYER_CLOSING
Message shown when a command is sent to a closing Player.
Definition: messages.h:57
static Response Success(const std::string &tag)
Shortcut for constructing a final response to a successful request.
Definition: response.cpp:49
There is no Audio.
bool dead
Whether the Player is closing.
Definition: player.hpp:145
static Response Failure(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a failed request.
Definition: response.cpp:62
void DumpState(size_t id, const std::string &tag) const
Emits a response for the current audio state to the sink.
Definition: player.cpp:265
std::unique_ptr< Audio > file
The loaded audio file.
Definition: player.hpp:144

§ End()

Response Player::End ( const std::string &  tag)

Ends a file, stopping and rewinding.

Parameters
tagThe tag of the request calling this command. For unsolicited ends, use Response::NOREQUEST.
Returns
Whether the end succeeded.

Definition at line 104 of file player.cpp.

References dead, Response::END, Response::Failure(), MSG_CMD_PLAYER_CLOSING, Response::NOREQUEST, PosRaw(), Respond(), SetPlaying(), and Response::Success().

Referenced by Pos(), Connection::RunCommand(), and Update().

105 {
106  if (this->dead) return Response::Failure(tag, MSG_CMD_PLAYER_CLOSING);
107 
108  // Let upstream know that the file ended by itself.
109  // This is needed for auto-advancing playlists, etc.
111 
112  this->SetPlaying(tag, false);
113 
114  // Rewind the file back to the start. We can't use Player::Pos() here
115  // in case End() is called from Pos(); a seek failure could start an
116  // infinite loop.
117  this->PosRaw(Response::NOREQUEST, 0);
118 
119  return Response::Success(tag);
120 }
A response.
Definition: response.hpp:23
void PosRaw(const std::string &tag, std::uint64_t pos)
Performs an actual seek.
Definition: player.cpp:252
void Respond(int id, Response rs) const
Outputs a response, if there is a ResponseSink attached.
Definition: player.cpp:290
const std::string MSG_CMD_PLAYER_CLOSING
Message shown when a command is sent to a closing Player.
Definition: messages.h:57
static const std::string NOREQUEST
The tag for unsolicited messages (not from responses).
Definition: response.hpp:27
static Response Success(const std::string &tag)
Shortcut for constructing a final response to a successful request.
Definition: response.cpp:49
bool dead
Whether the Player is closing.
Definition: player.hpp:145
The loaded file just ended.
static Response Failure(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a failed request.
Definition: response.cpp:62
Response SetPlaying(const std::string &tag, bool playing)
Tells the audio file to start or stop playing.
Definition: player.cpp:188

§ Load()

Response Player::Load ( const std::string &  tag,
const std::string &  path 
)

Loads a file.

Parameters
tagThe tag of the request calling this command. For unsolicited loads, use Response::NOREQUEST.
pathThe absolute path to a track to load.
Returns
Whether the load succeeded.

Definition at line 122 of file player.cpp.

References dead, Dump(), Eject(), Response::Failure(), file, Response::Invalid(), last_pos, LoadRaw(), Error::Message(), MSG_CMD_PLAYER_CLOSING, MSG_LOAD_EMPTY_PATH, Response::NOREQUEST, and Response::Success().

Referenced by Connection::RunCommand().

123 {
124  if (this->dead) return Response::Failure(tag, MSG_CMD_PLAYER_CLOSING);
125  if (path.empty()) return Response::Invalid(tag, MSG_LOAD_EMPTY_PATH);
126 
127  assert(this->file != nullptr);
128 
129  // Bin the current file as soon as possible.
130  // This ensures that we don't have any situations where two files are
131  // contending over resources, or the current file spends a second or
132  // two flushing its remaining audio.
133  this->Eject(Response::NOREQUEST);
134 
135  try {
136  this->file = this->LoadRaw(path);
137  } catch (FileError &e) {
138  // File errors aren't fatal, so catch them here.
139  return Response::Failure(tag, e.Message());
140  }
141 
142  assert(this->file != nullptr);
143  this->last_pos = 0;
144 
145  // A load will change all of the player's state in one go,
146  // so just send a Dump() instead of writing out all of the responses
147  // here.
148  // Don't take the response from here, though, because it has the wrong
149  // tag.
150  this->Dump(0, Response::NOREQUEST);
151 
152  return Response::Success(tag);
153 }
const std::string MSG_LOAD_EMPTY_PATH
Message shown when one tries to Load an empty path.
Definition: messages.h:78
const std::string MSG_CMD_PLAYER_CLOSING
Message shown when a command is sent to a closing Player.
Definition: messages.h:57
An Error signifying that playd can&#39;t read a file.
Definition: errors.hpp:75
static const std::string NOREQUEST
The tag for unsolicited messages (not from responses).
Definition: response.hpp:27
const std::string & Message() const
The human-readable message for this error.
Definition: errors.cpp:16
static Response Success(const std::string &tag)
Shortcut for constructing a final response to a successful request.
Definition: response.cpp:49
bool dead
Whether the Player is closing.
Definition: player.hpp:145
Response Eject(const std::string &tag)
Ejects the current loaded song, if any.
Definition: player.cpp:85
static Response Failure(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a failed request.
Definition: response.cpp:62
std::unique_ptr< Audio > LoadRaw(const std::string &path) const
Loads a file, creating an Audio for it.
Definition: player.cpp:306
std::uint64_t last_pos
The last-sent position.
Definition: player.hpp:147
Response Dump(size_t id, const std::string &tag) const
Dumps the current player state to the given ID.
Definition: player.cpp:65
std::unique_ptr< Audio > file
The loaded audio file.
Definition: player.hpp:144
static Response Invalid(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a invalid request.
Definition: response.cpp:56

§ LoadRaw()

std::unique_ptr< Audio > Player::LoadRaw ( const std::string &  path) const
private

Loads a file, creating an Audio for it.

Parameters
pathThe path to a file.
Returns
A unique pointer to the Audio for that file.

Definition at line 306 of file player.cpp.

References device_id, LoadSource(), and sink.

Referenced by Load().

307 {
308  std::unique_ptr<AudioSource> source = this->LoadSource(path);
309  assert(source != nullptr);
310 
311  auto sink = this->sink(*source, this->device_id);
312  return std::make_unique<PipeAudio>(std::move(source), std::move(sink));
313 }
int device_id
The sink&#39;s device ID.
Definition: player.hpp:141
std::unique_ptr< AudioSource > LoadSource(const std::string &path) const
Loads a file, creating an AudioSource.
Definition: player.cpp:315
SinkFn sink
The sink create function.
Definition: player.hpp:142

§ LoadSource()

std::unique_ptr< AudioSource > Player::LoadSource ( const std::string &  path) const
private

Loads a file, creating an AudioSource.

Parameters
pathThe path to the file to load.
Returns
An AudioSource pointer (may be nullptr, if no available and suitable AudioSource was found).
See also
Load

Definition at line 315 of file player.cpp.

References sources.

Referenced by LoadRaw().

316 {
317  size_t extpoint = path.find_last_of('.');
318  std::string ext = path.substr(extpoint + 1);
319 
320  auto ibuilder = this->sources.find(ext);
321  if (ibuilder == this->sources.end()) {
322  throw FileError("Unknown file format: " + ext);
323  }
324 
325  return (ibuilder->second)(path);
326 }
An Error signifying that playd can&#39;t read a file.
Definition: errors.hpp:75
std::map< std::string, SourceFn > sources
The file formats map.
Definition: player.hpp:143

§ Pos()

Response Player::Pos ( const std::string &  tag,
const std::string &  pos_str 
)

Seeks to a given position in the current file.

Parameters
tagThe tag of the request calling this command. For unsolicited seeks, use Response::NOREQUEST.
pos_strA string containing a timestamp, in microseconds
Returns
Whether the seek succeeded.

Definition at line 155 of file player.cpp.

References dead, End(), Response::Failure(), Response::Invalid(), Error::Message(), MSG_CMD_NEEDS_LOADED, MSG_CMD_PLAYER_CLOSING, PosParse(), PosRaw(), and Response::Success().

Referenced by Connection::RunCommand().

156 {
157  if (this->dead) return Response::Failure(tag, MSG_CMD_PLAYER_CLOSING);
158 
159  std::uint64_t pos = 0;
160  try {
161  pos = PosParse(pos_str);
162  } catch (SeekError &e) {
163  // Seek errors here are a result of clients sending weird times.
164  // Thus, we tell them off.
165  return Response::Invalid(tag, e.Message());
166  }
167 
168  try {
169  this->PosRaw(tag, pos);
170  } catch (NoAudioError) {
172  } catch (SeekError) {
173  // Seek failures here are a result of the decoder not liking the
174  // seek position (usually because it's outside the audio file!).
175  // Thus, unlike above, we try to recover.
176 
177  Debug() << "Seek failure" << std::endl;
178 
179  // Make it look to the client as if the seek ran off the end of
180  // the file.
181  this->End(tag);
182  }
183 
184  // If we've made it all the way down here, we deserve to succeed.
185  return Response::Success(tag);
186 }
static std::uint64_t PosParse(const std::string &pos_str)
Parses pos_str as a seek timestamp.
Definition: player.cpp:223
const std::string MSG_CMD_NEEDS_LOADED
Message shown when a command that works only when a file is loaded is fired when there isn&#39;t anything...
Definition: messages.h:42
void PosRaw(const std::string &tag, std::uint64_t pos)
Performs an actual seek.
Definition: player.cpp:252
const std::string MSG_CMD_PLAYER_CLOSING
Message shown when a command is sent to a closing Player.
Definition: messages.h:57
const std::string & Message() const
The human-readable message for this error.
Definition: errors.cpp:16
static Response Success(const std::string &tag)
Shortcut for constructing a final response to a successful request.
Definition: response.cpp:49
bool dead
Whether the Player is closing.
Definition: player.hpp:145
static Response Failure(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a failed request.
Definition: response.cpp:62
An Error signifying that playd can&#39;t seek in a file.
Definition: errors.hpp:90
Class for telling the human what playd is doing.
Definition: errors.hpp:133
Response End(const std::string &tag)
Ends a file, stopping and rewinding.
Definition: player.cpp:104
An Error signifying that no audio is loaded.
Definition: errors.hpp:120
static Response Invalid(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a invalid request.
Definition: response.cpp:56

§ PosParse()

std::uint64_t Player::PosParse ( const std::string &  pos_str)
staticprivate

Parses pos_str as a seek timestamp.

Parameters
pos_strThe time string to be parsed.
Returns
The parsed time.
Exceptions
std::out_of_rangeSee http://www.cplusplus.com/reference/string/stoull/#exceptions
std::invalid_argumentSee http://www.cplusplus.com/reference/string/stoull/#exceptions
SeekErrorRaised if checks beyond those done by stoull fail.

Definition at line 223 of file player.cpp.

References MSG_SEEK_INVALID_VALUE.

Referenced by Pos().

224 {
225  size_t cpos = 0;
226 
227  // Try and see if this position string is negative.
228  // Cheap and easy way: see if it has '-'.
229  // This means we don't need to skip whitespace first, with no loss
230  // of suction: no valid position string will contain '-'.
231  if (pos_str.find('-') != std::string::npos) {
233  }
234 
235 
236  std::uint64_t pos;
237  try {
238  pos = std::stoull(pos_str, &cpos);
239  } catch (...) {
241  }
242 
243  // cpos will point to the first character in pos that wasn't a number.
244  // We don't want any such characters here, so bail if the position isn't
245  // at the end of the string.
246  auto sl = pos_str.length();
247  if (cpos != sl) throw SeekError(MSG_SEEK_INVALID_VALUE);
248 
249  return pos;
250 }
An Error signifying that playd can&#39;t seek in a file.
Definition: errors.hpp:90
const std::string MSG_SEEK_INVALID_VALUE
Message shown when a seek command has an invalid time value.
Definition: messages.h:98

§ PosRaw()

void Player::PosRaw ( const std::string &  tag,
std::uint64_t  pos 
)
private

Performs an actual seek.

This does not do any EOF handling.

Parameters
tagThe tag of the request calling this command. For unsolicited seeks, use Response::NOREQUEST.
posThe new position, in microseconds.
Exceptions
SeekErrorRaised if the seek is out of range (usually EOF).
See also
Player::Seek

Definition at line 252 of file player.cpp.

References file, last_pos, Response::POS, and Respond().

Referenced by End(), and Pos().

253 {
254  assert(this->file != nullptr);
255 
256  this->file->SetPosition(pos);
257 
258  // This is required to make CanAnnounceTime() continue working.
259  this->last_pos = pos / 1000 / 1000;
260 
261  this->Respond(0, Response(tag, Response::Code::POS)
262  .AddArg(std::to_string(pos)));
263 }
A response.
Definition: response.hpp:23
void Respond(int id, Response rs) const
Outputs a response, if there is a ResponseSink attached.
Definition: player.cpp:290
std::uint64_t last_pos
The last-sent position.
Definition: player.hpp:147
std::unique_ptr< Audio > file
The loaded audio file.
Definition: player.hpp:144
Server sending current song time.

§ Quit()

Response Player::Quit ( const std::string &  tag)

Quits playd.

Parameters
tagThe tag of the request calling this command. For unsolicited quits, use Response::NOREQUEST.
Returns
Whether the quit succeeded.

Definition at line 210 of file player.cpp.

References dead, Eject(), Response::Failure(), MSG_CMD_PLAYER_CLOSING, and Response::Success().

211 {
212  if (this->dead) return Response::Failure(tag, MSG_CMD_PLAYER_CLOSING);
213 
214  this->Eject(tag);
215  this->dead = true;
216  return Response::Success(tag);
217 }
const std::string MSG_CMD_PLAYER_CLOSING
Message shown when a command is sent to a closing Player.
Definition: messages.h:57
static Response Success(const std::string &tag)
Shortcut for constructing a final response to a successful request.
Definition: response.cpp:49
bool dead
Whether the Player is closing.
Definition: player.hpp:145
Response Eject(const std::string &tag)
Ejects the current loaded song, if any.
Definition: player.cpp:85
static Response Failure(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a failed request.
Definition: response.cpp:62

§ Respond()

void Player::Respond ( int  id,
Response  rs 
) const
private

Outputs a response, if there is a ResponseSink attached.

Otherwise, this method does nothing.

Parameters
idThe ID of the client receiving this response. Use 0 for broadcasts.
responseThe Response to output.

Definition at line 290 of file player.cpp.

References io, and ResponseSink::Respond().

Referenced by Dump(), DumpState(), End(), PosRaw(), and Update().

291 {
292  if (this->io != nullptr) this->io->Respond(id, rs);
293 }
virtual void Respond(size_t id, const Response &response) const
Outputs a response.
Definition: response.cpp:97
const ResponseSink * io
The sink for responses.
Definition: player.hpp:146

§ SetIo()

void Player::SetIo ( ResponseSink io)

Sets the ResponseSink to which this Player shall send responses.

This sink shall be the target for WelcomeClient, as well as any responses generated by RunCommand or Update.

Parameters
ioThe response sink (invariably the IO system).

Definition at line 36 of file player.cpp.

References io.

37 {
38  this->io = &io;
39 }
const ResponseSink * io
The sink for responses.
Definition: player.hpp:146

§ SetPlaying()

Response Player::SetPlaying ( const std::string &  tag,
bool  playing 
)

Tells the audio file to start or stop playing.

Parameters
tagThe tag of the request calling this command. For unsolicited state changes, use Response::NOREQUEST.
playingTrue if playing; false otherwise.
See also
Play
Stop

Definition at line 188 of file player.cpp.

References dead, DumpState(), Response::Failure(), file, Response::Invalid(), Error::Message(), MSG_CMD_PLAYER_CLOSING, Response::NOREQUEST, and Response::Success().

Referenced by End(), and Connection::RunCommand().

189 {
190  if (this->dead) return Response::Failure(tag, MSG_CMD_PLAYER_CLOSING);
191 
192  // Why is SetPlaying not split between Start() and Stop()?, I hear the
193  // best practices purists amongst you say. Quite simply, there is a
194  // large amount of fiddly exception boilerplate here that would
195  // otherwise be duplicated between the two methods.
196 
197  assert(this->file != nullptr);
198 
199  try {
200  this->file->SetPlaying(playing);
201  } catch (NoAudioError &e) {
202  return Response::Invalid(tag, e.Message());
203  }
204 
205  this->DumpState(0, Response::NOREQUEST);
206 
207  return Response::Success(tag);
208 }
const std::string MSG_CMD_PLAYER_CLOSING
Message shown when a command is sent to a closing Player.
Definition: messages.h:57
static const std::string NOREQUEST
The tag for unsolicited messages (not from responses).
Definition: response.hpp:27
const std::string & Message() const
The human-readable message for this error.
Definition: errors.cpp:16
static Response Success(const std::string &tag)
Shortcut for constructing a final response to a successful request.
Definition: response.cpp:49
bool dead
Whether the Player is closing.
Definition: player.hpp:145
static Response Failure(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a failed request.
Definition: response.cpp:62
void DumpState(size_t id, const std::string &tag) const
Emits a response for the current audio state to the sink.
Definition: player.cpp:265
std::unique_ptr< Audio > file
The loaded audio file.
Definition: player.hpp:144
An Error signifying that no audio is loaded.
Definition: errors.hpp:120
static Response Invalid(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a invalid request.
Definition: response.cpp:56

§ Update()

bool Player::Update ( )

Instructs the Player to perform a cycle of work.

This includes decoding the next frame and responding to commands.

Returns
Whether the player has more cycles of work to do.

Definition at line 41 of file player.cpp.

References Audio::AT_END, CanAnnounceTime(), dead, End(), file, Response::NOREQUEST, Audio::PLAYING, Response::POS, and Respond().

Referenced by IoCore::UpdatePlayer().

42 {
43  assert(this->file != nullptr);
44  auto as = this->file->Update();
45 
47  if (as == Audio::State::PLAYING) {
48  // Since the audio is currently playing, the position may have
49  // advanced since last update. So we need to update it.
50  auto pos = this->file->Position();
51  if (this->CanAnnounceTime(pos)) {
54  .AddArg(std::to_string(pos)));
55  }
56  }
57 
58  return !this->dead;
59 }
The Audio is currently playing.
A response.
Definition: response.hpp:23
The Audio has ended and can&#39;t play without a seek.
void Respond(int id, Response rs) const
Outputs a response, if there is a ResponseSink attached.
Definition: player.cpp:290
static const std::string NOREQUEST
The tag for unsolicited messages (not from responses).
Definition: response.hpp:27
bool CanAnnounceTime(std::uint64_t micros)
Determines whether we can broadcast a POS response.
Definition: player.cpp:295
bool dead
Whether the Player is closing.
Definition: player.hpp:145
std::unique_ptr< Audio > file
The loaded audio file.
Definition: player.hpp:144
Response End(const std::string &tag)
Ends a file, stopping and rewinding.
Definition: player.cpp:104
Server sending current song time.

The documentation for this class was generated from the following files: