xref: /haiku/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h (revision 5e7964b0a929555415798dea3373db9ac4611caa)
1 /*
2  * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef MULTI_AUDIO_NODE_H
6 #define MULTI_AUDIO_NODE_H
7 
8 
9 #include <BufferConsumer.h>
10 #include <BufferProducer.h>
11 #include <Controllable.h>
12 #include <Locker.h>
13 #include <MediaAddOn.h>
14 #include <MediaDefs.h>
15 #include <MediaEventLooper.h>
16 #include <MediaNode.h>
17 #include <Message.h>
18 #include <TimeSource.h>
19 
20 #include "hmulti_audio.h"
21 #include "MultiAudioDevice.h"
22 #include "TimeComputer.h"
23 
24 
25 class BDiscreteParameter;
26 class BParameterGroup;
27 
28 class node_input;
29 class node_output;
30 
31 
32 class MultiAudioNode : public BBufferConsumer, public BBufferProducer,
33 		public BTimeSource,	public BMediaEventLooper, public BControllable {
34 protected:
35 	virtual						~MultiAudioNode();
36 
37 public:
38 								MultiAudioNode(BMediaAddOn* addon,
39 									const char* name, MultiAudioDevice* device,
40 									int32 internalID, BMessage* config);
41 
42 	virtual status_t			InitCheck() const;
43 
44 	static	void				GetFlavor(flavor_info* info, int32 id);
45 	static	void				GetFormat(media_format* outFormat);
46 
47 			status_t			GetConfigurationFor(BMessage* message);
48 
49 	// BMediaNode methods
50 	virtual	BMediaAddOn*		AddOn(int32* internalID) const;
51 	virtual	status_t			HandleMessage(int32 message, const void* data,
52 									size_t size);
53 
54 protected:
55 	virtual	void				Preroll();
56 	virtual	void				NodeRegistered();
57 	virtual	status_t			RequestCompleted(
58 									const media_request_info& info);
59 	virtual	void				SetTimeSource(BTimeSource* timeSource);
60 
61 	// BBufferConsumer methods
62 
63 	virtual	status_t			AcceptFormat(const media_destination& dest,
64 									media_format* format);
65 	virtual	status_t			GetNextInput(int32* cookie, media_input* input);
66 	virtual	void				DisposeInputCookie(int32 cookie);
67 	virtual	void				BufferReceived(BBuffer* buffer);
68 	virtual	void				ProducerDataStatus(
69 									const media_destination& forWhom,
70 									int32 status, bigtime_t atPerformanceTime);
71 	virtual	status_t			GetLatencyFor(const media_destination& forWhom,
72 									bigtime_t* latency,
73 									media_node_id* timeSource);
74 	virtual	status_t	 		Connected(const media_source& producer,
75 									const media_destination& where,
76 									const media_format& withFormat,
77 									media_input* input);
78 	virtual	void				Disconnected(const media_source& producer,
79 									const media_destination& where);
80 	virtual	status_t			FormatChanged(const media_source& producer,
81 									const media_destination& consumer,
82 									int32 changeTag,
83 									const media_format& format);
84 
85 	virtual	status_t			SeekTagRequested(
86 									const media_destination& destination,
87 									bigtime_t targetTime, uint32 flags,
88 									media_seek_tag* _seekTag,
89 									bigtime_t* _taggedTime, uint32* _flags);
90 
91 	// BBufferProducer methods
92 
93 	virtual status_t			FormatSuggestionRequested(media_type type,
94 									int32 quality, media_format* format);
95 
96 	virtual status_t			FormatProposal(const media_source& output,
97 									media_format* format);
98 
99 	virtual status_t			FormatChangeRequested(
100 									const media_source& source,
101 									const media_destination& destination,
102 									media_format* ioFormat,
103 									int32* _deprecated);
104 	virtual status_t			GetNextOutput(int32* cookie,
105 									media_output* _output);
106 	virtual status_t			DisposeOutputCookie(int32 cookie);
107 
108 	virtual	status_t			SetBufferGroup(const media_source& forSource,
109 									BBufferGroup* group);
110 
111 	virtual status_t			PrepareToConnect(const media_source& what,
112 									const media_destination& where,
113 									media_format* format, media_source* source,
114 									char* name);
115 
116 	virtual void				Connect(status_t error,
117 									const media_source& source,
118 									const media_destination& destination,
119 									const media_format& format, char* name);
120 	virtual void				Disconnect(const media_source& what,
121 									const media_destination& where);
122 
123 	virtual void				LateNoticeReceived(const media_source& what,
124 									bigtime_t howMuch,
125 									bigtime_t performanceTime);
126 
127 	virtual void				EnableOutput(const media_source& what,
128 									bool enabled, int32* _deprecated);
129 	virtual void				AdditionalBufferRequested(
130 									const media_source& source,
131 									media_buffer_id previousBuffer,
132 									bigtime_t previousTime,
133 									const media_seek_tag* previousTag);
134 
135 	// BMediaEventLooper methods
136 	virtual void				HandleEvent(const media_timed_event* event,
137 									bigtime_t lateness,
138 									bool realTimeEvent = false);
139 
140 	// BTimeSource methods
141 	virtual void				SetRunMode(run_mode mode);
142 	virtual status_t			TimeSourceOp(const time_source_op_info& op,
143 									void *_reserved);
144 
145 	// BControllable methods
146 	virtual status_t			GetParameterValue(int32 id,
147 									bigtime_t* lastChange, void* value,
148 									size_t* size);
149 	virtual void				SetParameterValue(int32 id, bigtime_t when,
150 									const void* value, size_t size);
151 	virtual BParameterWeb*		MakeParameterWeb();
152 
153 private:
154 	// private unimplemented
155 								MultiAudioNode(const MultiAudioNode& clone);
156 	MultiAudioNode& 			operator=(const MultiAudioNode& clone);
157 
158 			status_t			_HandleStart(const media_timed_event* event,
159 									bigtime_t lateness,
160 									bool realTimeEvent = false);
161 			status_t			_HandleSeek(const media_timed_event* event,
162 									bigtime_t lateness,
163 									bool realTimeEvent = false);
164 			status_t			_HandleWarp(const media_timed_event* event,
165 									bigtime_t lateness,
166 									bool realTimeEvent = false);
167 			status_t			_HandleStop(const media_timed_event* event,
168 									bigtime_t lateness,
169 									bool realTimeEvent = false);
170 			status_t			_HandleBuffer(const media_timed_event* event,
171 									bigtime_t lateness,
172 									bool realTimeEvent = false);
173 			status_t			_HandleDataStatus(
174 									const media_timed_event* event,
175 									bigtime_t lateness,
176 									bool realTimeEvent = false);
177 			status_t			_HandleParameter(const media_timed_event* event,
178 									bigtime_t lateness,
179 									bool realTimeEvent = false);
180 
181 			char*				_PlaybackBuffer(int32 cycle, int32 channel)
182 									{ return fDevice->BufferList()
183 										.playback_buffers
184 											[cycle][channel].base; }
185 			uint32				_PlaybackStride(int32 cycle, int32 channel)
186 									{ return fDevice->BufferList()
187 										.playback_buffers
188 											[cycle][channel].stride; }
189 
190 			char*				_RecordBuffer(int32 cycle, int32 channel)
191 									{ return fDevice->BufferList()
192 										.record_buffers
193 											[cycle][channel].base; }
194 			uint32				_RecordStride(int32 cycle, int32 channel)
195 									{ return fDevice->BufferList()
196 										.record_buffers
197 											[cycle][channel].stride; }
198 
199 			void				_WriteZeros(node_input& input,
200 									uint32 bufferCycle);
201 			void				_FillWithZeros(node_input& input);
202 			void				_FillNextBuffer(node_input& channel,
203 									BBuffer* buffer);
204 
205 	static	int32				_OutputThreadEntry(void* data);
206 			int32				_OutputThread();
207 			status_t			_StartOutputThreadIfNeeded();
208 			status_t			_StopOutputThread();
209 
210 			void	 			_AllocateBuffers(node_output& channel);
211 			BBuffer*	 		_FillNextBuffer(multi_buffer_info& info,
212 									node_output& output);
213 			void				_UpdateTimeSource(multi_buffer_info& info,
214 									multi_buffer_info& oldInfo,
215 									node_input& input);
216 
217 			node_output*	 	_FindOutput(media_source source);
218 			node_input* 		_FindInput(media_destination destination);
219 			node_input* 		_FindInput(int32 destinationId);
220 
221 			const char*			_GetControlName(multi_mix_control& control);
222 			void 				_ProcessGroup(BParameterGroup* group,
223 									int32 index, int32& numParameters);
224 			void 				_ProcessMux(BDiscreteParameter* parameter,
225 									int32 index);
226 			void				_CreateFrequencyParameterGroup(
227 									BParameterGroup* parentGroup,
228 									const char* name, int32 parameterID,
229 									uint32 rateMask);
230 
231 			status_t			_SetNodeInputFrameRate(float frameRate);
232 			status_t			_SetNodeOutputFrameRate(float frameRate);
233 			void				_UpdateInternalLatency(
234 									const media_format& format);
235 
236 private:
237 			status_t			fInitStatus;
238 
239 			BMediaAddOn*		fAddOn;
240 			int32				fId;
241 
242 			BLocker				fBufferLock;
243 
244 			BList				fInputs;
245 			TimeComputer		fTimeComputer;
246 
247 			bigtime_t 			fLatency;
248 			BList				fOutputs;
249 			media_format 		fOutputPreferredFormat;
250 			media_format 		fInputPreferredFormat;
251 
252 			bigtime_t			fInternalLatency;
253 				// this is computed from the real (negotiated) chunk size and bit rate,
254 				// not the defaults that are in the parameters
255 			bigtime_t			fBufferPeriod;
256 
257 			int32				fQuitThread;
258 			thread_id			fThread;
259 			MultiAudioDevice*	fDevice;
260 			bool 				fTimeSourceStarted;
261 			BParameterWeb*		fWeb;
262 			BMessage			fConfig;
263 };
264 
265 
266 #endif	// MULTI_AUDIO_NODE_H
267