root/src/add-ons/media/media-add-ons/tone_producer_demo/ToneProducer.h
/*
        ToneProducer.h

        Copyright 1999, Be Incorporated.   All Rights Reserved.
        This file may be used under the terms of the Be Sample Code License.

        NOTES eamoon@meadgroup.com 11june99
        - this node has some holes in it, but it's pretty useful starting
          point for writing producers.
        - I've tried to clean up the format negotiation a bit, which didn't
          fare too well when faced with an apathetic downstream node
          (LoggingConsumer.)

        KNOWN BUGS
          eamoon 17jun99
          * Can't handle 2 channels, but is too polite to refuse.
            How embarrassing.

*/

#ifndef ToneProducer_H
#define ToneProducer_H 1

#include <media/BufferProducer.h>
#include <media/MediaEventLooper.h>
#include <media/Controllable.h>

class BMediaAddOn;

// ----------------
// ToneProducer - a node to generate precisely defined digital tones
class ToneProducer : public BBufferProducer,  public BControllable, public BMediaEventLooper
{
public:
        enum event_t {
                // e.moon 2jun99
                _PARAMETER_EVENT                = BTimedEventQueue::B_USER_EVENT
        };

public:
        // add-on-friendly ctor
        // e.moon [8jun99]
        ToneProducer(BMediaAddOn* pAddOn=0);
        ~ToneProducer();

// BMediaNode methods
        BMediaAddOn* AddOn(     int32* internal_id) const;

// BControllable methods
        status_t GetParameterValue(
                int32 id,
                bigtime_t* last_change,
                void* value,
                size_t* ioSize);

        void SetParameterValue(
                int32 id,
                bigtime_t when,
                const void* value,
                size_t size);

        status_t StartControlPanel(
                BMessenger* pMessenger);

// BBufferProducer methods
        status_t FormatSuggestionRequested(
                media_type type,
                int32 quality,
                media_format* format);

        status_t FormatProposal(
                const media_source& output,
                media_format* format);

        /* If the format isn't good, put a good format into *io_format and return error */
        /* If format has wildcard, specialize to what you can do (and change). */
        /* If you can change the format, return OK. */
        /* The request comes from your destination sychronously, so you cannot ask it */
        /* whether it likes it -- you should assume it will since it asked. */
        status_t FormatChangeRequested(
                const media_source& source,
                const media_destination& destination,
                media_format* io_format,
                int32* _deprecated_);

        status_t GetNextOutput( /* cookie starts as 0 */
                int32* cookie,
                media_output* out_output);

        status_t DisposeOutputCookie(
                int32 cookie);

        /* In this function, you should either pass on the group to your upstream guy, */
        /* or delete your current group and hang on to this group. Deleting the previous */
        /* group (unless you passed it on with the reclaim flag set to false) is very */
        /* important, else you will 1) leak memory and 2) block someone who may want */
        /* to reclaim the buffers living in that group. */
        status_t SetBufferGroup(
                const media_source& for_source,
                BBufferGroup* group);

        /* Iterates over all outputs and maxes the latency found */
        status_t GetLatency(
                bigtime_t* out_latency);

        status_t PrepareToConnect(
                const media_source& what,
                const media_destination& where,
                media_format* format,
                media_source* out_source,
                char* out_name);

        void Connect(
                status_t error,
                const media_source& source,
                const media_destination& destination,
                const media_format& format,
                char* io_name);

        void Disconnect(
                const media_source& what,
                const media_destination& where);

        void LateNoticeReceived(
                const media_source& what,
                bigtime_t how_much,
                bigtime_t performance_time);

        void EnableOutput(
                const media_source & what,
                bool enabled,
                int32* _deprecated_);

        status_t SetPlayRate(
                int32 numer,
                int32 denom);

        status_t HandleMessage(
                int32 message,
                const void* data,
                size_t size);

        void AdditionalBufferRequested(
                const media_source& source,
                media_buffer_id prev_buffer,
                bigtime_t prev_time,
                const media_seek_tag* prev_tag);        //      may be NULL

        void LatencyChanged(
                const media_source& source,
                const media_destination& destination,
                bigtime_t new_latency,
                uint32 flags);

// BMediaEventLooper methods
        void NodeRegistered();

        void Start(bigtime_t performance_time);

        // Workaround for a Metrowerks PPC compiler bug
        void Stop(bigtime_t performance_time, bool immediate);

        void SetRunMode(run_mode mode);

        void HandleEvent(
                const media_timed_event* event,
                bigtime_t lateness,
                bool realTimeEvent = false);

private:
        void AllocateBuffers();
        BBuffer* FillNextBuffer(bigtime_t event_time);

        // 20sep99 e.moon: stereo support
        void FillSineBuffer(float* data, size_t numFrames, bool stereo);
        void FillTriangleBuffer(float* data, size_t numFrames, bool stereo);
        void FillSawtoothBuffer(float* data, size_t numFrames, bool stereo);

        BParameterWeb* mWeb;
        BBufferGroup* mBufferGroup;
        bigtime_t mLatency, mInternalLatency;
        media_output mOutput;
        bool mOutputEnabled;
        media_format mPreferredFormat;

        // These next attributes are related to tone buffer generation
        double mTheta;                  // generic parameter used by all generators
        bool mWaveAscending;            // used by the triangle-wave generator
        float mFrequency;               // can be anything, in Hertz
        float mGain;                            // should be in the range [0,1]
        int32 mWaveform;
        uint64 mFramesSent;
        bigtime_t mStartTime;

        // more parameter handling
        bigtime_t mGainLastChanged;
        bigtime_t mFreqLastChanged;
        bigtime_t mWaveLastChanged;

        // host addon
        // [8jun99] e.moon
        BMediaAddOn*            m_pAddOn;
};

#endif