This repository has been archived by the owner on Feb 8, 2018. It is now read-only.
/
audio-alsa.h
135 lines (101 loc) · 2.96 KB
/
audio-alsa.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* audio-alsa.h:
*
* Contact:
* Moonlight List (moonlight-list@lists.ximian.com)
*
* Copyright 2008 Novell, Inc. (http://www.novell.com)
*
* See the LICENSE file included with the distribution for details.
*/
#if INCLUDE_ALSA
#ifndef __AUDIO_ALSA_H__
#define __AUDIO_ALSA_H__
#include <poll.h>
#include <asoundlib.h>
#include "audio.h"
namespace Moonlight {
class AlsaPlayer;
class AlsaSource : public AudioSource {
AlsaPlayer *player;
snd_pcm_t *pcm;
snd_pcm_uframes_t period_size;
snd_pcm_uframes_t buffer_size;
MoonMutex mutex;
bool initialized;
bool mmap;
bool started;
bool drop_pending;
bool SetupHW ();
bool PreparePcm (snd_pcm_sframes_t *avail);
// Underrun recovery
// Handles EPIPE and ESTRPIPE, prints an error if recovery failed
// or if err isn't any of the above values.
bool XrunRecovery (int err);
bool WriteRW ();
bool WriteMmap ();
void Drain ();
bool InitializeAlsa ();
void CloseAlsa ();
protected:
virtual ~AlsaSource ();
virtual void Played ();
virtual void Paused ();
virtual void Stopped ();
virtual void StateChanged (AudioState old_state);
virtual guint64 GetDelayInternal ();
virtual bool InitializeInternal ();
virtual void CloseInternal ();
public:
pollfd *udfs;
int ndfs;
/* @SkipFactories */
AlsaSource (AlsaPlayer *player, MediaPlayer *mplayer, AudioStream *stream);
// Pushes data onto the pcm device if the
// device can accept more data, and if the
// there is data availabe. The node has to
// be locked during playback.
// Returns false if nothing has been played.
bool WriteAlsa ();
bool IsDropPending () { return drop_pending; }
void DropAlsa ();
};
class AlsaPlayer : public AudioPlayer {
// The audio thread
MoonThread *audio_thread;
bool shutdown; // set to true to exit the audio thread.
// A list of all the file descriptors in all the
// audio nodes. We need to poll on changes in any of the
// descriptors, so we create a big list with all of them
// and poll on that.
pollfd *udfs;
int ndfs;
// We also need to be able to wake up from the poll
// whenever we want to, so we create a pipe which we
// poll on. This is always the first file descriptor
// in udfs.
int fds [2];
// If UpdatePollList must be called before polling.
bool update_poll_pending;
// The audio loop which is executed
// on the audio thread.
void Loop ();
static void *Loop (void *data);
void WakeUp (); // Wakes up the audio thread.
protected:
virtual ~AlsaPlayer ();
virtual void AddInternal (AudioSource *node);
virtual void RemoveInternal (AudioSource *node);
virtual void PrepareShutdownInternal ();
virtual void FinishShutdownInternal ();
virtual bool Initialize ();
virtual AudioSource *CreateNode (MediaPlayer *mplayer, AudioStream *stream);
public:
AlsaPlayer ();
void UpdatePollList ();
static bool IsInstalled ();
};
};
#endif /* __AUDI_ALSA_H__ */
#endif /* INCLUDE_ALSA */