1 /* 2 SuperCollider real time audio synthesis system 3 Copyright (c) 2002 James McCartney. All rights reserved. 4 http://www.audiosynth.com 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #pragma once 22 23 // TODO next time this is updated, change SC_PlugIn.hpp `in`, `zin`, etc. to take uint32s 24 // TODO next time this is updated, change SC_PlugIn.hpp `numInputs`, `numOutputs` to have correct 25 // return type 26 static const int sc_api_version = 3; 27 28 #include "SC_Types.h" 29 #include "SC_SndBuf.h" 30 #include "SC_Unit.h" 31 #include "SC_BufGen.h" 32 #include "SC_FifoMsg.h" 33 #include "SC_fftlib.h" 34 #include "SC_Export.h" 35 36 typedef struct SF_INFO SF_INFO; 37 38 struct World; 39 40 typedef bool (*AsyncStageFn)(World* inWorld, void* cmdData); 41 typedef void (*AsyncFreeFn)(World* inWorld, void* cmdData); 42 43 struct ScopeBufferHnd { 44 void* internalData; 45 float* data; 46 uint32 channels; 47 uint32 maxFrames; 48 channel_dataScopeBufferHnd49 float* channel_data(uint32 channel) { return data + (channel * maxFrames); } 50 51 operator bool() { return internalData != 0; } 52 }; 53 54 struct InterfaceTable { 55 unsigned int mSineSize; 56 float32* mSineWavetable; 57 float32* mSine; 58 float32* mCosecant; 59 60 // call printf for debugging. should not use in finished code. 61 int (*fPrint)(const char* fmt, ...); 62 63 // get a seed for a random number generator 64 int32 (*fRanSeed)(); 65 66 // define a unit def 67 bool (*fDefineUnit)(const char* inUnitClassName, size_t inAllocSize, UnitCtorFunc inCtor, UnitDtorFunc inDtor, 68 uint32 inFlags); 69 70 // define a command /cmd 71 bool (*fDefinePlugInCmd)(const char* inCmdName, PlugInCmdFunc inFunc, void* inUserData); 72 73 // define a command for a unit generator /u_cmd 74 bool (*fDefineUnitCmd)(const char* inUnitClassName, const char* inCmdName, UnitCmdFunc inFunc); 75 76 // define a buf gen 77 bool (*fDefineBufGen)(const char* inName, BufGenFunc inFunc); 78 79 // clear all of the unit's outputs. 80 void (*fClearUnitOutputs)(Unit* inUnit, int inNumSamples); 81 82 // non real time memory allocation 83 void* (*fNRTAlloc)(size_t inSize); 84 void* (*fNRTRealloc)(void* inPtr, size_t inSize); 85 void (*fNRTFree)(void* inPtr); 86 87 // real time memory allocation 88 void* (*fRTAlloc)(World* inWorld, size_t inSize); 89 void* (*fRTRealloc)(World* inWorld, void* inPtr, size_t inSize); 90 void (*fRTFree)(World* inWorld, void* inPtr); 91 92 // call to set a Node to run or not. 93 void (*fNodeRun)(struct Node* node, int run); 94 95 // call to stop a Graph after the next buffer. 96 void (*fNodeEnd)(struct Node* graph); 97 98 // send a trigger from a Node to clients 99 void (*fSendTrigger)(struct Node* inNode, int triggerID, float value); 100 101 // send a reply message from a Node to clients 102 void (*fSendNodeReply)(struct Node* inNode, int replyID, const char* cmdName, int numArgs, const float* values); 103 104 // sending messages between real time and non real time levels. 105 bool (*fSendMsgFromRT)(World* inWorld, struct FifoMsg& inMsg); 106 bool (*fSendMsgToRT)(World* inWorld, struct FifoMsg& inMsg); 107 108 // libsndfile support 109 int (*fSndFileFormatInfoFromStrings)(SF_INFO* info, const char* headerFormatString, const char* sampleFormatString); 110 111 // get nodes by id 112 struct Node* (*fGetNode)(World* inWorld, int inID); 113 struct Graph* (*fGetGraph)(World* inWorld, int inID); 114 115 void (*fNRTLock)(World* inWorld); 116 void (*fNRTUnlock)(World* inWorld); 117 118 bool mUnused0; 119 120 void (*fGroup_DeleteAll)(struct Group* group); 121 void (*fDoneAction)(int doneAction, struct Unit* unit); 122 123 int (*fDoAsynchronousCommand)( 124 World* inWorld, void* replyAddr, const char* cmdName, void* cmdData, 125 AsyncStageFn stage2, // stage2 is non real time 126 AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true 127 AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true 128 AsyncFreeFn cleanup, int completionMsgSize, void* completionMsgData); 129 130 131 // fBufAlloc should only be called within a BufGenFunc 132 int (*fBufAlloc)(SndBuf* inBuf, int inChannels, int inFrames, double inSampleRate); 133 134 // To initialise a specific FFT, ensure your input and output buffers exist. Internal data structures 135 // will be allocated using the alloc object, 136 // Both "fullsize" and "winsize" should be powers of two (this is not checked internally). 137 struct scfft* (*fSCfftCreate)(size_t fullsize, size_t winsize, SCFFT_WindowFunction wintype, float* indata, 138 float* outdata, SCFFT_Direction forward, SCFFT_Allocator& alloc); 139 140 void (*fSCfftDoFFT)(scfft* f); 141 void (*fSCfftDoIFFT)(scfft* f); 142 143 // destroy any resources held internally. 144 void (*fSCfftDestroy)(scfft* f, SCFFT_Allocator& alloc); 145 146 // Get scope buffer. Returns the maximum number of possile frames. 147 bool (*fGetScopeBuffer)(World* inWorld, int index, int channels, int maxFrames, ScopeBufferHnd&); 148 void (*fPushScopeBuffer)(World* inWorld, ScopeBufferHnd&, int frames); 149 void (*fReleaseScopeBuffer)(World* inWorld, ScopeBufferHnd&); 150 }; 151 152 typedef struct InterfaceTable InterfaceTable; 153 154 #define Print (*ft->fPrint) 155 #define RanSeed (*ft->fRanSeed) 156 #define NodeEnd (*ft->fNodeEnd) 157 #define NodeRun (*ft->fNodeRun) 158 #define DefineUnit (*ft->fDefineUnit) 159 #define DefinePlugInCmd (*ft->fDefinePlugInCmd) 160 #define DefineUnitCmd (*ft->fDefineUnitCmd) 161 #define DefineBufGen (*ft->fDefineBufGen) 162 #define ClearUnitOutputs (*ft->fClearUnitOutputs) 163 #define SendTrigger (*ft->fSendTrigger) 164 #define SendNodeReply (*ft->fSendNodeReply) 165 #define SendMsgFromRT (*ft->fSendMsgFromRT) 166 #define SendMsgToRT (*ft->fSendMsgToRT) 167 #define DoneAction (*ft->fDoneAction) 168 169 #define NRTAlloc (*ft->fNRTAlloc) 170 #define NRTRealloc (*ft->fNRTRealloc) 171 #define NRTFree (*ft->fNRTFree) 172 173 #define RTAlloc (*ft->fRTAlloc) 174 #define RTRealloc (*ft->fRTRealloc) 175 #define RTFree (*ft->fRTFree) 176 177 #define SC_GetNode (*ft->fGetNode) 178 #define SC_GetGraph (*ft->fGetGraph) 179 180 #define NRTLock (*ft->fNRTLock) 181 #define NRTUnlock (*ft->fNRTUnlock) 182 183 #define BufAlloc (*ft->fBufAlloc) 184 185 #define GroupDeleteAll (*ft->fGroup_DeleteAll) 186 187 #define SndFileFormatInfoFromStrings (*ft->fSndFileFormatInfoFromStrings) 188 189 #define DoAsynchronousCommand (*ft->fDoAsynchronousCommand) 190 191 #define DefineSimpleUnit(name) (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, 0, 0); 192 193 #define DefineDtorUnit(name) \ 194 (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, (UnitDtorFunc)&name##_Dtor, 0); 195 196 #define DefineSimpleCantAliasUnit(name) \ 197 (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, 0, kUnitDef_CantAliasInputsToOutputs); 198 199 #define DefineDtorCantAliasUnit(name) \ 200 (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, (UnitDtorFunc)&name##_Dtor, \ 201 kUnitDef_CantAliasInputsToOutputs); 202 203 typedef enum { sc_server_scsynth = 0, sc_server_supernova = 1 } SC_ServerType; 204 205 #ifdef STATIC_PLUGINS 206 # define PluginLoad(name) void name##_Load(InterfaceTable* inTable) 207 #else 208 # ifdef SUPERNOVA 209 # define SUPERNOVA_CHECK \ 210 C_LINKAGE SC_API_EXPORT int server_type(void) { return sc_server_supernova; } 211 # else 212 # define SUPERNOVA_CHECK \ 213 C_LINKAGE SC_API_EXPORT int server_type(void) { return sc_server_scsynth; } 214 # endif 215 216 # define PluginLoad(name) \ 217 C_LINKAGE SC_API_EXPORT int api_version(void) { return sc_api_version; } \ 218 SUPERNOVA_CHECK \ 219 C_LINKAGE SC_API_EXPORT void load(InterfaceTable* inTable) 220 #endif 221 222 #define scfft_create (*ft->fSCfftCreate) 223 #define scfft_dofft (*ft->fSCfftDoFFT) 224 #define scfft_doifft (*ft->fSCfftDoIFFT) 225 #define scfft_destroy (*ft->fSCfftDestroy) 226 227 228 class SCWorld_Allocator : public SCFFT_Allocator { 229 InterfaceTable* ft; 230 World* world; 231 232 public: SCWorld_Allocator(InterfaceTable * ft,World * world)233 SCWorld_Allocator(InterfaceTable* ft, World* world): ft(ft), world(world) {} 234 alloc(size_t size)235 virtual void* alloc(size_t size) { return RTAlloc(world, size); } 236 free(void * ptr)237 virtual void free(void* ptr) { RTFree(world, ptr); } 238 }; 239