/* SuperCollider real time audio synthesis system Copyright (c) 2002 James McCartney. All rights reserved. http://www.audiosynth.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Having SequencedCommands allows performing actions that might otherwise require * taking a mutex, which is undesirable in a real time thread. * Some commands require several stages of processing at both the real time * and non real time levels. This class does the messaging between levels for you * so that you only need to write the functions. */ #ifndef _SC_SequencedCommand_ #define _SC_SequencedCommand_ #include "OSC_Packet.h" #include "SC_World.h" #include "SC_BufGen.h" #include "sc_msg_iter.h" #include #include #define CallSequencedCommand(T, inWorld, inSize, inData, inReply) \ void* space = World_Alloc(inWorld, sizeof(T)); \ T *cmd = new (space) T(inWorld, inReply); \ if (!cmd) return kSCErr_Failed; \ int err = cmd->Init(inData, inSize); \ if (err) { \ cmd->~T(); \ World_Free(inWorld, space); \ return err; \ } \ if (inWorld->mRealTime) cmd->CallNextStage(); \ else cmd->CallEveryStage(); class SC_SequencedCommand { public: SC_SequencedCommand(World *inWorld, ReplyAddress *inReplyAddress); virtual ~SC_SequencedCommand(); void Delete(); void CallEveryStage(); void CallNextStage(); virtual int Init(char *inData, int inSize); virtual bool Stage1(); // real time virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time void SendDone(char *inCommandName); protected: int mNextStage; ReplyAddress mReplyAddress; World *mWorld; int mMsgSize; char *mMsgData; virtual void CallDestructor()=0; }; /////////////////////////////////////////////////////////////////////////// class SyncCmd : public SC_SequencedCommand { public: SyncCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: virtual void CallDestructor(); int mID; }; /////////////////////////////////////////////////////////////////////////// class BufGenCmd : public SC_SequencedCommand { public: BufGenCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual ~BufGenCmd(); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: int mBufIndex; BufGen *mBufGen; sc_msg_iter mMsg; char *mData; int mSize; SndBuf mSndBuf; float *mFreeData; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class BufAllocCmd : public SC_SequencedCommand { public: BufAllocCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: int mBufIndex; SndBuf mSndBuf; int mNumChannels, mNumFrames; float *mFreeData; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class BufFreeCmd : public SC_SequencedCommand { public: BufFreeCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: int mBufIndex; float *mFreeData; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class BufCloseCmd : public SC_SequencedCommand { public: BufCloseCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: int mBufIndex; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class BufZeroCmd : public SC_SequencedCommand { public: BufZeroCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: int mBufIndex; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class BufAllocReadCmd : public SC_SequencedCommand { public: BufAllocReadCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual ~BufAllocReadCmd(); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: int mBufIndex; float *mFreeData; SndBuf mSndBuf; char *mFilename; int mFileOffset, mNumFrames; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class BufReadCmd : public SC_SequencedCommand { public: BufReadCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual ~BufReadCmd(); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: int mBufIndex; char *mFilename; int mFileOffset, mNumFrames, mBufOffset; bool mLeaveFileOpen; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class BufWriteCmd : public SC_SequencedCommand { public: BufWriteCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual ~BufWriteCmd(); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: int mBufIndex; char *mFilename; SF_INFO mFileInfo; int mNumFrames, mBufOffset; bool mLeaveFileOpen; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class AudioQuitCmd : public SC_SequencedCommand { public: AudioQuitCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class AudioStatusCmd : public SC_SequencedCommand { public: AudioStatusCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual bool Stage2(); // non real time protected: virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class NotifyCmd : public SC_SequencedCommand { public: NotifyCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time protected: virtual void CallDestructor(); int mOnOff; int mID; }; /////////////////////////////////////////////////////////////////////////// #define CallSendFailureCommand(inWorld, inCmdName, inErrString, inReply) \ void* space = World_Alloc(inWorld, sizeof(SendFailureCmd)); \ SendFailureCmd *cmd = new (space) SendFailureCmd(inWorld, inReply); \ if (!cmd) return kSCErr_Failed; \ cmd->InitSendFailureCmd(inCmdName, inErrString); \ if (inWorld->mRealTime) cmd->CallNextStage(); \ else cmd->CallEveryStage(); \ class SendFailureCmd : public SC_SequencedCommand { public: SendFailureCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual ~SendFailureCmd(); virtual void InitSendFailureCmd(const char *inCmdName, const char* inErrString); virtual bool Stage2(); // non real time protected: char *mCmdName, *mErrString; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// #include "SC_GraphDef.h" class LoadSynthDefCmd : public SC_SequencedCommand { public: LoadSynthDefCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual ~LoadSynthDefCmd(); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: char *mFilename; GraphDef *mDefs; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// #include "SC_GraphDef.h" class RecvSynthDefCmd : public SC_SequencedCommand { public: RecvSynthDefCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual ~RecvSynthDefCmd(); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: char *mBuffer; GraphDef *mDefs; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class LoadSynthDefDirCmd : public SC_SequencedCommand { public: LoadSynthDefDirCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual ~LoadSynthDefDirCmd(); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: char *mFilename; GraphDef *mDefs; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// class SendReplyCmd : public SC_SequencedCommand { public: SendReplyCmd(World *inWorld, ReplyAddress *inReplyAddress); virtual int Init(char *inData, int inSize); virtual bool Stage2(); // non real time protected: virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData); typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData); class AsyncPlugInCmd : public SC_SequencedCommand { public: AsyncPlugInCmd(World *inWorld, ReplyAddress *inReplyAddress, const char* cmdName, void *cmdData, AsyncStageFn stage2, // stage2 is non real time AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true AsyncFreeFn cleanup, int completionMsgSize, void* completionMsgData); virtual ~AsyncPlugInCmd(); virtual bool Stage2(); // non real time virtual bool Stage3(); // real time virtual void Stage4(); // non real time protected: const char *mCmdName; void *mCmdData; AsyncStageFn mStage2, mStage3, mStage4; AsyncFreeFn mCleanup; virtual void CallDestructor(); }; /////////////////////////////////////////////////////////////////////////// #endif