Welcome to mirror list, hosted at ThFree Co, Russian Federation.

PulseAudioDevice.h « pulseaudio « plugins « audaspace « extern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 5735911063335b9a4ae2513a562964593166f0cb (plain)
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
136
137
138
139
140
141
142
143
144
145
146
/*******************************************************************************
 * Copyright 2009-2016 Jörg Müller
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

#pragma once

#ifdef PULSEAUDIO_PLUGIN
#define AUD_BUILD_PLUGIN
#endif

/**
 * @file PulseAudioDevice.h
 * @ingroup plugin
 * The PulseAudioDevice class.
 */

#include "devices/SoftwareDevice.h"
#include "util/RingBuffer.h"

#include <condition_variable>
#include <thread>

#include <pulse/pulseaudio.h>

AUD_NAMESPACE_BEGIN

/**
 * This device plays back through PulseAudio, the simple direct media layer.
 */
class AUD_PLUGIN_API PulseAudioDevice : public SoftwareDevice
{
private:
	class PulseAudioSynchronizer : public DefaultSynchronizer
	{
		PulseAudioDevice* m_device;

	public:
		PulseAudioSynchronizer(PulseAudioDevice* device);

		virtual double getPosition(std::shared_ptr<IHandle> handle);
	};

	/// Synchronizer.
	PulseAudioSynchronizer m_synchronizer;

	/**
	 * Whether there is currently playback.
	 */
	volatile bool m_playback;

	pa_threaded_mainloop* m_mainloop;
	pa_context* m_context;
	pa_stream* m_stream;
	pa_context_state_t m_state;

	/**
	 * The mixing ring buffer.
	 */
	RingBuffer m_ring_buffer;

	/**
	 * Whether the device is valid.
	 */
	bool m_valid;

	int m_buffersize;
	uint32_t m_underflows;

	/**
	 * The mixing thread.
	 */
	std::thread m_mixingThread;

	/**
	 * Mutex for mixing.
	 */
	std::mutex m_mixingLock;

	/**
	 * Condition for mixing.
	 */
	std::condition_variable m_mixingCondition;

	/**
	 * Updates the ring buffer.
	 */
	AUD_LOCAL void updateRingBuffer();

	/**
	 * Reports the state of the PulseAudio server connection.
	 * \param context The PulseAudio context.
	 * \param data The PulseAudio device.
	 */
	AUD_LOCAL static void PulseAudio_state_callback(pa_context* context, void* data);

	/**
	 * Supplies the next samples to PulseAudio.
	 * \param stream The PulseAudio stream.
	 * \param num_bytes The length in bytes to be supplied.
	 * \param data The PulseAudio device.
	 */
	AUD_LOCAL static void PulseAudio_request(pa_stream* stream, size_t total_bytes, void* data);

	// delete copy constructor and operator=
	PulseAudioDevice(const PulseAudioDevice&) = delete;
	PulseAudioDevice& operator=(const PulseAudioDevice&) = delete;

protected:
	virtual void playing(bool playing);

public:
	/**
	 * Opens the PulseAudio audio device for playback.
	 * \param specs The wanted audio specification.
	 * \param buffersize The size of the internal buffer.
	 * \note The specification really used for opening the device may differ.
	 * \exception Exception Thrown if the audio device cannot be opened.
	 */
	PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);

	/**
	 * Closes the PulseAudio audio device.
	 */
	virtual ~PulseAudioDevice();

	virtual ISynchronizer* getSynchronizer();

	/**
	 * Registers this plugin.
	 */
	static void registerPlugin();
};

AUD_NAMESPACE_END