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
bool IsOpen() const
Caller must lock the mutex.
Definition: Internal.hxx:305
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()
const std::exception_ptr & GetLastError() const
Caller must lock the mutex.
Definition: Internal.hxx:319
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
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'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't wait for completion.
Thread thread
The thread handle, or nullptr if the output thread isn'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
const char * GetName() const
Definition: Internal.hxx:291
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
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.
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'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'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
bool IsCommandFinished() const
Caller must lock the mutex.
Definition: Internal.hxx:312
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 IsEnabled() const
Caller must lock the mutex.
Definition: Internal.hxx:298
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()
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