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