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