xref: /haiku/src/add-ons/media/media-add-ons/opensound/OpenSoundNode.h (revision 83b1a68c52ba3e0e8796282759f694b7fdddf06d)
1 /*
2  * OpenSound media addon for BeOS and Haiku
3  *
4  * Copyright (c) 2007, François Revol (revol@free.fr)
5  * Copyright (c) 2002, 2003 Jerome Duval (jerome.duval@free.fr)
6  * Distributed under the terms of the MIT License.
7  *
8  */
9 #ifndef _OPENSOUNDNODE_H
10 #define _OPENSOUNDNODE_H
11 
12 #include <BufferConsumer.h>
13 #include <BufferProducer.h>
14 #include <Controllable.h>
15 #include <MediaEventLooper.h>
16 #include <MediaNode.h>
17 #include <Message.h>
18 #include <ParameterWeb.h>
19 #include <TimeSource.h>
20 
21 class OpenSoundDevice;
22 class OpenSoundDeviceEngine;
23 class OpenSoundDeviceMixer;
24 
25 struct audio_buf_info;
26 struct flavor_info;
27 
28 class OpenSoundNode : public BBufferConsumer, public BBufferProducer,
29 	public BTimeSource, public BMediaEventLooper, public BControllable {
30 
31 private:
32 	class NodeInput;
33 	class NodeOutput;
34 
35 protected:
36 	virtual						~OpenSoundNode();
37 
38 public:
39 	explicit					OpenSoundNode(BMediaAddOn* addon,
40 									const char* name,
41 									OpenSoundDevice* device,
42 									int32 internalID, BMessage* config);
43 
44 	virtual	status_t			InitCheck() const;
45 
46 	// BMediaNode interface
47 public:
48 	virtual	BMediaAddOn*		AddOn(int32* internalID) const;
49 		// Who instantiated you -- or NULL for app class
50 
51 protected:
52 	virtual	void				Preroll();
53 		// These don't return errors; instead, they use the global error
54 		// condition reporter. A node is required to have a queue of at
55 		// least one pending command (plus TimeWarp) and is recommended to
56 		// allow for at least one pending command of each type. Allowing an
57 		// arbitrary number of outstanding commands might be nice, but apps
58 		// cannot depend on that happening.
59 
60 public:
61 	virtual	status_t			HandleMessage(int32 message,
62 									const void* data, size_t size);
63 
64 protected:
65 	virtual	void				NodeRegistered();
66 	virtual	status_t			RequestCompleted(
67 									const media_request_info& info);
68 	virtual	void				SetTimeSource(BTimeSource* timeSource);
69 
70 	// BBufferConsumer interface
71 protected:
72 	virtual	status_t			AcceptFormat(
73 									const media_destination& dest,
74 									media_format* format);
75 	virtual	status_t			GetNextInput(int32* cookie,
76 									media_input* out_input);
77 	virtual	void				DisposeInputCookie(int32 cookie);
78 	virtual	void				BufferReceived(BBuffer* buffer);
79 	virtual	void				ProducerDataStatus(
80 									const media_destination& for_whom,
81 									int32 status,
82 									bigtime_t at_performance_time);
83 	virtual	status_t			GetLatencyFor(
84 									const media_destination& for_whom,
85 									bigtime_t* out_latency,
86 									media_node_id* out_timesource);
87 	virtual	status_t			Connected(const media_source& producer,
88 									const media_destination& where,
89 									const media_format& with_format,
90 									media_input* out_input);
91 			// here's a good place to request buffer group usage
92 
93 	virtual	void				Disconnected(const media_source& producer,
94 									const media_destination& where);
95 
96 	virtual	status_t			FormatChanged(const media_source& producer,
97 									const media_destination& consumer,
98 								int32 change_tag,
99 								const media_format& format);
100 
101 	virtual	status_t			SeekTagRequested(
102 									const media_destination& destination,
103 									bigtime_t in_target_time,
104 									uint32 in_flags,
105 									media_seek_tag* out_seek_tag,
106 									bigtime_t* out_tagged_time,
107 									uint32* out_flags);
108 
109 	// BBufferProducer interface
110 protected:
111 	virtual	status_t			FormatSuggestionRequested(media_type type,
112 									int32 quality, media_format* format);
113 
114 	virtual	status_t			FormatProposal(const media_source& output,
115 									media_format* format);
116 
117 	virtual	status_t			FormatChangeRequested(
118 									const media_source& source,
119 									const media_destination& destination,
120 									media_format* io_format,
121 									int32* _deprecated_);
122 	virtual	status_t			GetNextOutput(int32* cookie,
123 									media_output* out_output);
124 	virtual	status_t			DisposeOutputCookie(int32 cookie);
125 
126 	virtual	status_t			SetBufferGroup(
127 									const media_source& for_source,
128 									BBufferGroup* group);
129 
130 	virtual	status_t			PrepareToConnect(const media_source& what,
131 									const media_destination& where,
132 									media_format* format,
133 									media_source* out_source,
134 									char* out_name);
135 
136 	virtual	void				Connect(status_t error,
137 									const media_source& source,
138 									const media_destination& destination,
139 									const media_format& format,
140 									char* io_name);
141 
142 	virtual	void				Disconnect(const media_source& what,
143 									const media_destination& where);
144 
145 	virtual	void				LateNoticeReceived(
146 									const media_source& what,
147 									bigtime_t how_much,
148 									bigtime_t performance_time);
149 
150 	virtual	void				EnableOutput(const media_source& what,
151 									bool enabled, int32* _deprecated_);
152 	virtual	void				AdditionalBufferRequested(
153 									const media_source& source,
154 									media_buffer_id prev_buffer,
155 									bigtime_t prev_time,
156 									const media_seek_tag* prev_tag);
157 
158 	// BMediaEventLooper interface
159 protected:
160 		/* you must override to handle your events! */
161 		/* you should not call HandleEvent directly */
162 	virtual	void				HandleEvent(const media_timed_event* event,
163 									bigtime_t lateness,
164 									bool realTimeEvent = false);
165 
166 	// BTimeSource interface
167 protected:
168 	virtual	void				SetRunMode(run_mode mode);
169 	virtual	status_t			TimeSourceOp(const time_source_op_info& op,
170 									void* _reserved);
171 
172 	//  BControllable interface
173 protected:
174 	virtual	status_t			GetParameterValue(int32 id,
175 									bigtime_t* last_change,
176 									void* value, size_t* ioSize);
177 	virtual	void				SetParameterValue(int32 id,
178 									bigtime_t when, const void* value,
179 									size_t size);
180 	virtual	BParameterWeb*		MakeParameterWeb();
181 
182 private:
183 			void 				_ProcessGroup(BParameterGroup* group,
184 									int32 index, int32& _parameters);
185 			void 				_ProcessMux(BDiscreteParameter* parameter,
186 									int32 index);
187 			status_t			_PropagateParameterChanges(int from,
188 									int type, const char* id);
189 
190 protected:
191 	virtual	status_t			HandleStart(const media_timed_event* event,
192 									bigtime_t lateness,
193 									bool realTimeEvent = false);
194 	virtual	status_t			HandleSeek(const media_timed_event* event,
195 									bigtime_t lateness,
196 									bool realTimeEvent = false);
197 	virtual	status_t			HandleWarp(const media_timed_event* event,
198 									bigtime_t lateness,
199 									bool realTimeEvent = false);
200 	virtual	status_t			HandleStop(const media_timed_event* event,
201 									bigtime_t lateness,
202 									bool realTimeEvent = false);
203 	virtual	status_t			HandleBuffer(
204 									const media_timed_event* event,
205 									bigtime_t lateness,
206 									bool realTimeEvent = false);
207 	virtual	status_t			HandleDataStatus(
208 									const media_timed_event* event,
209 									bigtime_t lateness,
210 									bool realTimeEvent = false);
211 	virtual	status_t			HandleParameter(
212 									const media_timed_event* event,
213 									bigtime_t lateness,
214 									bool realTimeEvent = false);
215 
216 public:
217 	static	void				GetFlavor(flavor_info* outInfo, int32 id);
218 	static	void				GetFormat(media_format* outFormat);
219 
220 			status_t			GetConfigurationFor(BMessage* intoMessage);
221 
222 
223 private:
224 								OpenSoundNode(const OpenSoundNode& clone);
225 									// private unimplemented
226 			OpenSoundNode&		operator=(const OpenSoundNode& clone);
227 
228 private:
229 	static	void				_SignalHandler(int sig);
230 
231 	static	int32				_PlayThreadEntry(void* data);
232 	static	int32				_RecThreadEntry(void* data);
233 			int32				_PlayThread(NodeInput* input);
234 			int32				_RecThread(NodeOutput* output);
235 
236 			status_t			_StartPlayThread(NodeInput* input);
237 			status_t			_StopPlayThread(NodeInput* input);
238 			status_t			_StartRecThread(NodeOutput* output);
239 			status_t			_StopRecThread(NodeOutput* output);
240 
241 			BBuffer* 			_FillNextBuffer(audio_buf_info* abinfo,
242 									NodeOutput& channel);
243 			void				_UpdateTimeSource(bigtime_t performanceTime,
244 									bigtime_t realTime, float drift);
245 
246 
247 			NodeOutput* 		_FindOutput(
248 									const media_source& source) const;
249 			NodeInput* 			_FindInput(
250 									const media_destination& dest) const;
251 			NodeInput* 			_FindInput(int32 destinationId);
252 
253 private:
254 			status_t			fInitCheckStatus;
255 
256 			BMediaAddOn*		fAddOn;
257 			int32				fId;
258 
259 			BList				fInputs;
260 			BList				fOutputs;
261 
262 #if 1
263 			// TODO: remove and use use a preferred format
264 			// per NodeInput/NodeOutput channel
265 			media_format 		fPreferredFormat;
266 #endif
267 			bigtime_t 			fLatency;
268 			bigtime_t			fInternalLatency;
269 				// this is computed from the real (negotiated) chunk size
270 				// and bit rate, not the defaults that are in the
271 				// parameters
272 			OpenSoundDevice*	fDevice;
273 
274 			bool 				fTimeSourceStarted;
275 			bigtime_t			fTimeSourceStartTime;
276 
277 			BParameterWeb*		fWeb;
278 			BMessage			fConfig;
279 };
280 
281 #endif // _OPENSOUNDNODE_H
282