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 friend class NodeInput; 35 friend class NodeOutput; 36 37 protected: 38 virtual ~OpenSoundNode(); 39 40 public: 41 explicit OpenSoundNode(BMediaAddOn* addon, 42 const char* name, 43 OpenSoundDevice* device, 44 int32 internalID, BMessage* config); 45 46 virtual status_t InitCheck() const; 47 48 // BMediaNode interface 49 public: 50 virtual BMediaAddOn* AddOn(int32* internalID) const; 51 // Who instantiated you -- or NULL for app class 52 53 protected: 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. 61 62 public: 63 virtual status_t HandleMessage(int32 message, 64 const void* data, size_t size); 65 66 protected: 67 virtual void NodeRegistered(); 68 virtual status_t RequestCompleted( 69 const media_request_info& info); 70 virtual void SetTimeSource(BTimeSource* timeSource); 71 72 // BBufferConsumer interface 73 protected: 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, 83 int32 status, 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 94 95 virtual void Disconnected(const media_source& producer, 96 const media_destination& where); 97 98 virtual status_t FormatChanged(const media_source& producer, 99 const media_destination& consumer, 100 int32 change_tag, 101 const media_format& format); 102 103 virtual status_t SeekTagRequested( 104 const media_destination& destination, 105 bigtime_t in_target_time, 106 uint32 in_flags, 107 media_seek_tag* out_seek_tag, 108 bigtime_t* out_tagged_time, 109 uint32* out_flags); 110 111 // BBufferProducer interface 112 protected: 113 virtual status_t FormatSuggestionRequested(media_type type, 114 int32 quality, media_format* format); 115 116 virtual status_t FormatProposal(const media_source& output, 117 media_format* format); 118 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); 127 128 virtual status_t SetBufferGroup( 129 const media_source& for_source, 130 BBufferGroup* group); 131 132 virtual status_t PrepareToConnect(const media_source& what, 133 const media_destination& where, 134 media_format* format, 135 media_source* out_source, 136 char* out_name); 137 138 virtual void Connect(status_t error, 139 const media_source& source, 140 const media_destination& destination, 141 const media_format& format, 142 char* io_name); 143 144 virtual void Disconnect(const media_source& what, 145 const media_destination& where); 146 147 virtual void LateNoticeReceived( 148 const media_source& what, 149 bigtime_t how_much, 150 bigtime_t performance_time); 151 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, 157 bigtime_t prev_time, 158 const media_seek_tag* prev_tag); 159 160 // BMediaEventLooper interface 161 protected: 162 /* you must override to handle your events! */ 163 /* you should not call HandleEvent directly */ 164 virtual void HandleEvent(const media_timed_event* event, 165 bigtime_t lateness, 166 bool realTimeEvent = false); 167 168 // BTimeSource interface 169 protected: 170 virtual void SetRunMode(run_mode mode); 171 virtual status_t TimeSourceOp(const time_source_op_info& op, 172 void* _reserved); 173 174 // BControllable interface 175 protected: 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, 181 size_t size); 182 virtual BParameterWeb* MakeParameterWeb(); 183 184 private: 185 void _ProcessGroup(BParameterGroup* group, 186 int32 index, int32& _parameters); 187 void _ProcessMux(BDiscreteParameter* parameter, 188 int32 index); 189 status_t _PropagateParameterChanges(int from, 190 int type, const char* id); 191 192 protected: 193 virtual status_t HandleStart(const media_timed_event* event, 194 bigtime_t lateness, 195 bool realTimeEvent = false); 196 virtual status_t HandleSeek(const media_timed_event* event, 197 bigtime_t lateness, 198 bool realTimeEvent = false); 199 virtual status_t HandleWarp(const media_timed_event* event, 200 bigtime_t lateness, 201 bool realTimeEvent = false); 202 virtual status_t HandleStop(const media_timed_event* event, 203 bigtime_t lateness, 204 bool realTimeEvent = false); 205 virtual status_t HandleBuffer( 206 const media_timed_event* event, 207 bigtime_t lateness, 208 bool realTimeEvent = false); 209 virtual status_t HandleDataStatus( 210 const media_timed_event* event, 211 bigtime_t lateness, 212 bool realTimeEvent = false); 213 virtual status_t HandleParameter( 214 const media_timed_event* event, 215 bigtime_t lateness, 216 bool realTimeEvent = false); 217 218 public: 219 static void GetFlavor(flavor_info* outInfo, int32 id); 220 static void GetFormat(media_format* outFormat); 221 222 status_t GetConfigurationFor(BMessage* intoMessage); 223 224 225 private: 226 OpenSoundNode(const OpenSoundNode& clone); 227 // private unimplemented 228 OpenSoundNode& operator=(const OpenSoundNode& clone); 229 230 private: 231 static void _SignalHandler(int sig); 232 233 static int32 _PlayThreadEntry(void* data); 234 static int32 _RecThreadEntry(void* data); 235 int32 _PlayThread(NodeInput* input); 236 int32 _RecThread(NodeOutput* output); 237 238 status_t _StartPlayThread(NodeInput* input); 239 status_t _StopPlayThread(NodeInput* input); 240 status_t _StartRecThread(NodeOutput* output); 241 status_t _StopRecThread(NodeOutput* output); 242 243 BBuffer* _FillNextBuffer(audio_buf_info* abinfo, 244 NodeOutput& channel); 245 void _UpdateTimeSource(bigtime_t performanceTime, 246 bigtime_t realTime, float drift); 247 248 249 NodeOutput* _FindOutput( 250 const media_source& source) const; 251 NodeInput* _FindInput( 252 const media_destination& dest) const; 253 NodeInput* _FindInput(int32 destinationId); 254 255 private: 256 status_t fInitCheckStatus; 257 258 BMediaAddOn* fAddOn; 259 int32 fId; 260 261 BList fInputs; 262 BList fOutputs; 263 264 #if 1 265 // TODO: remove and use use a preferred format 266 // per NodeInput/NodeOutput channel 267 media_format fPreferredFormat; 268 #endif 269 bigtime_t fLatency; 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 273 // parameters 274 OpenSoundDevice* fDevice; 275 276 bool fTimeSourceStarted; 277 bigtime_t fTimeSourceStartTime; 278 279 BParameterWeb* fWeb; 280 BMessage fConfig; 281 }; 282 283 #endif // _OPENSOUNDNODE_H 284