xref: /haiku/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h (revision 71452e98334eaac603bf542d159e24788a46bebb)
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, const char* name,
39 								MultiAudioDevice* device, int32 internalID,
40 								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(const media_request_info& info);
58 	virtual	void			SetTimeSource(BTimeSource* timeSource);
59 
60 	// BBufferConsumer methods
61 
62 	virtual	status_t		AcceptFormat(const media_destination& dest,
63 								media_format* format);
64 	virtual	status_t		GetNextInput(int32* cookie, media_input* input);
65 	virtual	void			DisposeInputCookie(int32 cookie);
66 	virtual	void			BufferReceived(BBuffer* buffer);
67 	virtual	void			ProducerDataStatus(const media_destination& forWhom,
68 								int32 status, bigtime_t atPerformanceTime);
69 	virtual	status_t		GetLatencyFor(const media_destination& forWhom,
70 								bigtime_t* latency, media_node_id* timeSource);
71 	virtual	status_t 		Connected(const media_source& producer,
72 								const media_destination& where,
73 								const media_format& withFormat,
74 								media_input* input);
75 	virtual	void			Disconnected(const media_source& producer,
76 								const media_destination& where);
77 	virtual	status_t		FormatChanged(const media_source& producer,
78 								const media_destination& consumer,
79 								int32 changeTag, const media_format& format);
80 
81 	virtual	status_t		SeekTagRequested(
82 								const media_destination& destination,
83 								bigtime_t targetTime, uint32 flags,
84 								media_seek_tag* _seekTag, bigtime_t* _taggedTime,
85 								uint32* _flags);
86 
87 	// BBufferProducer methods
88 
89 	virtual status_t		FormatSuggestionRequested(media_type type,
90 								int32 quality, media_format* format);
91 
92 	virtual status_t		FormatProposal(const media_source& output,
93 								media_format* format);
94 
95 	virtual status_t		FormatChangeRequested(const media_source& source,
96 								const media_destination& destination,
97 								media_format* io_format, int32* _deprecated);
98 	virtual status_t		GetNextOutput(int32* cookie,
99 								media_output* out_output);
100 	virtual status_t		DisposeOutputCookie(int32 cookie);
101 
102 	virtual	status_t		SetBufferGroup(const media_source& for_source,
103 								BBufferGroup* group);
104 
105 	virtual status_t		PrepareToConnect(const media_source& what,
106 								const media_destination& where,
107 								media_format* format, media_source* source,
108 								char* name);
109 
110 	virtual void			Connect(status_t error, const media_source& source,
111 								const media_destination& destination,
112 								const media_format& format, char* name);
113 	virtual void			Disconnect(const media_source& what,
114 								const media_destination& where);
115 
116 	virtual void			LateNoticeReceived(const media_source& what,
117 								bigtime_t howMuch, bigtime_t performanceTime);
118 
119 	virtual void			EnableOutput(const media_source& what, bool enabled,
120 								int32* _deprecated);
121 	virtual void			AdditionalBufferRequested(const media_source& source,
122 								media_buffer_id previousBuffer,
123 								bigtime_t previousTime,
124 								const media_seek_tag* previousTag);
125 
126 	// BMediaEventLooper methods
127 	virtual void			HandleEvent(const media_timed_event* event,
128 								bigtime_t lateness, bool realTimeEvent = false);
129 
130 	// BTimeSource methods
131 	virtual void			SetRunMode(run_mode mode);
132 	virtual status_t		TimeSourceOp(const time_source_op_info& op,
133 								void *_reserved);
134 
135 	// BControllable methods
136 	virtual status_t		GetParameterValue(int32 id, bigtime_t* lastChange,
137 								void* value, size_t* size);
138 	virtual void			SetParameterValue(int32 id, bigtime_t when,
139 								const void* value, size_t size);
140 	virtual BParameterWeb*	MakeParameterWeb();
141 
142 private:
143 	// private unimplemented
144 							MultiAudioNode(const MultiAudioNode& clone);
145 	MultiAudioNode& 		operator=(const MultiAudioNode& clone);
146 
147 			status_t		_HandleStart(const media_timed_event* event,
148 								bigtime_t lateness, bool realTimeEvent = false);
149 			status_t		_HandleSeek(const media_timed_event* event,
150 								bigtime_t lateness, bool realTimeEvent = false);
151 			status_t		_HandleWarp(const media_timed_event* event,
152 								bigtime_t lateness, bool realTimeEvent = false);
153 			status_t		_HandleStop(const media_timed_event* event,
154 								bigtime_t lateness, bool realTimeEvent = false);
155 			status_t		_HandleBuffer(const media_timed_event* event,
156 								bigtime_t lateness, bool realTimeEvent = false);
157 			status_t		_HandleDataStatus(const media_timed_event* event,
158 								bigtime_t lateness, bool realTimeEvent = false);
159 			status_t		_HandleParameter(const media_timed_event* event,
160 								bigtime_t lateness, bool realTimeEvent = false);
161 
162 			char*			_PlaybackBuffer(int32 cycle, int32 channel)
163 								{ return fDevice->BufferList().playback_buffers
164 									[cycle][channel].base; }
165 			uint32			_PlaybackStride(int32 cycle, int32 channel)
166 								{ return fDevice->BufferList().playback_buffers
167 									[cycle][channel].stride; }
168 
169 			char*			_RecordBuffer(int32 cycle, int32 channel)
170 								{ return fDevice->BufferList().record_buffers
171 									[cycle][channel].base; }
172 			uint32			_RecordStride(int32 cycle, int32 channel)
173 								{ return fDevice->BufferList().record_buffers
174 									[cycle][channel].stride; }
175 
176 			void			_WriteZeros(node_input& input, uint32 bufferCycle);
177 			void			_FillWithZeros(node_input& input);
178 			void			_FillNextBuffer(node_input& channel,
179 								BBuffer* buffer);
180 
181 	static	int32			_OutputThreadEntry(void* data);
182 			int32			_OutputThread();
183 			status_t		_StartOutputThreadIfNeeded();
184 			status_t		_StopOutputThread();
185 
186 			void 			_AllocateBuffers(node_output& channel);
187 			BBuffer* 		_FillNextBuffer(multi_buffer_info& info,
188 								node_output& output);
189 			void			_UpdateTimeSource(multi_buffer_info& info,
190 								multi_buffer_info& oldInfo, node_input& input);
191 
192 			node_output* 	_FindOutput(media_source source);
193 			node_input* 	_FindInput(media_destination destination);
194 			node_input* 	_FindInput(int32 destinationId);
195 
196 			const char*		_GetControlName(multi_mix_control& control);
197 			void 			_ProcessGroup(BParameterGroup* group, int32 index,
198 								int32& numParameters);
199 			void 			_ProcessMux(BDiscreteParameter* parameter,
200 								int32 index);
201 			void			_CreateFrequencyParameterGroup(
202 								BParameterGroup* parentGroup, const char* name,
203 								int32 parameterID, uint32 rateMask);
204 
205 			status_t		_SetNodeInputFrameRate(float frameRate);
206 			status_t		_SetNodeOutputFrameRate(float frameRate);
207 			void			_UpdateInternalLatency(const media_format& format);
208 
209 private:
210 	status_t			fInitStatus;
211 
212 	BMediaAddOn*		fAddOn;
213 	int32				fId;
214 
215 	BLocker				fBufferLock;
216 
217 	BList				fInputs;
218 	TimeComputer		fTimeComputer;
219 
220 	bigtime_t 			fLatency;
221 	BList				fOutputs;
222 	media_format 		fOutputPreferredFormat;
223 	media_format 		fInputPreferredFormat;
224 
225 	bigtime_t			fInternalLatency;
226 		// this is computed from the real (negotiated) chunk size and bit rate,
227 		// not the defaults that are in the parameters
228 	bigtime_t			fBufferPeriod;
229 
230 	sem_id				fBufferFreeSem;
231 	thread_id			fThread;
232 	MultiAudioDevice*	fDevice;
233 	bool 				fTimeSourceStarted;
234 	BParameterWeb*		fWeb;
235 	BMessage			fConfig;
236 };
237 
238 #endif	// MULTI_AUDIO_NODE_H
239