MPD  0.20.18
Internal.hxx
Go to the documentation of this file.
1 /*
2  * Copyright 2003-2017 The Music Player Daemon Project
3  * http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef MPD_OUTPUT_INTERNAL_HXX
21 #define MPD_OUTPUT_INTERNAL_HXX
22 
23 #include "Source.hxx"
24 #include "SharedPipeConsumer.hxx"
25 #include "AudioFormat.hxx"
26 #include "filter/Observer.hxx"
27 #include "thread/Mutex.hxx"
28 #include "thread/Cond.hxx"
29 #include "thread/Thread.hxx"
30 #include "system/PeriodClock.hxx"
31 
32 #include <exception>
33 
34 class PreparedFilter;
35 class MusicPipe;
36 class EventLoop;
37 class Mixer;
38 class MixerListener;
39 class AudioOutputClient;
40 struct MusicChunk;
41 struct ConfigBlock;
42 struct AudioOutputPlugin;
43 struct ReplayGainConfig;
44 
45 struct AudioOutput {
46  enum class Command {
47  NONE,
48  ENABLE,
49  DISABLE,
50 
55  OPEN,
56 
57  CLOSE,
58  PAUSE,
59 
64  DRAIN,
65 
66  CANCEL,
67  KILL
68  };
69 
73  const char *name;
74 
79 
85  Mixer *mixer = nullptr;
86 
92  bool tags;
93 
98  bool always_on;
99 
103  bool enabled = true;
104 
109  bool really_enabled = false;
110 
119  bool open = false;
120 
125  bool pause = false;
126 
134  bool allow_play = true;
135 
142  bool in_playback_loop = false;
143 
149  bool woken_for_play = false;
150 
157 
162 
170 
178 
184 
190 
196 
203 
211 
217 
222 
226  struct Request {
231 
235  const MusicPipe *pipe;
236  } request;
237 
241  mutable Mutex mutex;
242 
248 
254 
259 
266  std::exception_ptr last_error;
267 
271  AudioOutput(const AudioOutputPlugin &_plugin,
272  const ConfigBlock &block);
273 
274  ~AudioOutput();
275 
276 private:
277  void Configure(const ConfigBlock &block);
278 
279 public:
280  void Setup(EventLoop &event_loop,
281  const ReplayGainConfig &replay_gain_config,
282  MixerListener &mixer_listener,
283  const ConfigBlock &block);
284 
285  void StartThread();
286  void StopThread();
287 
288  void BeginDestroy();
289  void FinishDestroy();
290 
291  const char *GetName() const {
292  return name;
293  }
294 
298  bool IsEnabled() const {
299  return enabled;
300  }
301 
305  bool IsOpen() const {
306  return open;
307  }
308 
312  bool IsCommandFinished() const {
313  return command == Command::NONE;
314  }
315 
319  const std::exception_ptr &GetLastError() const {
320  return last_error;
321  }
322 
328  void WaitForCommand();
329 
335  void CommandAsync(Command cmd);
336 
343  void CommandWait(Command cmd);
344 
349  void LockCommandWait(Command cmd);
350 
356  void EnableAsync();
357 
363  void DisableAsync();
364 
373  if (enabled == really_enabled)
374  return;
375 
376  if (enabled)
377  EnableAsync();
378  else
379  DisableAsync();
380  }
381 
382  void LockPauseAsync();
383 
388  void CloseWait();
389  void LockCloseWait();
390 
395  void LockRelease();
396 
398  source.SetReplayGainMode(_mode);
399  }
400 
404  bool Open(const AudioFormat audio_format, const MusicPipe &mp);
405 
413  bool LockUpdate(const AudioFormat audio_format,
414  const MusicPipe &mp,
415  bool force);
416 
417  void LockPlay();
418 
419  void LockDrainAsync();
420 
426  void LockCancelAsync();
427 
431  void LockAllowPlay();
432 
438  gcc_pure
439  bool IsChunkConsumed(const MusicChunk &chunk) const noexcept;
440 
441  gcc_pure
442  bool LockIsChunkConsumed(const MusicChunk &chunk) noexcept {
443  const std::lock_guard<Mutex> protect(mutex);
444  return IsChunkConsumed(chunk);
445  }
446 
447  void ClearTailChunk(const MusicChunk &chunk) {
448  source.ClearTailChunk(chunk);
449  }
450 
451 private:
452  void CommandFinished();
453 
457  void Enable();
458 
459  void Disable();
460 
464  void Open();
465 
474  void OpenOutputAndConvert(AudioFormat audio_format);
475 
476  void Close(bool drain);
477 
483  void CloseOutput(bool drain);
484 
488  void CloseFilter();
489 
496  bool WaitForDelay();
497 
498  bool FillSourceOrClose();
499 
500  bool PlayChunk();
501 
510  bool Play();
511 
512  void Pause();
513 
517  void Task();
518 };
519 
524 extern struct notify audio_output_client_notify;
525 
529 AudioOutput *
530 audio_output_new(EventLoop &event_loop,
531  const ReplayGainConfig &replay_gain_config,
532  const ConfigBlock &block,
533  MixerListener &mixer_listener,
534  AudioOutputClient &client);
535 
536 void
538 
539 #endif
AudioOutputSource source
Source of audio data.
Definition: Internal.hxx:258
bool always_on
Shall this output always play something (i.e.
Definition: Internal.hxx:98
struct AudioOutput::Request request
void SetReplayGainMode(ReplayGainMode _mode)
Definition: Internal.hxx:397
PeriodClock fail_timer
If not nullptr, the device has failed, and this timer is used to estimate how long it should stay dis...
Definition: Internal.hxx:156
bool pause
Is the device paused? i.e.
Definition: Internal.hxx:125
ReplayGainMode
std::exception_ptr last_error
The error that occurred in the output thread.
Definition: Internal.hxx:266
This structure describes the format of a raw PCM stream.
Definition: AudioFormat.hxx:37
void LockCloseWait()
Mixer * mixer
The mixer object associated with this audio output device.
Definition: Internal.hxx:85
AudioFormat audio_format
The AudioFormat requested by #Command::OPEN.
Definition: Internal.hxx:230
An interface between the AudioOutput and the #Player.
Definition: Client.hxx:28
const char * GetName() const
Definition: Internal.hxx:291
const std::exception_ptr & GetLastError() const
Caller must lock the mutex.
Definition: Internal.hxx:319
A queue of MusicChunk objects.
Definition: MusicPipe.hxx:39
void EnableDisableAsync()
Attempt to enable or disable the device as specified by the enabled attribute; attempt to sync it wit...
Definition: Internal.hxx:372
AudioFormat config_audio_format
The configured audio format.
Definition: Internal.hxx:161
struct notify audio_output_client_notify
Notify object used by the thread&#39;s client, i.e.
Command command
The next command to be performed by the output thread.
Definition: Internal.hxx:221
An event loop that polls for events on file/socket descriptors.
Definition: Loop.hxx:52
void CloseWait()
Same LockCloseWait(), but expects the lock to be held by the caller.
Definition: Cond.hxx:41
Definition: Mutex.hxx:43
void BeginDestroy()
bool LockUpdate(const AudioFormat audio_format, const MusicPipe &mp, bool force)
Opens or closes the device, depending on the "enabled" flag.
AudioOutput(const AudioOutputPlugin &_plugin, const ConfigBlock &block)
Throws #std::runtime_error on error.
bool open
Is the device (already) open and functional?
Definition: Internal.hxx:119
PreparedFilter * prepared_other_replay_gain_filter
The replay_gain_filter_plugin instance of this audio output, to be applied to the second chunk during...
Definition: Internal.hxx:202
void LockCommandWait(Command cmd)
Lock the AudioOutput object and execute the command synchronously.
Mutex mutex
This mutex protects open, fail_timer, #pipe.
Definition: Internal.hxx:241
A chunk of music data.
Definition: MusicChunk.hxx:43
Source of audio data to be played by an AudioOutput.
Definition: Source.hxx:49
A helper class which observes calls to a PreparedFilter and allows the caller to access the Filter in...
Definition: Observer.hxx:32
void StartThread()
void CommandWait(Command cmd)
Sends a command to the AudioOutput object and waits for completion.
FilterObserver volume_filter
The #VolumeFilter instance of this audio output.
Definition: Internal.hxx:189
Open the output, or reopen it if it is already open, adjusting for input AudioFormat changes...
void DisableAsync()
Disables the device, but don&#39;t wait for completion.
Thread thread
The thread handle, or nullptr if the output thread isn&#39;t running.
Definition: Internal.hxx:216
AudioFormat filter_audio_format
The AudioFormat which is emitted by the Filter, with config_audio_format already applied.
Definition: Internal.hxx:169
void StopThread()
bool tags
Will this output receive tags from the decoder? The default is true, but it may be configured to fals...
Definition: Internal.hxx:92
void LockPauseAsync()
gcc_pure bool LockIsChunkConsumed(const MusicChunk &chunk) noexcept
Definition: Internal.hxx:442
void LockAllowPlay()
Set the "allow_play" and signal the thread.
AudioOutputClient * client
The PlayerControl object which "owns" this output.
Definition: Internal.hxx:253
bool IsCommandFinished() const
Caller must lock the mutex.
Definition: Internal.hxx:312
AudioOutput * audio_output_new(EventLoop &event_loop, const ReplayGainConfig &replay_gain_config, const ConfigBlock &block, MixerListener &mixer_listener, AudioOutputClient &client)
Throws #std::runtime_error on error.
bool IsEnabled() const
Caller must lock the mutex.
Definition: Internal.hxx:298
AudioFormat out_audio_format
The audio_format which is really sent to the device.
Definition: Internal.hxx:177
bool woken_for_play
Has the OutputThread been woken up to play more chunks? This is set by audio_output_play() and reset ...
Definition: Internal.hxx:149
gcc_pure bool IsChunkConsumed(const MusicChunk &chunk) const noexcept
Did we already consumed this chunk?
void LockDrainAsync()
FilterObserver convert_filter
The convert_filter_plugin instance of this audio output.
Definition: Internal.hxx:210
PreparedFilter * prepared_filter
The filter object of this audio output.
Definition: Internal.hxx:183
void EnableAsync()
Enables the device, but don&#39;t wait for completion.
void FinishDestroy()
bool in_playback_loop
True while the OutputThread is inside ao_play().
Definition: Internal.hxx:142
void WaitForCommand()
Waits for command completion.
bool allow_play
When this flag is set, the output thread will not do any playback.
Definition: Internal.hxx:134
void CommandAsync(Command cmd)
Sends a command, but does not wait for completion.
const char * name
The device&#39;s configured display name.
Definition: Internal.hxx:73
An interface that listens on events from mixer plugins.
Definition: Listener.hxx:29
Additional data for command.
Definition: Internal.hxx:226
void audio_output_free(AudioOutput *ao)
void SetReplayGainMode(ReplayGainMode _mode)
Definition: Source.hxx:122
const MusicPipe * pipe
The MusicPipe passed to #Command::OPEN.
Definition: Internal.hxx:235
void Setup(EventLoop &event_loop, const ReplayGainConfig &replay_gain_config, MixerListener &mixer_listener, const ConfigBlock &block)
void ClearTailChunk(const MusicChunk &chunk)
Definition: Internal.hxx:447
bool enabled
Has the user enabled this device?
Definition: Internal.hxx:103
#define gcc_pure
Definition: Compiler.h:116
This is a stopwatch which saves the timestamp of an event, and can check whether a specified time spa...
Definition: PeriodClock.hxx:29
Cond cond
This condition object wakes up the output thread after command has been set.
Definition: Internal.hxx:247
void LockRelease()
Closes the audio output, but if the "always_on" flag is set, put it into pause mode instead...
Drains the internal (hardware) buffers of the device.
void LockPlay()
bool IsOpen() const
Caller must lock the mutex.
Definition: Internal.hxx:305
void LockCancelAsync()
Clear the "allow_play" flag and send the "CANCEL" command asynchronously.
const AudioOutputPlugin & plugin
The plugin which implements this output device.
Definition: Internal.hxx:78
bool really_enabled
Is this device actually enabled, i.e.
Definition: Internal.hxx:109
A plugin which controls an audio output device.
PreparedFilter * prepared_replay_gain_filter
The replay_gain_filter_plugin instance of this audio output.
Definition: Internal.hxx:195
void ClearTailChunk(const MusicChunk &chunk) noexcept
Definition: Source.hxx:190