2 * OpenSound media addon for BeOS and Haiku
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.
9 #ifndef _OPENSOUNDNODE_H
10 #define _OPENSOUNDNODE_H
12 #include <BufferConsumer.h>
13 #include <BufferProducer.h>
14 #include <Controllable.h>
15 #include <MediaEventLooper.h>
16 #include <MediaNode.h>
18 #include <ParameterWeb.h>
19 #include <TimeSource.h>
21 class OpenSoundDevice
;
22 class OpenSoundDeviceEngine
;
23 class OpenSoundDeviceMixer
;
25 struct audio_buf_info
;
28 class OpenSoundNode
: public BBufferConsumer
, public BBufferProducer
,
29 public BTimeSource
, public BMediaEventLooper
, public BControllable
{
34 friend class NodeInput
;
35 friend class NodeOutput
;
38 virtual ~OpenSoundNode();
41 explicit OpenSoundNode(BMediaAddOn
* addon
,
43 OpenSoundDevice
* device
,
44 int32 internalID
, BMessage
* config
);
46 virtual status_t
InitCheck() const;
48 // BMediaNode interface
50 virtual BMediaAddOn
* AddOn(int32
* internalID
) const;
51 // Who instantiated you -- or NULL for app class
54 virtual void Preroll();
55 // These don't return errors; instead, they use the global error
56 // condition reporter. A node is required to have a queue of at
57 // least one pending command (plus TimeWarp) and is recommended to
58 // allow for at least one pending command of each type. Allowing an
59 // arbitrary number of outstanding commands might be nice, but apps
60 // cannot depend on that happening.
63 virtual status_t
HandleMessage(int32 message
,
64 const void* data
, size_t size
);
67 virtual void NodeRegistered();
68 virtual status_t
RequestCompleted(
69 const media_request_info
& info
);
70 virtual void SetTimeSource(BTimeSource
* timeSource
);
72 // BBufferConsumer interface
74 virtual status_t
AcceptFormat(
75 const media_destination
& dest
,
76 media_format
* format
);
77 virtual status_t
GetNextInput(int32
* cookie
,
78 media_input
* out_input
);
79 virtual void DisposeInputCookie(int32 cookie
);
80 virtual void BufferReceived(BBuffer
* buffer
);
81 virtual void ProducerDataStatus(
82 const media_destination
& for_whom
,
84 bigtime_t at_performance_time
);
85 virtual status_t
GetLatencyFor(
86 const media_destination
& for_whom
,
87 bigtime_t
* out_latency
,
88 media_node_id
* out_timesource
);
89 virtual status_t
Connected(const media_source
& producer
,
90 const media_destination
& where
,
91 const media_format
& with_format
,
92 media_input
* out_input
);
93 // here's a good place to request buffer group usage
95 virtual void Disconnected(const media_source
& producer
,
96 const media_destination
& where
);
98 virtual status_t
FormatChanged(const media_source
& producer
,
99 const media_destination
& consumer
,
101 const media_format
& format
);
103 virtual status_t
SeekTagRequested(
104 const media_destination
& destination
,
105 bigtime_t in_target_time
,
107 media_seek_tag
* out_seek_tag
,
108 bigtime_t
* out_tagged_time
,
111 // BBufferProducer interface
113 virtual status_t
FormatSuggestionRequested(media_type type
,
114 int32 quality
, media_format
* format
);
116 virtual status_t
FormatProposal(const media_source
& output
,
117 media_format
* format
);
119 virtual status_t
FormatChangeRequested(
120 const media_source
& source
,
121 const media_destination
& destination
,
122 media_format
* io_format
,
123 int32
* _deprecated_
);
124 virtual status_t
GetNextOutput(int32
* cookie
,
125 media_output
* out_output
);
126 virtual status_t
DisposeOutputCookie(int32 cookie
);
128 virtual status_t
SetBufferGroup(
129 const media_source
& for_source
,
130 BBufferGroup
* group
);
132 virtual status_t
PrepareToConnect(const media_source
& what
,
133 const media_destination
& where
,
134 media_format
* format
,
135 media_source
* out_source
,
138 virtual void Connect(status_t error
,
139 const media_source
& source
,
140 const media_destination
& destination
,
141 const media_format
& format
,
144 virtual void Disconnect(const media_source
& what
,
145 const media_destination
& where
);
147 virtual void LateNoticeReceived(
148 const media_source
& what
,
150 bigtime_t performance_time
);
152 virtual void EnableOutput(const media_source
& what
,
153 bool enabled
, int32
* _deprecated_
);
154 virtual void AdditionalBufferRequested(
155 const media_source
& source
,
156 media_buffer_id prev_buffer
,
158 const media_seek_tag
* prev_tag
);
160 // BMediaEventLooper interface
162 /* you must override to handle your events! */
163 /* you should not call HandleEvent directly */
164 virtual void HandleEvent(const media_timed_event
* event
,
166 bool realTimeEvent
= false);
168 // BTimeSource interface
170 virtual void SetRunMode(run_mode mode
);
171 virtual status_t
TimeSourceOp(const time_source_op_info
& op
,
174 // BControllable interface
176 virtual status_t
GetParameterValue(int32 id
,
177 bigtime_t
* last_change
,
178 void* value
, size_t* ioSize
);
179 virtual void SetParameterValue(int32 id
,
180 bigtime_t when
, const void* value
,
182 virtual BParameterWeb
* MakeParameterWeb();
185 void _ProcessGroup(BParameterGroup
* group
,
186 int32 index
, int32
& _parameters
);
187 void _ProcessMux(BDiscreteParameter
* parameter
,
189 status_t
_PropagateParameterChanges(int from
,
190 int type
, const char* id
);
193 virtual status_t
HandleStart(const media_timed_event
* event
,
195 bool realTimeEvent
= false);
196 virtual status_t
HandleSeek(const media_timed_event
* event
,
198 bool realTimeEvent
= false);
199 virtual status_t
HandleWarp(const media_timed_event
* event
,
201 bool realTimeEvent
= false);
202 virtual status_t
HandleStop(const media_timed_event
* event
,
204 bool realTimeEvent
= false);
205 virtual status_t
HandleBuffer(
206 const media_timed_event
* event
,
208 bool realTimeEvent
= false);
209 virtual status_t
HandleDataStatus(
210 const media_timed_event
* event
,
212 bool realTimeEvent
= false);
213 virtual status_t
HandleParameter(
214 const media_timed_event
* event
,
216 bool realTimeEvent
= false);
219 static void GetFlavor(flavor_info
* outInfo
, int32 id
);
220 static void GetFormat(media_format
* outFormat
);
222 status_t
GetConfigurationFor(BMessage
* intoMessage
);
226 OpenSoundNode(const OpenSoundNode
& clone
);
227 // private unimplemented
228 OpenSoundNode
& operator=(const OpenSoundNode
& clone
);
231 static void _SignalHandler(int sig
);
233 static int32
_PlayThreadEntry(void* data
);
234 static int32
_RecThreadEntry(void* data
);
235 int32
_PlayThread(NodeInput
* input
);
236 int32
_RecThread(NodeOutput
* output
);
238 status_t
_StartPlayThread(NodeInput
* input
);
239 status_t
_StopPlayThread(NodeInput
* input
);
240 status_t
_StartRecThread(NodeOutput
* output
);
241 status_t
_StopRecThread(NodeOutput
* output
);
243 BBuffer
* _FillNextBuffer(audio_buf_info
* abinfo
,
244 NodeOutput
& channel
);
245 void _UpdateTimeSource(bigtime_t performanceTime
,
246 bigtime_t realTime
, float drift
);
249 NodeOutput
* _FindOutput(
250 const media_source
& source
) const;
251 NodeInput
* _FindInput(
252 const media_destination
& dest
) const;
253 NodeInput
* _FindInput(int32 destinationId
);
256 status_t fInitCheckStatus
;
265 // TODO: remove and use use a preferred format
266 // per NodeInput/NodeOutput channel
267 media_format fPreferredFormat
;
270 bigtime_t fInternalLatency
;
271 // this is computed from the real (negotiated) chunk size
272 // and bit rate, not the defaults that are in the
274 OpenSoundDevice
* fDevice
;
276 bool fTimeSourceStarted
;
277 bigtime_t fTimeSourceStartTime
;
283 #endif // _OPENSOUNDNODE_H