/* * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) * Distributed under the terms of the MIT License. */ #ifndef MULTI_AUDIO_NODE_H #define MULTI_AUDIO_NODE_H #include #include #include #include #include #include #include #include #include #include #include "hmulti_audio.h" #include "MultiAudioDevice.h" #include "TimeComputer.h" class BDiscreteParameter; class BParameterGroup; class node_input; class node_output; class MultiAudioNode : public BBufferConsumer, public BBufferProducer, public BTimeSource, public BMediaEventLooper, public BControllable { protected: virtual ~MultiAudioNode(); public: MultiAudioNode(BMediaAddOn* addon, const char* name, MultiAudioDevice* device, int32 internalID, BMessage* config); virtual status_t InitCheck() const; static void GetFlavor(flavor_info* info, int32 id); static void GetFormat(media_format* outFormat); status_t GetConfigurationFor(BMessage* message); // BMediaNode methods virtual BMediaAddOn* AddOn(int32* internalID) const; virtual status_t HandleMessage(int32 message, const void* data, size_t size); protected: virtual void Preroll(); virtual void NodeRegistered(); virtual status_t RequestCompleted( const media_request_info& info); virtual void SetTimeSource(BTimeSource* timeSource); // BBufferConsumer methods virtual status_t AcceptFormat(const media_destination& dest, media_format* format); virtual status_t GetNextInput(int32* cookie, media_input* input); virtual void DisposeInputCookie(int32 cookie); virtual void BufferReceived(BBuffer* buffer); virtual void ProducerDataStatus( const media_destination& forWhom, int32 status, bigtime_t atPerformanceTime); virtual status_t GetLatencyFor(const media_destination& forWhom, bigtime_t* latency, media_node_id* timeSource); virtual status_t Connected(const media_source& producer, const media_destination& where, const media_format& withFormat, media_input* input); virtual void Disconnected(const media_source& producer, const media_destination& where); virtual status_t FormatChanged(const media_source& producer, const media_destination& consumer, int32 changeTag, const media_format& format); virtual status_t SeekTagRequested( const media_destination& destination, bigtime_t targetTime, uint32 flags, media_seek_tag* _seekTag, bigtime_t* _taggedTime, uint32* _flags); // BBufferProducer methods virtual status_t FormatSuggestionRequested(media_type type, int32 quality, media_format* format); virtual status_t FormatProposal(const media_source& output, media_format* format); virtual status_t FormatChangeRequested( const media_source& source, const media_destination& destination, media_format* ioFormat, int32* _deprecated); virtual status_t GetNextOutput(int32* cookie, media_output* _output); virtual status_t DisposeOutputCookie(int32 cookie); virtual status_t SetBufferGroup(const media_source& forSource, BBufferGroup* group); virtual status_t PrepareToConnect(const media_source& what, const media_destination& where, media_format* format, media_source* source, char* name); virtual void Connect(status_t error, const media_source& source, const media_destination& destination, const media_format& format, char* name); virtual void Disconnect(const media_source& what, const media_destination& where); virtual void LateNoticeReceived(const media_source& what, bigtime_t howMuch, bigtime_t performanceTime); virtual void EnableOutput(const media_source& what, bool enabled, int32* _deprecated); virtual void AdditionalBufferRequested( const media_source& source, media_buffer_id previousBuffer, bigtime_t previousTime, const media_seek_tag* previousTag); // BMediaEventLooper methods virtual void HandleEvent(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent = false); // BTimeSource methods virtual void SetRunMode(run_mode mode); virtual status_t TimeSourceOp(const time_source_op_info& op, void *_reserved); // BControllable methods virtual status_t GetParameterValue(int32 id, bigtime_t* lastChange, void* value, size_t* size); virtual void SetParameterValue(int32 id, bigtime_t when, const void* value, size_t size); virtual BParameterWeb* MakeParameterWeb(); private: // private unimplemented MultiAudioNode(const MultiAudioNode& clone); MultiAudioNode& operator=(const MultiAudioNode& clone); status_t _HandleStart(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent = false); status_t _HandleSeek(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent = false); status_t _HandleWarp(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent = false); status_t _HandleStop(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent = false); status_t _HandleBuffer(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent = false); status_t _HandleDataStatus( const media_timed_event* event, bigtime_t lateness, bool realTimeEvent = false); status_t _HandleParameter(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent = false); char* _PlaybackBuffer(int32 cycle, int32 channel) { return fDevice->BufferList() .playback_buffers [cycle][channel].base; } uint32 _PlaybackStride(int32 cycle, int32 channel) { return fDevice->BufferList() .playback_buffers [cycle][channel].stride; } char* _RecordBuffer(int32 cycle, int32 channel) { return fDevice->BufferList() .record_buffers [cycle][channel].base; } uint32 _RecordStride(int32 cycle, int32 channel) { return fDevice->BufferList() .record_buffers [cycle][channel].stride; } void _WriteZeros(node_input& input, uint32 bufferCycle); void _FillWithZeros(node_input& input); void _FillNextBuffer(node_input& channel, BBuffer* buffer); static int32 _OutputThreadEntry(void* data); int32 _OutputThread(); status_t _StartOutputThreadIfNeeded(); status_t _StopOutputThread(); void _AllocateBuffers(node_output& channel); BBuffer* _FillNextBuffer(multi_buffer_info& info, node_output& output); void _UpdateTimeSource(multi_buffer_info& info, node_input& input); node_output* _FindOutput(media_source source); node_input* _FindInput(media_destination destination); node_input* _FindInput(int32 destinationId); const char* _GetControlName(multi_mix_control& control); void _ProcessGroup(BParameterGroup* group, int32 index, int32& numParameters); void _ProcessMux(BDiscreteParameter* parameter, int32 index); void _CreateFrequencyParameterGroup( BParameterGroup* parentGroup, const char* name, int32 parameterID, uint32 rateMask); status_t _SetNodeInputFrameRate(float frameRate); status_t _SetNodeOutputFrameRate(float frameRate); void _UpdateInternalLatency( const media_format& format); private: status_t fInitStatus; BMediaAddOn* fAddOn; int32 fId; BLocker fBufferLock; BList fInputs; TimeComputer fTimeComputer; bigtime_t fLatency; BList fOutputs; media_format fOutputPreferredFormat; media_format fInputPreferredFormat; bigtime_t fInternalLatency; // this is computed from the real (negotiated) chunk size and bit rate, // not the defaults that are in the parameters bigtime_t fBufferPeriod; int32 fQuitThread; thread_id fThread; MultiAudioDevice* fDevice; bool fTimeSourceStarted; BParameterWeb* fWeb; BMessage fConfig; }; #endif // MULTI_AUDIO_NODE_H