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 _PlaybackBuffer(int32 cycle,int32 channel)181 char* _PlaybackBuffer(int32 cycle, int32 channel) 182 { return fDevice->BufferList() 183 .playback_buffers 184 [cycle][channel].base; } _PlaybackStride(int32 cycle,int32 channel)185 uint32 _PlaybackStride(int32 cycle, int32 channel) 186 { return fDevice->BufferList() 187 .playback_buffers 188 [cycle][channel].stride; } 189 _RecordBuffer(int32 cycle,int32 channel)190 char* _RecordBuffer(int32 cycle, int32 channel) 191 { return fDevice->BufferList() 192 .record_buffers 193 [cycle][channel].base; } _RecordStride(int32 cycle,int32 channel)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 node_input& input); 215 216 node_output* _FindOutput(media_source source); 217 node_input* _FindInput(media_destination destination); 218 node_input* _FindInput(int32 destinationId); 219 220 const char* _GetControlName(multi_mix_control& control); 221 void _ProcessGroup(BParameterGroup* group, 222 int32 index, int32& numParameters); 223 void _ProcessMux(BDiscreteParameter* parameter, 224 int32 index); 225 void _CreateFrequencyParameterGroup( 226 BParameterGroup* parentGroup, 227 const char* name, int32 parameterID, 228 uint32 rateMask); 229 230 status_t _SetNodeInputFrameRate(float frameRate); 231 status_t _SetNodeOutputFrameRate(float frameRate); 232 void _UpdateInternalLatency( 233 const media_format& format); 234 235 private: 236 status_t fInitStatus; 237 238 BMediaAddOn* fAddOn; 239 int32 fId; 240 241 BLocker fBufferLock; 242 243 BList fInputs; 244 TimeComputer fTimeComputer; 245 246 bigtime_t fLatency; 247 BList fOutputs; 248 media_format fOutputPreferredFormat; 249 media_format fInputPreferredFormat; 250 251 bigtime_t fInternalLatency; 252 // this is computed from the real (negotiated) chunk size and bit rate, 253 // not the defaults that are in the parameters 254 bigtime_t fBufferPeriod; 255 256 int32 fQuitThread; 257 thread_id fThread; 258 MultiAudioDevice* fDevice; 259 bool fTimeSourceStarted; 260 BParameterWeb* fWeb; 261 BMessage fConfig; 262 }; 263 264 265 #endif // MULTI_AUDIO_NODE_H 266