diff options
Diffstat (limited to 'sc4pd/headers/server')
28 files changed, 3666 insertions, 0 deletions
diff --git a/sc4pd/headers/server/HashTable.h b/sc4pd/headers/server/HashTable.h new file mode 100755 index 0000000..85da92c --- /dev/null +++ b/sc4pd/headers/server/HashTable.h @@ -0,0 +1,356 @@ +/* + 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 +*/ + +#ifndef _HashTable_ +#define _HashTable_ + +#include "SC_Types.h" +#include "SC_BoundsMacros.h" +#include "SC_Str4.h" +#include "Hash.h" +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +template<class T, class Allocator> +class HashTable +{ + Allocator *mPool; + int32 mNumItems, mMaxItems, mTableSize, mHashMask; + T** mItems; + bool mCanResize; + +public: + + HashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true) + : mPool(inPool) + { + mNumItems = 0; + mMaxItems = inMaxItems; + mTableSize = mMaxItems << 1; + mItems = AllocTable(mTableSize); + mHashMask = mTableSize - 1; + mCanResize = inCanResize; + } + + ~HashTable() { + mPool->Free(mItems); + } + + int32 TableSize() const { return mTableSize; } + int32 MaxItems() const { return mMaxItems; } + int32 NumItems() const { return mNumItems; } + + T** AllocTable(int inTableSize) + { + size_t size = inTableSize * sizeof(T*); + T** items = static_cast<T**>(mPool->Alloc(size)); + for (int i=0; i<inTableSize; ++i) { + items[i] = 0; + } + return items; + } + + void MakeEmpty() + { + for (int i=0; i<mTableSize; ++i) { + mItems[i] = 0; + } + mNumItems = 0; + } + + void Resize() + { + int32 newSize = sc_max(mTableSize << 1, 32); + int32 oldSize = mTableSize; + T** oldItems = mItems; + mItems = AllocTable(newSize); + mTableSize = newSize; + mMaxItems = mTableSize >> 1; + mHashMask = mTableSize - 1; + mNumItems = 0; + for (int i=0; i<oldSize; ++i) { + T* item = oldItems[i]; + if (item) Add(item); + } + mPool->Free(oldItems); + //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize); + } + + bool Add(T* inItem) + { + //printf("mNumItems %d\n", mNumItems); + //printf("mMaxItems %d\n", mMaxItems); + //printf("mCanResize %d\n", mCanResize); + if (mNumItems >= mMaxItems) { + if (!mCanResize) return false; + Resize(); + } + + //printf("GetHash(inItem) %d\n", GetHash(inItem)); + //printf("GetKey(inItem) %s\n", GetKey(inItem)); + int32 index = IndexFor(GetHash(inItem), (int32*)GetKey(inItem)); + //printf("index %d\n", index); + + T *item = mItems[index]; + if (item) return item == inItem; + + mItems[index] = inItem; + mNumItems++; + return true; + } + + bool Remove(T* inItem) + { + int32 index = IndexFor(GetHash(inItem), (int32*)GetKey(inItem)); + if (mItems[index] != inItem) return false; + mItems[index] = 0; + + FixCollisionsFrom(index); + mNumItems--; + return true; + } + + bool RemoveKey(int32* inKey) + { + T* item = Get(inKey); + if (!item) return false; + return Remove(item); + } + + int32 IndexFor(int32 inHashID, int32* inKey) const + { + int index = inHashID & mHashMask; + for(;;) { + T *item = mItems[index]; + if (!item) return index; + if (GetHash(item) == inHashID && str4eq(inKey, GetKey(item))) return index; + index = (index + 1) & mHashMask; + } + } + + T* Get(int32* inKey) const + { + return Get(Hash(inKey), inKey); + } + + T* Get(int32 inHashID, int32* inKey) const + { + //printf("Get hash %d %s\n", inHashID, inKey); + int32 index = IndexFor(inHashID, inKey); + //printf("index %d\n", index); + return mItems[index]; + } + + bool Includes(T* inItem) const + { + return Get(GetHash(inItem), GetKey(inItem)) == inItem; + } + + T* AtIndex(int32 inIndex) const + { + return mItems[inIndex]; + } + +private: + void FixCollisionsFrom(int32 inIndex) + { + int oldIndex = inIndex; + for (;;) { + oldIndex = (oldIndex + 1) & mHashMask; + T *oldItem = mItems[oldIndex]; + if (!oldItem) break; + int newIndex = IndexFor(GetHash(oldItem), (int32*)GetKey(oldItem)); + if (oldIndex != newIndex) { + mItems[oldIndex] = mItems[newIndex]; + mItems[newIndex] = oldItem; + } + } + } +}; + + +template<class T, class Allocator> +class IntHashTable +{ + Allocator *mPool; + int32 mNumItems, mMaxItems, mTableSize, mHashMask; + T** mItems; + bool mCanResize; + +public: + + IntHashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true) + : mPool(inPool) + { + mNumItems = 0; + mMaxItems = inMaxItems; + mTableSize = mMaxItems << 1; + mItems = AllocTable(mTableSize); + mHashMask = mTableSize - 1; + mCanResize = inCanResize; + } + + ~IntHashTable() { + mPool->Free(mItems); + } + + int32 TableSize() const { return mTableSize; } + int32 MaxItems() const { return mMaxItems; } + int32 NumItems() const { return mNumItems; } + + T** AllocTable(int inTableSize) + { + size_t size = inTableSize * sizeof(T*); + T** items = static_cast<T**>(mPool->Alloc(size)); + for (int i=0; i<inTableSize; ++i) { + items[i] = 0; + } + return items; + } + + void Resize() + { + int32 newSize = sc_max(mTableSize << 1, 32); + T** oldItems = mItems; + mItems = AllocTable(newSize); + for (int i=0; i<mTableSize; ++i) { + T* item = oldItems[i]; + if (item) Add(item); + } + mTableSize = newSize; + mMaxItems = mTableSize >> 1; + mHashMask = mTableSize - 1; + mPool->Free(oldItems); + //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize); + } + + bool Add(T* inItem) + { + //printf("mNumItems %d\n", mNumItems); + //printf("mMaxItems %d\n", mMaxItems); + //printf("mCanResize %d\n", mCanResize); + if (mNumItems >= mMaxItems) { + if (!mCanResize) return false; + Resize(); + } + + //printf("GetHash(inItem) %d\n", GetHash(inItem)); + //printf("GetKey(inItem) %d\n", GetKey(inItem)); + int32 index = IndexFor(GetHash(inItem), GetKey(inItem)); + //printf("index %d\n", index); + + T *item = mItems[index]; + if (item) return item == inItem; + + mItems[index] = inItem; + mNumItems++; + return true; + } + + bool Remove(T* inItem) + { + int32 index = IndexFor(GetHash(inItem), GetKey(inItem)); + //printf("rmv index %d hash %d key %d\n", index, GetHash(inItem), GetKey(inItem)); + if (mItems[index] != inItem) return false; + mItems[index] = 0; + + FixCollisionsFrom(index); + mNumItems--; + return true; + } + + bool RemoveKey(int32 inKey) + { + T* item = Get(inKey); + if (!item) return false; + return Remove(item); + } + + int32 IndexFor(int32 inHashID, int32 inKey) const + { + int index = inHashID & mHashMask; + for(;;) { + T *item = mItems[index]; + if (!item) return index; + if (GetHash(item) == inHashID && inKey == GetKey(item)) return index; + index = (index + 1) & mHashMask; + } + } + + T* Get(int32 inKey) const + { + //printf("Get key %d\n", inKey); + return Get(Hash(inKey), inKey); + } + + T* Get(int32 inHashID, int32 inKey) const + { + int32 index = IndexFor(inHashID, inKey); + //printf("Get index %d hash %d key %d\n", index, inHashID, inKey); + return mItems[index]; + } + + bool Includes(T* inItem) const + { + return Get(GetHash(inItem), GetKey(inItem)) == inItem; + } + + T* AtIndex(int32 inIndex) const + { + return mItems[inIndex]; + } + + void Dump() + { + for (int i=0; i<mTableSize; ++i) { + T* item = mItems[i]; + if (item) { + printf("%4d %4d %08X %08X\n", i, GetKey(item), GetHash(item), item); + } + } + } + +private: + void FixCollisionsFrom(int32 inIndex) + { + //printf("FixCollisionsFrom %d\n", inIndex); + int oldIndex = inIndex; + for (;;) { + oldIndex = (oldIndex + 1) & mHashMask; + T *oldItem = mItems[oldIndex]; + if (!oldItem) break; + int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem)); + if (oldIndex != newIndex) { + //printf("swap %d %d\n", oldIndex, newIndex); + mItems[oldIndex] = mItems[newIndex]; + mItems[newIndex] = oldItem; + } + } + } +}; + +struct Malloc +{ + void Free(void* ptr) { free(ptr); } + void* Alloc(size_t size) { return malloc(size); } +}; + +#endif diff --git a/sc4pd/headers/server/IntFifo.h b/sc4pd/headers/server/IntFifo.h new file mode 100644 index 0000000..3dde5ec --- /dev/null +++ b/sc4pd/headers/server/IntFifo.h @@ -0,0 +1,87 @@ +/* + 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 +*/ + +#ifndef _IntFifo_ +#define _IntFifo_ + +#ifdef SC_DARWIN +# include <CoreServices/CoreServices.h> +#endif + +template <int N> +class IntFifo +{ +public: + IntFifo() + : mMask(N - 1), mReadHead(0), mWriteHead(0) + {} + + void MakeEmpty() { mReadHead = mWriteHead; } + bool IsEmpty() { return mReadHead == mWriteHead; } + bool HasData() { return mReadHead != mWriteHead; } + + bool Put(int data) + { + long next = NextPos(mWriteHead); + if (next == mReadHead) return false; // fifo is full + mItems[next] = data; +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mWriteHead, next, &mWriteHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next); +#else + mWriteHead = next; +#endif + return true; + } + + int32 Get() + { + //assert(HasData()); + long next = NextPos(mReadHead); + out = mItems[next].Perform(); +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mReadHead, next, &mReadHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next); +#else + mReadHead = next; +#endif + } + +private: + int NextPos(int inPos) { return (inPos + 1) & mMask; } + + long mMask; +#ifdef SC_DARWIN + UInt32 mReadHead, mWriteHead; +#else + volatile int mReadHead, mWriteHead; +#endif + int32 mItems[N]; +}; + +#endif + + diff --git a/sc4pd/headers/server/MsgFifo.h b/sc4pd/headers/server/MsgFifo.h new file mode 100755 index 0000000..cdc8578 --- /dev/null +++ b/sc4pd/headers/server/MsgFifo.h @@ -0,0 +1,169 @@ +/* + 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 +*/ + +#ifndef _MsgFifo_ +#define _MsgFifo_ + +#ifdef SC_DARWIN +# include <CoreServices/CoreServices.h> +#endif + +///////////////////////////////////////////////////////////////////// + +template <class MsgType, int N> +class MsgFifo +{ +public: + MsgFifo() + : mReadHead(0), mWriteHead(0), mFreeHead(0) + {} + + void MakeEmpty() { mFreeHead = mReadHead = mWriteHead; } + bool IsEmpty() { return mReadHead == mWriteHead; } + bool HasData() { return mReadHead != mWriteHead; } + bool NeedsFree() { return mFreeHead != mReadHead; } + + bool Write(MsgType& data) + { + unsigned int next = NextPos(mWriteHead); + if (next == mFreeHead) return false; // fifo is full + mItems[next] = data; +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mWriteHead, next, &mWriteHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next); +#else + mWriteHead = next; +#endif + return true; + } + + void Perform() // get next and advance + { + while (HasData()) { + unsigned int next = NextPos(mReadHead); + mItems[next].Perform(); +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mReadHead, next, &mReadHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next); +#else + mReadHead = next; +#endif + } + } + void Free() // reclaim messages + { + while (NeedsFree()) { + unsigned int next = NextPos(mFreeHead); + mItems[next].Free(); +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mFreeHead, next, &mFreeHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mFreeHead),next); +#else + mFreeHead = next; +#endif + } + } + +private: + int NextPos(int inPos) { return (inPos + 1) & (N - 1); } + +#ifdef SC_DARWIN + UInt32 mReadHead, mWriteHead, mFreeHead; +#else + volatile unsigned int mReadHead, mWriteHead, mFreeHead; +#endif + MsgType mItems[N]; +}; + +///////////////////////////////////////////////////////////////////// + +template <class MsgType, int N> +class MsgFifoNoFree +{ +public: + MsgFifoNoFree() + : mReadHead(0), mWriteHead(0) + { + } + + void MakeEmpty() { mReadHead = mWriteHead; } + bool IsEmpty() { return mReadHead == mWriteHead; } + bool HasData() { return mReadHead != mWriteHead; } + + bool Write(MsgType& data) + { + unsigned int next = NextPos(mWriteHead); + if (next == mReadHead) return false; // fifo is full + mItems[next] = data; +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mWriteHead, next, &mWriteHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next); +#else + mWriteHead = next; +#endif + return true; + } + + void Perform() // get next and advance + { + while (HasData()) { + unsigned int next = NextPos(mReadHead); + mItems[next].Perform(); +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mReadHead, next, &mReadHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next); +#else + mReadHead = next; +#endif + } + } + +private: + int NextPos(int inPos) { return (inPos + 1) & (N - 1); } + +#ifdef SC_DARWIN + UInt32 mReadHead, mWriteHead; +#else + volatile unsigned int mReadHead, mWriteHead; +#endif + MsgType mItems[N]; +}; + +///////////////////////////////////////////////////////////////////// + + +#endif + + diff --git a/sc4pd/headers/server/OSC_Packet.h b/sc4pd/headers/server/OSC_Packet.h new file mode 100644 index 0000000..5964e81 --- /dev/null +++ b/sc4pd/headers/server/OSC_Packet.h @@ -0,0 +1,43 @@ +/* + 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 +*/ +/* + * OSC_Packet.h + * SC3synth + * + * Created by James McCartney on Sat Aug 24 2002. + * Copyright (c) 2001 __MyCompanyName__. All rights reserved. + * + */ + +#ifndef _OSC_Packet_ +#define _OSC_Packet_ + +#include "SC_Reply.h" + +struct OSC_Packet +{ + char *mData; + int32 mSize; + bool mIsBundle; + + ReplyAddress mReplyAddr; +}; + +#endif diff --git a/sc4pd/headers/server/PriorityQueue.h b/sc4pd/headers/server/PriorityQueue.h new file mode 100755 index 0000000..eb1064f --- /dev/null +++ b/sc4pd/headers/server/PriorityQueue.h @@ -0,0 +1,123 @@ +/* + 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 +*/ + +#ifndef _PriorityQueue_ +#define _PriorityQueue_ + +#include <stdio.h> +#include <math.h> +#include <stdexcept> + +#define SANITYCHECK 0 + +#ifdef SC_WIN32 +const int64 kMaxInt64 = 0x7FFFFFFFFFFFFFFF; +#else +const int64 kMaxInt64 = ~(1LL<<63); +#endif + +template <class Event, int N> +class PriorityQueueT +{ +public: + PriorityQueueT() { + Empty(); + } + + bool Add(Event& inEvent) + { + if (mSize >= N) return false; + long mom = mSize++; + long me = mom; + for (; mom>0;) { /* percolate up heap */ + mom = mom - 1 >> 1; + if (inEvent.mTime < mEvents[mom].mTime) { + mEvents[me] = mEvents[mom]; + me = mom; + } else break; + } + mEvents[me] = inEvent; +#if SANITYCHECK + SanityCheck(); +#endif + return true; + } + void Perform(int64 inTime) + { + while (NextTime() <= inTime) { + Event event = Remove(); + event.Perform(); + } + } + int64 NextTime() { return mEvents[0].mTime; } + bool Ready(int64 inTime) { return NextTime() <= inTime; } + void Flush() { Perform(kMaxInt64); } + void Empty() { mSize = 0; SetEmptyTime(); } + void SetEmptyTime() { mEvents[0].mTime = kMaxInt64; } + int Size() { return mSize; } + + Event Remove() + { + Event event = mEvents[0]; + if (--mSize == 0) SetEmptyTime(); + else { + Event temp = mEvents[mSize]; + long mom = 0; + long me = 1; + for (;me < mSize;) { /* demote heap */ + if (me+1 < mSize && mEvents[me].mTime > mEvents[me+1].mTime) { + me ++; + } + if (temp.mTime > mEvents[me].mTime) { + mEvents[mom] = mEvents[me]; + mom = me; + me = (me << 1) + 1; + } else break; + } + mEvents[mom] = temp; + } +#if SANITYCHECK + SanityCheck(); +#endif + return event; + } + void SanityCheck() + { + for (int i=0; i<mSize; ++i) + { + int j = (i<<1)+1; + int k = j+1; + //if (j<mSize && mEvents[i].mTime > mEvents[j].mTime) throw std::runtime_error("priority queue unsorted"); + //if (k<mSize && mEvents[i].mTime > mEvents[k].mTime) throw std::runtime_error("priority queue unsorted"); + } + } + void DebugDump() + { + for (int i=0; i<mSize; ++i) + { + printf("%d %016llX\n", i, mEvents[i].mTime); + } + } +private: + int mSize; + Event mEvents[N]; +}; + +#endif diff --git a/sc4pd/headers/server/ReadWriteMacros.h b/sc4pd/headers/server/ReadWriteMacros.h new file mode 100644 index 0000000..a1bd226 --- /dev/null +++ b/sc4pd/headers/server/ReadWriteMacros.h @@ -0,0 +1,430 @@ +/* + 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 +*/ + + +#ifndef _ReadWriteMacros_ +#define _ReadWriteMacros_ + +#include "SC_Types.h" +#include <stdio.h> +#include <string.h> + +inline void writeData(char *&buf, char *data, int size) +{ + memcpy(buf, data, size); + buf += size; +} + +inline void writeZero(char *&buf, int len) +{ + for (int i=0; i<len; ++i) *buf++ = 0; +} + +inline void writeSkip(char *&buf, int len) +{ + buf += len; +} + +inline void writeInt8(char *&buf, int8 inInt) +{ + *buf++ = (char)(inInt & 255); +} + +inline void writeUInt8(char *&buf, uint8 inInt) +{ + *buf++ = (char)(inInt & 255); +} + +inline void writeInt16_be(char *&buf, int16 inInt) +{ + *buf++ = (char)((inInt >> 8) & 255); + *buf++ = (char)(inInt & 255); +} + +inline void writeInt16_le(char *&buf, int16 inInt) +{ + *buf++ = (char)(inInt & 255); + *buf++ = (char)((inInt >> 8) & 255); +} + +inline void writeInt32_be(char *&buf, int32 inInt) +{ + *buf++ = (char)((inInt >> 24) & 255); + *buf++ = (char)((inInt >> 16) & 255); + *buf++ = (char)((inInt >> 8) & 255); + *buf++ = (char)(inInt & 255); +} + +inline void writeInt32_le(char *&buf, int32 inInt) +{ + *buf++ = (char)(inInt & 255); + *buf++ = (char)((inInt >> 8) & 255); + *buf++ = (char)((inInt >> 16) & 255); + *buf++ = (char)((inInt >> 24) & 255); +} + +inline void writeSymbol(char *&buf, char *inString) +{ + size_t length = strlen(inString); + writeUInt8(buf, (uint8)length); + memcpy(buf, inString, length); + buf += length; +} + +inline void writeString(char *&buf, char *inString, size_t inLength) +{ + writeInt32_be(buf, inLength); + memcpy(buf, inString, inLength); + buf += inLength; +} + +inline void writeString(char *&buf, char *inString) +{ + size_t length = strlen(inString); + writeString(buf, inString, length); +} + + + +inline void writeData(FILE *file, char *data, size_t size) +{ + fwrite(data, 1, size, file); +} + +inline void writeInt8(FILE *file, int8 inInt) +{ + fputc(inInt & 255, file); +} + +inline void writeUInt8(FILE *file, uint8 inInt) +{ + fputc(inInt & 255, file); +} + +inline void writeInt16_be(FILE *file, int16 inInt) +{ + fputc((inInt >> 8) & 255, file); + fputc(inInt & 255, file); +} + +inline void writeInt16_le(FILE *file, int16 inInt) +{ + fputc(inInt & 255, file); + fputc((inInt >> 8) & 255, file); +} + +inline void writeInt32_be(FILE *file, int32 inInt) +{ + fputc((inInt >> 24) & 255, file); + fputc((inInt >> 16) & 255, file); + fputc((inInt >> 8) & 255, file); + fputc(inInt & 255, file); +} + +inline void writeInt64_be(FILE *file, int64 inInt) +{ + writeInt32_be(file, (int32)((inInt >> 32) & 0x00000000FFFFFFFF)); + writeInt32_be(file, (int32)(inInt)); +} + +inline void writeInt32_le(FILE *file, int32 inInt) +{ + fputc(inInt & 255, file); + fputc((inInt >> 8) & 255, file); + fputc((inInt >> 16) & 255, file); + fputc((inInt >> 24) & 255, file); +} + +inline void writeFloat_be(FILE *file, float inFloat) +{ + union { + float f; + int32 i; + } u; + u.f = inFloat; + writeInt32_be(file, u.i); +} + +inline void writeFloat_le(FILE *file, float inFloat) +{ + union { + float f; + int32 i; + } u; + u.f = inFloat; + writeInt32_le(file, u.i); +} + +inline void writeSymbol(FILE *file, char *inString) +{ + size_t length = strlen(inString); + writeUInt8(file, (uint8)length); + fwrite(inString, 1, length, file); +} + +inline void writeString(FILE *file, char *inString, size_t inLength) +{ + writeInt32_be(file, inLength); + fwrite(inString, 1, inLength, file); +} + +inline void writeString(FILE *file, char *inString) +{ + size_t length = strlen(inString); + writeString(file, inString, length); +} + +inline int32 readInt8(FILE *file) +{ + int32 res = fgetc(file); + + return res; +} + +inline uint32 readUInt8(FILE *file) +{ + uint32 res = (uint32)fgetc(file); + return res; +} + +inline int32 readInt16_be(FILE *file) +{ + int32 c = fgetc(file); + int32 d = fgetc(file); + + int32 res = ((c & 255) << 8) | (d & 255); + return res; +} + +inline int32 readInt16_le(FILE *file) +{ + int32 c = fgetc(file); + int32 d = fgetc(file); + + int32 res = ((d & 255) << 8) | (c & 255); + return res; +} + +inline int32 readInt32_be(FILE *file) +{ + int32 a = fgetc(file); + int32 b = fgetc(file); + int32 c = fgetc(file); + int32 d = fgetc(file); + + int32 res = ((a & 255) << 24) | ((b & 255) << 16) | ((c & 255) << 8) | (d & 255); + return res; +} + +inline int32 readInt32_le(FILE *file) +{ + int32 a = fgetc(file); + int32 b = fgetc(file); + int32 c = fgetc(file); + int32 d = fgetc(file); + + int32 res = ((d & 255) << 24) | ((c & 255) << 16) | ((b & 255) << 8) | (a & 255); + return res; +} + +inline int64 readInt64_be(FILE *file) +{ + int64 hi = readInt32_be(file); + int64 lo = readInt32_be(file); + return (hi << 32) | (lo & 0x00000000FFFFFFFF); +} + +inline float readFloat_be(FILE *file) +{ + union { + float f; + int32 i; + } u; + u.i = readInt32_be(file); + //post("readFloat %g\n", u.f); + return u.f; +} + +inline float readFloat_le(FILE *file) +{ + union { + float f; + int32 i; + } u; + u.i = readInt32_le(file); + //post("readFloat %g\n", u.f); + return u.f; +} + +inline void readString(FILE *file, char *outString, size_t inLength) +{ + fread(outString, 1, inLength, file); + outString[inLength] = 0; +} + +inline void readSymbol(FILE *file, char *outString) +{ + size_t length = (size_t)readUInt8(file); + readString(file, outString, length); +} + +inline void readData(FILE *file, char *outData, size_t inLength) +{ + fread(outData, 1, inLength, file); +} + + +inline int32 readInt8(char *&buf) +{ + int32 res = *buf++; + return res; +} + +inline uint32 readUInt8(char *&buf) +{ + uint32 res = *buf++; + return res; +} + +inline int32 readInt16_be(char *&buf) +{ + int32 c = readInt8(buf); + int32 d = readInt8(buf); + + int32 res = ((c & 255) << 8) | (d & 255); + return res; +} + +inline int32 readInt16_le(char *&buf) +{ + int32 c = readInt8(buf); + int32 d = readInt8(buf); + + int32 res = ((d & 255) << 8) | (c & 255); + return res; +} + + +inline int32 readInt32_be(char *&buf) +{ + int32 a = readInt8(buf); + int32 b = readInt8(buf); + int32 c = readInt8(buf); + int32 d = readInt8(buf); + + int32 res = ((a & 255) << 24) | ((b & 255) << 16) | ((c & 255) << 8) | (d & 255); + return res; +} + +inline int32 readInt32_le(char *&buf) +{ + int32 a = readInt8(buf); + int32 b = readInt8(buf); + int32 c = readInt8(buf); + int32 d = readInt8(buf); + + int32 res = ((d & 255) << 24) | ((c & 255) << 16) | ((b & 255) << 8) | (a & 255); + return res; +} + +inline float readFloat_be(char *&buf) +{ + union { + float f; + int32 i; + } u; + u.i = readInt32_be(buf); + //post("readFloat %g\n", u.f); + return u.f; +} + +inline float readFloat_le(char *&buf) +{ + union { + float f; + int32 i; + } u; + u.i = readInt32_le(buf); + //post("readFloat %g\n", u.f); + return u.f; +} + +inline double readDouble_be(char *&buf) +{ + //post("readDouble\n"); + union { + double f; + uint8 c[8]; + } u; + + u.c[0] = (uint8)readInt8(buf); + u.c[1] = (uint8)readInt8(buf); + u.c[2] = (uint8)readInt8(buf); + u.c[3] = (uint8)readInt8(buf); + u.c[4] = (uint8)readInt8(buf); + u.c[5] = (uint8)readInt8(buf); + u.c[6] = (uint8)readInt8(buf); + u.c[7] = (uint8)readInt8(buf); + //post("readDouble %g %08X %08X\n", u.f, u.f); + return u.f; +} + +inline double readDouble_le(char *&buf) +{ + //post("readDouble\n"); + union { + double f; + uint8 c[8]; + } u; + + u.c[7] = (uint8)readInt8(buf); + u.c[6] = (uint8)readInt8(buf); + u.c[5] = (uint8)readInt8(buf); + u.c[4] = (uint8)readInt8(buf); + u.c[3] = (uint8)readInt8(buf); + u.c[2] = (uint8)readInt8(buf); + u.c[1] = (uint8)readInt8(buf); + u.c[0] = (uint8)readInt8(buf); + + //post("readDouble %g\n", u.f); + return u.f; +} + +inline void readString(char *&buf, char *outString, size_t inLength) +{ + memcpy(outString, buf, inLength); + outString[inLength] = 0; + buf += inLength; +} + +inline void readSymbol(char *&buf, char *outString) +{ + size_t length = (size_t)readUInt8(buf); + readString(buf, outString, length); +} + +inline void readData(char *&buf, char *outData, size_t inLength) +{ + memcpy(outData, buf, inLength); + buf += inLength; +} + + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/server/Rendezvous.h b/sc4pd/headers/server/Rendezvous.h new file mode 100644 index 0000000..2067cd2 --- /dev/null +++ b/sc4pd/headers/server/Rendezvous.h @@ -0,0 +1,41 @@ +/* + * Rendezvous.h + * SC3synth + * + * Created by C. Ramakrishnan on Wed Dec 18 2002. + * Illposed Software + * + */ + +/* + 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 +*/ + +#ifndef _Rendezvous_ +#define _Rendezvous_ + +typedef enum { + kSCRendezvous_UDP, + kSCRendezvous_TCP +} SCRendezvousProtocol; + +void PublishPortToRendezvous(SCRendezvousProtocol protocol, short portNum); + +#endif + diff --git a/sc4pd/headers/server/SC_ComPort.h b/sc4pd/headers/server/SC_ComPort.h new file mode 100755 index 0000000..3674fd5 --- /dev/null +++ b/sc4pd/headers/server/SC_ComPort.h @@ -0,0 +1,144 @@ +/* + 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 +*/ + + +#ifndef _SC_ComPort_ +#define _SC_ComPort_ + +#if defined (__APPLE__) && defined (__GNUC__) +#define USE_RENDEZVOUS +#endif + +#include <sys/types.h> +#ifdef SC_WIN32 +# include <winsock2.h> +#else +# include <sys/socket.h> +#endif +#include "OSC_Packet.h" +#include "SC_Sem.h" + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_CmdPort +{ +protected: + pthread_t mThread; + struct World *mWorld; + + void Start(); + virtual ReplyFunc GetReplyFunc()=0; +public: + SC_CmdPort(struct World *inWorld); + + virtual void* Run()=0; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_ComPort : public SC_CmdPort +{ +protected: + int mPortNum; + int mSocket; + struct sockaddr_in mBindSockAddr; + +#ifdef USE_RENDEZVOUS + pthread_t mRendezvousThread; +#endif + +public: + SC_ComPort(struct World *inWorld, int inPortNum); + virtual ~SC_ComPort(); + + int Socket() { return mSocket; } + + int PortNum() const { return mPortNum; } +#ifdef USE_RENDEZVOUS + // default implementation does nothing (this is correct for + // SC_TcpConnectionPort). Subclasses may override. + virtual void PublishToRendezvous() { }; +#endif +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_UdpInPort : public SC_ComPort +{ +protected: + struct sockaddr_in mReplySockAddr; + virtual ReplyFunc GetReplyFunc(); + +public: + SC_UdpInPort(struct World *inWorld, int inPortNum); + ~SC_UdpInPort(); + + int PortNum() const { return mPortNum; } + + void* Run(); +#ifdef USE_RENDEZVOUS + virtual void PublishToRendezvous(); +#endif + +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_TcpInPort : public SC_ComPort +{ + SC_Semaphore mConnectionAvailable; + int mBacklog; + +protected: + virtual ReplyFunc GetReplyFunc(); + +public: + SC_TcpInPort(struct World *inWorld, int inPortNum, int inMaxConnections, int inBacklog); + + virtual void* Run(); + + void ConnectionTerminated(); +#ifdef USE_RENDEZVOUS + virtual void PublishToRendezvous(); +#endif +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_TcpConnectionPort : public SC_ComPort +{ + SC_TcpInPort *mParent; + +protected: + virtual ReplyFunc GetReplyFunc(); + +public: + SC_TcpConnectionPort(struct World *inWorld, SC_TcpInPort *inParent, int inSocket); + virtual ~SC_TcpConnectionPort(); + + virtual void* Run(); +}; + +const int kPacketBufSize = 8192; // this seems to be the maximum size of a UDP packet + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/sc4pd/headers/server/SC_Complex.h b/sc4pd/headers/server/SC_Complex.h new file mode 100644 index 0000000..d4aed20 --- /dev/null +++ b/sc4pd/headers/server/SC_Complex.h @@ -0,0 +1,142 @@ +/* + 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 +*/ + + +#ifndef _SC_Complex_ +#define _SC_Complex_ + +#include "SC_Types.h" +#include "float.h" + +//////////////////////////////////////////////////////////////////////////////// + +struct Polar; + +struct Complex +{ + Complex() {} + Complex(float r, float i) : real(r), imag(i) {} + void Set(float r, float i) { real = r; imag = i; } + + Complex& operator=(Complex b) { real = b.real; imag = b.imag; return *this; } + Complex& operator=(float b) { real = b; imag = 0.; return *this; } + + Polar ToPolar(); + Polar ToPolarApx(); + + void ToPolarInPlace(); + void ToPolarApxInPlace(); + + float real, imag; +}; + +struct Polar +{ + Polar() {} + Polar(float m, float p) : mag(m), phase(p) {} + void Set(float m, float p) { mag = m; phase = p; } + + Complex ToComplex(); + Complex ToComplexApx(); + + void ToComplexInPlace(); + void ToComplexApxInPlace(); + + float mag, phase; +}; + +struct ComplexFT +{ + float dc, nyq; + Complex complex[1]; +}; + +struct PolarFT +{ + float dc, nyq; + Polar polar[1]; +}; + +void ToComplex(Polar in, Complex& out); + +inline Complex operator+(Complex a, Complex b) { return Complex(a.real + b.real, a.imag + b.imag); } +inline Complex operator+(Complex a, float b) { return Complex(a.real + b, a.imag); } +inline Complex operator+(float a, Complex b) { return Complex(a + b.real, b.imag); } + +inline Complex& operator+=(Complex& a, const Complex& b) { a.real += b.real, a.imag += b.imag; return a; } +inline Complex& operator+=(Complex& a, float b) { a.real += b; return a; } + +inline Complex operator-(Complex a, Complex b) { return Complex(a.real - b.real, a.imag - b.imag); } +inline Complex operator-(Complex a, float b) { return Complex(a.real - b, a.imag); } +inline Complex operator-(float a, Complex b) { return Complex(a - b.real, b.imag); } + +inline Complex operator-=(Complex a, Complex b) { a.real -= b.real, a.imag -= b.imag; return a; } +inline Complex operator-=(Complex a, float b) { a.real -= b; return a; } + +inline Complex operator*(Complex a, Complex b) +{ + return Complex(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real); +} + +inline Complex operator*(Complex a, float b) +{ + return Complex(a.real * b, a.imag * b); +} + +inline Complex operator*(float a, Complex b) +{ + return Complex(b.real * a, b.imag * a); +} + +inline Complex operator*=(Complex a, Complex b) +{ + a.Set( + a.real * b.real - a.imag * b.imag, + a.real * b.imag + a.imag * b.real + ); + return a; +} + +inline Complex operator*=(Complex a, float b) +{ + a.real *= b; + a.imag *= b; + return a; +} + + +inline Polar operator*(Polar a, float b) +{ + return Polar(a.mag * b, a.phase); +} + +inline Polar operator*(float a, Polar b) +{ + return Polar(a * b.mag, b.phase); +} + +inline Polar operator*=(Polar a, float b) +{ + a.mag *= b; + return a; +} + + +#endif diff --git a/sc4pd/headers/server/SC_CoreAudio.h b/sc4pd/headers/server/SC_CoreAudio.h new file mode 100755 index 0000000..fba5184 --- /dev/null +++ b/sc4pd/headers/server/SC_CoreAudio.h @@ -0,0 +1,263 @@ +/* + 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 +*/ + + +#ifndef _SC_CoreAudio_ +#define _SC_CoreAudio_ + +#include "MsgFifo.h" +#include "SC_FifoMsg.h" +#include "OSC_Packet.h" +#include "SC_SyncCondition.h" +#include "PriorityQueue.h" +#include "SC_Lock.h" + +#define SC_AUDIO_API_COREAUDIO 1 +#define SC_AUDIO_API_JACK 2 +#define SC_AUDIO_API_PORTAUDIO 3 + +#ifdef SC_WIN32 +# define SC_AUDIO_API SC_AUDIO_API_PORTAUDIO +#endif + +#ifndef SC_AUDIO_API +# define SC_AUDIO_API SC_AUDIO_API_COREAUDIO +#endif // SC_AUDIO_API + +#if SC_AUDIO_API == SC_AUDIO_API_COREAUDIO +# include <CoreAudio/AudioHardware.h> +# include <CoreAudio/HostTime.h> +#endif + +#if SC_AUDIO_API == SC_AUDIO_API_JACK +# include <jack/jack.h> +class SC_JackPortList; +#endif + +#if SC_AUDIO_API == SC_AUDIO_API_PORTAUDIO +#include "portaudio.h" +#endif + + +struct SC_ScheduledEvent +{ + SC_ScheduledEvent() : mTime(0), mPacket(0) {} + SC_ScheduledEvent(struct World *inWorld, int64 inTime, OSC_Packet *inPacket) + : mTime(inTime), mPacket(inPacket), mWorld(inWorld) {} + + int64 Time() { return mTime; } + void Perform(); + + int64 mTime; + OSC_Packet *mPacket; + struct World *mWorld; +}; + +typedef MsgFifo<FifoMsg, 1024> EngineFifo; + + +class SC_AudioDriver +{ +protected: + int64 mOSCincrement; + struct World *mWorld; + double mOSCtoSamples; + int mSampleTime; + + // Common members + uint32 mHardwareBufferSize; // bufferSize returned by kAudioDevicePropertyBufferSize + EngineFifo mFromEngine, mToEngine; + SC_SyncCondition mAudioSync; + pthread_t mThread; + bool mRunThreadFlag; + uint32 mSafetyOffset; + PriorityQueueT<SC_ScheduledEvent, 2048> mScheduler; + SC_Lock *mProcessPacketLock; + int mNumSamplesPerCallback; + uint32 mPreferredHardwareBufferFrameSize; + uint32 mPreferredSampleRate; + double mBuffersPerSecond; + double mAvgCPU, mPeakCPU; + int mPeakCounter, mMaxPeakCounter; + double mOSCincrementNumerator; + + double mStartHostSecs; + double mPrevHostSecs; + double mStartSampleTime; + double mPrevSampleTime; + double mSmoothSampleRate; + double mSampleRate; + + // Driver interface methods, implemented by subclasses + virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate) = 0; + virtual bool DriverStart() = 0; + virtual bool DriverStop() = 0; + +public: + // Common methods + SC_AudioDriver(struct World *inWorld); + virtual ~SC_AudioDriver(); + + int64 mOSCbuftime; + + bool Setup(); + bool Start(); + bool Stop(); + + void ClearSched() { mScheduler.Empty(); } + + void Lock() { mProcessPacketLock->Lock(); } + void Unlock() { mProcessPacketLock->Unlock(); } + + void RunNonRealTime(float *in, float *out, int numSamples, int64 oscTime); + void* RunThread(); + + int SafetyOffset() const { return mSafetyOffset; } + int NumSamplesPerCallback() const { return mNumSamplesPerCallback; } + void SetPreferredHardwareBufferFrameSize(int inSize) + { + mPreferredHardwareBufferFrameSize = inSize; + } + void SetPreferredSampleRate(int inRate) + { + mPreferredSampleRate = inRate; + } + + bool SendMsgToEngine(FifoMsg& inMsg); + bool SendMsgFromEngine(FifoMsg& inMsg); + + void AddEvent(SC_ScheduledEvent& event) { mScheduler.Add(event); } + + double GetAvgCPU() const { return mAvgCPU; } + double GetPeakCPU() const { return mPeakCPU; } + double GetSampleRate() const { return mSampleRate; } + double GetActualSampleRate() const { return mSmoothSampleRate; } +}; + + +// the following classes should be split out into separate source files. +#if SC_AUDIO_API == SC_AUDIO_API_COREAUDIO +class SC_CoreAudioDriver : public SC_AudioDriver +{ + + AudioBufferList * mInputBufList; + AudioDeviceID mInputDevice; + AudioDeviceID mOutputDevice; + + AudioStreamBasicDescription inputStreamDesc; // info about the default device + AudioStreamBasicDescription outputStreamDesc; // info about the default device + + friend OSStatus appIOProc ( AudioDeviceID inDevice, + const AudioTimeStamp* inNow, + const AudioBufferList* inInputData, + const AudioTimeStamp* inInputTime, + AudioBufferList* outOutputData, + const AudioTimeStamp* inOutputTime, + void* defptr); + +protected: + // Driver interface methods + virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate); + virtual bool DriverStart(); + virtual bool DriverStop(); + +public: + SC_CoreAudioDriver(struct World *inWorld); + virtual ~SC_CoreAudioDriver(); + + void Run(const AudioBufferList* inInputData, AudioBufferList* outOutputData, int64 oscTime); + + bool UseInput() { return mInputDevice != kAudioDeviceUnknown; } + bool UseSeparateIO() { return UseInput() && mInputDevice != mOutputDevice; } + AudioDeviceID InputDevice() { return mInputDevice; } + AudioDeviceID OutputDevice() { return mOutputDevice; } + + void SetInputBufferList(AudioBufferList * inBufList) { mInputBufList = inBufList; } + AudioBufferList* GetInputBufferList() const { return mInputBufList; } +}; + +inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld) +{ + return new SC_CoreAudioDriver(inWorld); +} +#endif // SC_AUDIO_API_COREAUDIO + + +#if SC_AUDIO_API == SC_AUDIO_API_JACK +class SC_JackDriver : public SC_AudioDriver +{ + jack_client_t *mClient; + SC_JackPortList *mInputList; + SC_JackPortList *mOutputList; + int64 mMaxOutputLatency; + +protected: + // Driver interface methods + virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate); + virtual bool DriverStart(); + virtual bool DriverStop(); + +public: + SC_JackDriver(struct World *inWorld); + virtual ~SC_JackDriver(); + + void Run(); + void BufferSizeChanged(int numSamples); + void SampleRateChanged(double sampleRate); + void GraphOrderChanged(); +}; + +inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld) +{ + return new SC_JackDriver(inWorld); +} +#endif // SC_AUDIO_API_JACK + + +#if SC_AUDIO_API == SC_AUDIO_API_PORTAUDIO +class SC_PortAudioDriver : public SC_AudioDriver +{ + + int mInputChannelCount, mOutputChannelCount; + PaStream *mStream; + +protected: + // Driver interface methods + virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate); + virtual bool DriverStart(); + virtual bool DriverStop(); + +public: + SC_PortAudioDriver(struct World *inWorld); + virtual ~SC_PortAudioDriver(); + + int PortAudioCallback( const void *input, void *output, + unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags ); +}; + +inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld) +{ + return new SC_PortAudioDriver(inWorld); +} +#endif // SC_AUDIO_API_PORTAUDIO + + +#endif diff --git a/sc4pd/headers/server/SC_Errors.h b/sc4pd/headers/server/SC_Errors.h new file mode 100755 index 0000000..3d3459a --- /dev/null +++ b/sc4pd/headers/server/SC_Errors.h @@ -0,0 +1,58 @@ +/* + 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 +*/ + + +#ifndef _SC_Errors_ +#define _SC_Errors_ + +typedef int SCErr; + +const char *SC_ErrorString(SCErr err); + +enum { + kSCErr_None, + kSCErr_Failed, + kSCErr_NodeNotFound, + kSCErr_TargetNodeNotFound, + kSCErr_GroupNotFound, + kSCErr_SynthDefNotFound, + kSCErr_NoSuchCommand, + kSCErr_WrongArgType, + kSCErr_IndexOutOfRange, + kSCErr_AccessDenied, + kSCErr_NoReplyPort, + kSCErr_InvalidControlIndex, + kSCErr_AlreadyLoggedIn, + kSCErr_NotLoggedIn, + kSCErr_TooManyUsers, + kSCErr_TooManyNodes, + kSCErr_DuplicateNodeID, + kSCErr_ReservedNodeID, + kSCErr_OutOfRealTimeMemory, + + kSCErr_UnsupportedHeaderFormat, + kSCErr_UnsupportedSampleFormat, + + kSCErr_BufGenNotFound, + + kSCErr_NumErrors +}; + +#endif diff --git a/sc4pd/headers/server/SC_GraphDef.h b/sc4pd/headers/server/SC_GraphDef.h new file mode 100644 index 0000000..dca6fd2 --- /dev/null +++ b/sc4pd/headers/server/SC_GraphDef.h @@ -0,0 +1,75 @@ +/* + 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 +*/ + + +#ifndef _SC_GraphDef_ +#define _SC_GraphDef_ + +#include "SC_SynthDef.h" +#include "HashTable.h" + +struct ParamSpec +{ + int32 mName[kSCNameLen]; + int32 mIndex; + int32 mHash; +}; + +typedef HashTable<ParamSpec, Malloc> ParamSpecTable; + +struct GraphDef +{ + NodeDef mNodeDef; + + uint32 mNumControls; + + uint32 mNumWires; + uint32 mNumConstants; + uint32 mNumUnitSpecs; + uint32 mNumWireBufs; + uint32 mNumCalcUnits; + + float32 *mInitialControlValues; + float32 *mConstants; + + struct UnitSpec *mUnitSpecs; + + size_t mWiresAllocSize, mUnitsAllocSize, mCalcUnitsAllocSize; + size_t mControlAllocSize, mMapControlsAllocSize; + + uint32 mNumParamSpecs; + ParamSpec *mParamSpecs; + ParamSpecTable *mParamSpecTable; + + int mRefCount; + struct GraphDef* mNext; +}; +typedef struct GraphDef GraphDef; + +GraphDef* GraphDef_Recv(World *inWorld, char *buffer, GraphDef *inList); +GraphDef* GraphDef_Load(struct World *inWorld, const char *filename, GraphDef* inList); +GraphDef* GraphDef_LoadDir(struct World *inWorld, char *dirname, GraphDef* inList); +GraphDef* GraphDef_LoadGlob(World *inWorld, const char *pattern, GraphDef *inList); +void GraphDef_DeleteMsg(struct World *inWorld, GraphDef *inDef); +void GraphDef_Dump(GraphDef *inGraphDef); +int32 GetHash(ParamSpec* inParamSpec); +int32* GetKey(ParamSpec* inParamSpec); + +#endif diff --git a/sc4pd/headers/server/SC_Group.h b/sc4pd/headers/server/SC_Group.h new file mode 100644 index 0000000..5a104a7 --- /dev/null +++ b/sc4pd/headers/server/SC_Group.h @@ -0,0 +1,34 @@ +/* + 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 +*/ + + +#ifndef _SC_Group_ +#define _SC_Group_ + +#include "SC_Graph.h" + +struct Group { + Node mNode; + + Node *mHead, *mTail; +}; +typedef struct Group Group; + +#endif diff --git a/sc4pd/headers/server/SC_HiddenWorld.h b/sc4pd/headers/server/SC_HiddenWorld.h new file mode 100644 index 0000000..7776874 --- /dev/null +++ b/sc4pd/headers/server/SC_HiddenWorld.h @@ -0,0 +1,113 @@ +/* + 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 +*/ + + +#ifndef _SC_HiddenWorld_ +#define _SC_HiddenWorld_ + +#include "SC_Types.h" +#include "SC_Sem.h" +#include "SC_Rate.h" +#include "SC_SndBuf.h" +#include "SC_RGen.h" +#include "HashTable.h" +#include "SC_World.h" +#include "SC_Reply.h" +#include "MsgFifo.h" + +extern HashTable<struct UnitDef, Malloc> *gUnitDefLib; + + +struct TriggerMsg { + World *mWorld; + int32 mNodeID; + int32 mTriggerID; + float mValue; + + void Perform(); +}; + +struct NodeEndMsg { + World *mWorld; + int32 mNodeID; + int32 mGroupID; + int32 mPrevNodeID; + int32 mNextNodeID; + int32 mIsGroup; + int32 mHeadID; + int32 mTailID; + int32 mState; + + void Perform(); +}; + +struct DeleteGraphDefMsg { + struct GraphDef* mDef; + + void Perform(); +}; + + +typedef MsgFifoNoFree<TriggerMsg, 1024> TriggersFifo; +typedef MsgFifoNoFree<NodeEndMsg, 1024> NodeEndsFifo; +typedef MsgFifoNoFree<DeleteGraphDefMsg, 512> DeleteGraphDefsFifo; + +struct HiddenWorld +{ + + class AllocPool *mAllocPool; + IntHashTable<struct Node, AllocPool> *mNodeLib; + HashTable<struct GraphDef, Malloc> *mGraphDefLib; + uint32 mNumUsers, mMaxUsers; + ReplyAddress *mUsers; + + class SC_AudioDriver *mAudioDriver; + char mPassword[32]; + + uint32 mMaxWireBufs; + float *mWireBufSpace; + + TriggersFifo mTriggers; + NodeEndsFifo mNodeEnds; + DeleteGraphDefsFifo mDeleteGraphDefs; + + SC_Semaphore* mQuitProgram; + + SNDFILE *mNRTInputFile; + SNDFILE *mNRTOutputFile; + FILE *mNRTCmdFile; + + int32 mHiddenID; + int32 mRecentID; + +#ifdef SC_DARWIN + const char* mInputStreamsEnabled; + const char* mOutputStreamsEnabled; +#endif +}; + +typedef struct HiddenWorld HiddenWorld; + +inline SC_AudioDriver *AudioDriver(World *inWorld) +{ + return inWorld->hw->mAudioDriver; +} + +#endif diff --git a/sc4pd/headers/server/SC_Lib.h b/sc4pd/headers/server/SC_Lib.h new file mode 100755 index 0000000..552a231 --- /dev/null +++ b/sc4pd/headers/server/SC_Lib.h @@ -0,0 +1,62 @@ +/* + 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 +*/ + + +#ifndef _SC_Lib_ +#define _SC_Lib_ + +#include "SC_Errors.h" +#include "SC_Lock.h" +#include "SC_Types.h" +#include "Hash.h" +#include "HashTable.h" +#include <stdlib.h> +#include <string.h> + +class SC_NamedObj +{ +public: + SC_NamedObj(); + virtual ~SC_NamedObj(); + + const int32* Name() const { return mName; } + void SetName(const char *inName); + void SetName(const int32 *inName); + +private: + friend int32 GetHash(const SC_NamedObj *inObj); + friend const int32* GetKey(const SC_NamedObj *inObj); + + int32 mName[kSCNameLen]; + int32 mHash; +}; + +inline int32 GetHash(const SC_NamedObj *inObj) +{ + return inObj->mHash; +} + +inline const int32 *GetKey(const SC_NamedObj *inObj) +{ + return inObj->mName; +} + +#endif + diff --git a/sc4pd/headers/server/SC_Lib_Cintf.h b/sc4pd/headers/server/SC_Lib_Cintf.h new file mode 100755 index 0000000..64eda5e --- /dev/null +++ b/sc4pd/headers/server/SC_Lib_Cintf.h @@ -0,0 +1,124 @@ +/* + 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 +*/ + + +#ifndef _SC_Lib_Cintf_ +#define _SC_Lib_Cintf_ + +#include "SC_Lib.h" +#include "SC_Reply.h" + +typedef SCErr (*SC_CommandFunc)(struct World *inWorld, int inSize, char *inData, ReplyAddress *inReply); + +class SC_LibCmd : public SC_NamedObj +{ +public: + SC_LibCmd(SC_CommandFunc inFunc); + + SCErr Perform(struct World *inWorld, int inSize, char *inData, ReplyAddress *inReply); + +private: + SC_CommandFunc mFunc; +}; + +extern Malloc gMalloc; +extern HashTable<class SC_LibCmd, Malloc> *gCmdLib; + +void initialize_library(); +SCErr NewCommand(const char *inPath, uint32 inCommandNumber, SC_CommandFunc inFunc); + +// command numbers: +enum { + cmd_none = 0, + + cmd_notify = 1, + cmd_status = 2, + cmd_quit = 3, + cmd_cmd = 4, + + cmd_d_recv = 5, + cmd_d_load = 6, + cmd_d_loadDir = 7, + cmd_d_freeAll = 8, + + cmd_s_new = 9, + + cmd_n_trace = 10, + cmd_n_free = 11, + cmd_n_run = 12, + cmd_n_cmd = 13, + cmd_n_map = 14, + cmd_n_set = 15, + cmd_n_setn = 16, + cmd_n_fill = 17, + cmd_n_before = 18, + cmd_n_after = 19, + + cmd_u_cmd = 20, + + cmd_g_new = 21, + cmd_g_head = 22, + cmd_g_tail = 23, + cmd_g_freeAll = 24, + + cmd_c_set = 25, + cmd_c_setn = 26, + cmd_c_fill = 27, + + cmd_b_alloc = 28, + cmd_b_allocRead = 29, + cmd_b_read = 30, + cmd_b_write = 31, + cmd_b_free = 32, + cmd_b_close = 33, + cmd_b_zero = 34, + cmd_b_set = 35, + cmd_b_setn = 36, + cmd_b_fill = 37, + cmd_b_gen = 38, + + cmd_dumpOSC = 39, + + cmd_c_get = 40, + cmd_c_getn = 41, + cmd_b_get = 42, + cmd_b_getn = 43, + cmd_s_get = 44, + cmd_s_getn = 45, + + cmd_n_query = 46, + cmd_b_query = 47, + + cmd_n_mapn = 48, + cmd_s_noid = 49, + + cmd_g_deepFree = 50, + cmd_clearSched = 51, + + cmd_sync = 52, + + NUMBER_OF_COMMANDS = 53 +}; + +extern SC_LibCmd* gCmdArray[NUMBER_OF_COMMANDS]; + + +#endif + diff --git a/sc4pd/headers/server/SC_List.h b/sc4pd/headers/server/SC_List.h new file mode 100755 index 0000000..d5bed41 --- /dev/null +++ b/sc4pd/headers/server/SC_List.h @@ -0,0 +1,229 @@ +/* + 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 +*/ + +/* + +A doubly linked list template. + +*/ + +#ifndef _SC_List_ +#define _SC_List_ + +#include <stdexcept> +#ifndef NDEBUG +# define NDEBUG +#endif +#include <assert.h> + + +// A Link can be a node in a list or a list itself. + +template <class T> +class Link +{ +public: + Link() : mNext(this), mPrev(this) {} + + T* Prev() { return static_cast<T*>(mPrev); } + T* Next() { return static_cast<T*>(mNext); } + + void RemoveLeaveDangling() + { + mPrev->mNext = mNext; + mNext->mPrev = mPrev; + } + + void Remove() + { + RemoveLeaveDangling(); + mNext = mPrev = this; + } + + void InsertAfter(T *inLink) + { + mPrev = inLink; + mNext = inLink->mNext; + mNext->mPrev = this; + mPrev->mNext = this; + } + + void InsertBefore(T *inLink) + { + mNext = inLink; + mPrev = inLink->mPrev; + mNext->mPrev = this; + mPrev->mNext = this; + } + + T* Head() { return static_cast<T*>(mNext); } + T* Tail() { return static_cast<T*>(mPrev); } + + T* PopHead(); + T* PopTail(); + void PushHead(T* inBuf); + void PushTail(T* inBuf); + + bool ContainsBuf(T* inBuf); + bool IsEmpty() { return mNext == this; } + void BeEmpty() { mNext = mPrev = this; } + + void Cat(T* inLink); + + bool SanityCheck(); + void DebugDump(); + +//private: +// Codewarrior refuses to inline Next() in some places.. + Link<T> *mNext, *mPrev; +}; + +template <class T, class Alloc> +void MakeListEmpty(Link<T> *inLink, Alloc* inAlloc) +{ + Link<T>* link = inLink->mNext; + while (link != inLink) { + Link<T>* nextlink = link->mNext; + // SC uses placement new extensively, so here we do a 'placement delete'. + // Using DestructSelf allows me to have either virtual + // or non virtual destructors in subclasses at the discretion of the subclass. + ((T*)(link))->DestructSelf(); + inAlloc->Free(static_cast<T*>(link)); + link = nextlink; + } + inLink->mNext = inLink->mPrev = inLink; +} + +template <class T> +void Link<T>::PushHead(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + link->InsertAfter(static_cast<T*>(this)); + + assert(SanityCheck()); +} + +template <class T> +T* Link<T>::PopHead() +{ + assert(SanityCheck()); + if (IsEmpty()) return 0; + + Link<T>* link = mNext; + + link->Remove(); + + assert(SanityCheck()); + return static_cast<T*>(link); +} + +template <class T> +void Link<T>::PushTail(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + link->InsertBefore(static_cast<T*>(this)); + + assert(SanityCheck()); +} + +template <class T> +T* Link<T>::PopTail() +{ + assert(SanityCheck()); + if (IsEmpty()) return 0; + + Link<T>* link = mPrev; + link->Remove(); + + assert(SanityCheck()); + return static_cast<T*>(link); +} + +template <class T> +void Link<T>::Cat(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + + if (link->IsEmpty()) return; + if (IsEmpty()) { + mNext = link->mNext; + mPrev = link->mPrev; + link->mNext->mPrev = this; + link->mPrev->mNext = this; + } else { + link->mNext->mPrev = mPrev; + link->mPrev->mNext = this; + mPrev->mNext = link->mNext; + mPrev = link->mPrev; + } + link->mPrev = link; + link->mNext = link; + + assert(SanityCheck()); +} + +template <class T> +bool Link<T>::ContainsBuf(T* inLink) +{ + Link<T>* link = static_cast<Link<T>*>(inLink); + Link<T>* curLink = mNext; + while (curLink != this) { + if (curLink == link) return true; + curLink = curLink->mNext; + } + return false; +} + +template <class T> +void Link<T>::DebugDump() +{ + Link<T>* link = mNext; + while (link != this) { + //postbuf("Link-> %08X next %08X prev %08X\n", + // link, link->mNext, link->mPrev); + link = link->mNext; + } +} + +template <class T> +bool Link<T>::SanityCheck() +{ + Link<T>* link = mNext; + while (link != this) { + if (link->mPrev->mNext != link) { + throw std::runtime_error("Link: bad link <-,->"); + } + if (link->mNext->mPrev != link) { + throw std::runtime_error("Link: bad link ->,<-"); + } + link = link->mNext; + } + return true; +} + + + +#endif diff --git a/sc4pd/headers/server/SC_Lock.h b/sc4pd/headers/server/SC_Lock.h new file mode 100755 index 0000000..57635fe --- /dev/null +++ b/sc4pd/headers/server/SC_Lock.h @@ -0,0 +1,38 @@ +/* + 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 +*/ + + +#ifndef _SC_Lock_ +#define _SC_Lock_ + +#include <pthread.h> + +class SC_Lock +{ +public: + SC_Lock() { pthread_mutex_init (&mutex, NULL); } + ~SC_Lock() { pthread_mutex_destroy (&mutex); } + void Lock() { pthread_mutex_lock (&mutex); } + void Unlock() { pthread_mutex_unlock (&mutex); } +private: + pthread_mutex_t mutex; +}; + +#endif diff --git a/sc4pd/headers/server/SC_Prototypes.h b/sc4pd/headers/server/SC_Prototypes.h new file mode 100644 index 0000000..c2f353e --- /dev/null +++ b/sc4pd/headers/server/SC_Prototypes.h @@ -0,0 +1,213 @@ +/* + 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 +*/ + + +#ifndef _SC_Prototypes_ +#define _SC_Prototypes_ + +#include <ctype.h> // for size_t + +#include "SC_Types.h" + +//////////////////////////////////////////////////////////////////////// + +// replacement for calloc. +// calloc lazily zeroes memory on first touch. This is good for most purposes, but bad for realtime audio. +void* zalloc(size_t n, size_t size); + +//////////////////////////////////////////////////////////////////////// + +void World_Run(struct World *inWorld); +void World_Start(World *inWorld); +void World_Cleanup(World *inWorld); +void World_SetSampleRate(struct World *inWorld, double inSampleRate); + +extern "C" { +void* World_Alloc(struct World *inWorld, size_t inByteSize); +void* World_Realloc(struct World *inWorld, void *inPtr, size_t inByteSize); +void World_Free(struct World *inWorld, void *inPtr); +void World_NRTLock(World *world); +void World_NRTUnlock(World *world); +} + +size_t World_TotalFree(struct World *inWorld); +size_t World_LargestFreeChunk(struct World *inWorld); + + +int32 GetKey(struct Node *inNode); +int32 GetHash(struct Node *inNode); +bool World_AddNode(struct World *inWorld, struct Node* inNode); +bool World_RemoveNode(struct World *inWorld, struct Node* inNode); + +extern "C" { +struct Node* World_GetNode(struct World *inWorld, int32 inID); +struct Graph* World_GetGraph(struct World *inWorld, int32 inID); +} + +struct Group* World_GetGroup(struct World *inWorld, int32 inID); + +int32 *GetKey(struct UnitDef *inUnitDef); +int32 GetHash(struct UnitDef *inUnitDef); +bool AddUnitDef(struct UnitDef* inUnitDef); +bool RemoveUnitDef(struct UnitDef* inUnitDef); +struct UnitDef* GetUnitDef(int32* inKey); + +int32 *GetKey(struct BufGen *inBufGen); +int32 GetHash(struct BufGen *inBufGen); +bool AddBufGen(struct BufGen* inBufGen); +bool RemoveBufGen(struct BufGen* inBufGen); +struct BufGen* GetBufGen(int32* inKey); + +int32 *GetKey(struct PlugInCmd *inPlugInCmd); +int32 GetHash(struct PlugInCmd *inPlugInCmd); +bool AddPlugInCmd(struct PlugInCmd* inPlugInCmd); +bool RemovePlugInCmd(struct PlugInCmd* inPlugInCmd); +struct PlugInCmd* GetPlugInCmd(int32* inKey); +int PlugIn_DoCmd(struct World *inWorld, int inSize, char *inArgs, struct ReplyAddress *inReply); + +int32 *GetKey(struct GraphDef *inGraphDef); +int32 GetHash(struct GraphDef *inGraphDef); +bool World_AddGraphDef(struct World *inWorld, struct GraphDef* inGraphDef); +bool World_FreeGraphDef(struct World *inWorld, struct GraphDef* inGraphDef); +bool World_RemoveGraphDef(struct World *inWorld, struct GraphDef* inGraphDef); +struct GraphDef* World_GetGraphDef(struct World *inWorld, int32* inKey); +void World_FreeAllGraphDefs(World *inWorld); +void GraphDef_Free(GraphDef *inGraphDef); +void GraphDef_Define(World *inWorld, GraphDef *inList); +void GraphDef_FreeOverwritten(World *inWorld); + +SCErr bufAlloc(struct SndBuf* buf, int numChannels, int numFrames, double sampleRate); + +//////////////////////////////////////////////////////////////////////// + +void Rate_Init(struct Rate *inRate, double inSampleRate, int inBufLength); + +void Dimension_Init(struct SC_Dimension *inDimension, int inWidth, int inHeight); + +//////////////////////////////////////////////////////////////////////// + +#define GRAPHDEF(inGraph) ((GraphDef*)((inGraph)->mNode.mDef)) +#define GRAPH_PARAM_TABLE(inGraph) (GRAPHDEF(inGraph)->mParamSpecTable) + +int Graph_New(struct World *inWorld, struct GraphDef *def, int32 inID, struct sc_msg_iter* args, struct Graph** outGraph); +void Graph_Ctor(struct World *inWorld, struct GraphDef *inGraphDef, struct Graph *graph, struct sc_msg_iter *msg); +void Graph_Dtor(struct Graph *inGraph); +int Graph_GetControl(struct Graph* inGraph, uint32 inIndex, float& outValue); +int Graph_GetControl(struct Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, float& outValue); +void Graph_SetControl(struct Graph* inGraph, uint32 inIndex, float inValue); +void Graph_SetControl(struct Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, float inValue); +void Graph_MapControl(Graph* inGraph, uint32 inIndex, uint32 inBus); +void Graph_MapControl(Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, uint32 inBus); +void Graph_Trace(Graph *inGraph); +void Graph_RemoveID(World* inWorld, Graph *inGraph); + +//////////////////////////////////////////////////////////////////////// + +int Node_New(struct World *inWorld, struct NodeDef *def, int32 inID, struct Node **outNode); +void Node_Dtor(struct Node *inNode); +void Node_Remove(struct Node* s); +void Node_Delete(struct Node* inNode); +void Node_AddAfter(struct Node* s, struct Node *afterThisOne); +void Node_AddBefore(struct Node* s, struct Node *beforeThisOne); +void Node_Replace(struct Node* s, struct Node *replaceThisOne); +void Node_SetControl(Node* inNode, int inIndex, float inValue); +void Node_SetControl(Node* inNode, int32 inHash, int32 *inName, int inIndex, float inValue); +void Node_MapControl(Node* inNode, int inIndex, int inBus); +void Node_MapControl(Node* inNode, int32 inHash, int32 *inName, int inIndex, int inBus); +void Node_StateMsg(Node* inNode, int inState); +void Node_Trace(Node* inNode); + +extern "C" { +void Node_SetRun(Node* inNode, int inRun); +void Node_SendTrigger(Node* inNode, int triggerID, float value); +void Node_End(struct Node* inNode); +void Node_NullCalc(struct Node* inNode); +void Unit_DoneAction(int doneAction, struct Unit* unit); +} + +//////////////////////////////////////////////////////////////////////// + +extern "C" { +void Group_Calc(Group *inGroup); +void Graph_Calc(struct Graph *inGraph); +} + +int Group_New(World *inWorld, int32 inID, Group** outGroup); +void Group_Dtor(Group *inGroup); +void Group_DeleteAll(Group *inGroup); +void Group_DeepFreeGraphs(Group *inGroup); +void Group_AddHead (Group *s, Node *child); +void Group_AddTail (Group *s, Node *child); +void Group_Insert(Group *s, Node *child, int inIndex); +void Group_SetControl(struct Group* inGroup, uint32 inIndex, float inValue); +void Group_SetControl(struct Group *inGroup, int32 inHash, int32 *inName, uint32 inIndex, float inValue); +void Group_MapControl(Group* inGroup, uint32 inIndex, uint32 inBus); +void Group_MapControl(Group* inGroup, int32 inHash, int32 *inName, uint32 inIndex, uint32 inBus); +void Group_Trace(Group* inGroup); + +//////////////////////////////////////////////////////////////////////// + +struct Unit* Unit_New(struct World *inWorld, struct UnitSpec *inUnitSpec, char*& memory); +void Unit_EndCalc(struct Unit *inUnit, int inNumSamples); +void Unit_End(struct Unit *inUnit); + +void Unit_Dtor(struct Unit *inUnit); + +extern "C" { +void Unit_ZeroOutputs(struct Unit *inUnit, int inNumSamples); +} + +//////////////////////////////////////////////////////////////////////// + +void SendDone(struct ReplyAddress *inReply, char *inCommandName); +void SendFailure(struct ReplyAddress *inReply, char *inCommandName, char *errString); +void ReportLateness(struct ReplyAddress *inReply, float32 seconds); +void DumpReplyAddress(struct ReplyAddress *inReplyAddress); +int32 Hash(struct ReplyAddress *inReplyAddress); + +//////////////////////////////////////////////////////////////////////// + +extern "C" { +int32 timeseed(); +} + +//////////////////////////////////////////////////////////////////////// + +typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData); +typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData); + +int PerformAsynchronousCommand + ( + World *inWorld, + void* replyAddr, + 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 + ); + +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/sc4pd/headers/server/SC_Reply.h b/sc4pd/headers/server/SC_Reply.h new file mode 100755 index 0000000..0400747 --- /dev/null +++ b/sc4pd/headers/server/SC_Reply.h @@ -0,0 +1,55 @@ +/* + 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 +*/ + + +#ifndef _SC_Msg_ +#define _SC_Msg_ + +#include <stdio.h> +#include <stdlib.h> +#ifdef SC_WIN32 +# include <winsock2.h> +#else +#include <netinet/in.h> +#endif +#include "sc_msg_iter.h" + +typedef void (*ReplyFunc)(struct ReplyAddress *inReplyAddr, char* inBuf, int inSize); + +void null_reply_func(struct ReplyAddress* addr, char* msg, int size); + +struct ReplyAddress +{ + struct sockaddr_in mSockAddr; + int mSockAddrLen; + int mSocket; + ReplyFunc mReplyFunc; +}; + +bool operator==(const ReplyAddress& a, const ReplyAddress& b); + +inline void SendReply(ReplyAddress *inReplyAddr, char* inBuf, int inSize) +{ + (inReplyAddr->mReplyFunc)(inReplyAddr, inBuf, inSize); +} + +#endif + + diff --git a/sc4pd/headers/server/SC_Samp.h b/sc4pd/headers/server/SC_Samp.h new file mode 100644 index 0000000..dde9159 --- /dev/null +++ b/sc4pd/headers/server/SC_Samp.h @@ -0,0 +1,38 @@ +/* + 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 +*/ + + +#ifndef _SC_Samp_ +#define _SC_Samp_ + +#include "SC_Types.h" + +const int kSineSize = 8192; +const int kSineMask = kSineSize - 1; + +extern float32 gSine[kSineSize+1]; +extern float32 gPMSine[kSineSize+1]; +extern float32 gInvSine[kSineSize+1]; +extern float32 gSineWavetable[2*kSineSize]; + +void SignalAsWavetable(float32* signal, float32* wavetable, long inSize); +void WavetableAsSignal(float32* wavetable, float32* signal, long inSize); + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/server/SC_SequencedCommand.h b/sc4pd/headers/server/SC_SequencedCommand.h new file mode 100644 index 0000000..d1a7fb5 --- /dev/null +++ b/sc4pd/headers/server/SC_SequencedCommand.h @@ -0,0 +1,481 @@ +/* + 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 <sndfile.h> +#include <new> + +#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 + diff --git a/sc4pd/headers/server/SC_Str4.h b/sc4pd/headers/server/SC_Str4.h new file mode 100644 index 0000000..306b823 --- /dev/null +++ b/sc4pd/headers/server/SC_Str4.h @@ -0,0 +1,103 @@ +/* + 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 +*/ + +/* a 4 byte aligned and zero padded string allows faster string operations. */ + +#ifndef _SC_Str4_ +#define _SC_Str4_ + +#include "Hash.h" +#include <stdio.h> +#include <limits.h> + +#ifndef _LASTCHAR_ +#define _LASTCHAR_ +#if BYTE_ORDER == LITTLE_ENDIAN +const int32 kLASTCHAR = 0xFF000000; +#else +const int32 kLASTCHAR = 0x000000FF; +#endif +#endif + + +void str4cpy(int32 *dst, const char *src); +void mem4cpy(int32 *dst, const char *src, int charlen); + +// returns the number of pad bytes to add to a string of a given length +inline int str4padbytes(int charlen) +{ + return 4 - (charlen & 3); +} + +// converts length in bytes to length in words +inline int str4len(int charlen) +{ + return (charlen + 4) >> 2; +} + +// returns length in words of a char * +inline int str4len(const char *src) +{ + const char *src0 = src; + while (*src) { src++; } + return str4len(src - src0); +} + +// returns length in words of a int32 * +inline int str4len(const int32 *src) +{ + const int32 *src0 = src; + while (*src++ & kLASTCHAR) {} + int wordlen = src - src0; + return wordlen; +} + +// returns length in words of a int32 * +inline bool str4eq(const int32 *a, const int32 *b) +{ + while(true) { + if (*a != *b) return false; + if ((*a & kLASTCHAR) == 0) return true; + a++; b++; + } +} + +// copy an int32 * +inline void str4cpy(int32 *dst, const int32 *src) +{ + int32 c; + do { + *dst++ = c = *src++; + } while (c & kLASTCHAR); +} + +inline int sc_atoi(char *string) +{ + int value = 0; + if (*string == 0) return -1; + uint32 c; + while ((c = *string++ - '0') <= 9) { + value = value * 10 + c; + } + return value; +} + + +#endif diff --git a/sc4pd/headers/server/SC_SyncCondition.h b/sc4pd/headers/server/SC_SyncCondition.h new file mode 100755 index 0000000..a75fbaa --- /dev/null +++ b/sc4pd/headers/server/SC_SyncCondition.h @@ -0,0 +1,45 @@ +/* + 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 +*/ + + +#ifndef _SC_SyncCondition_ +#define _SC_SyncCondition_ + +#include <pthread.h> + +class SC_SyncCondition +{ +public: + SC_SyncCondition(); + ~SC_SyncCondition(); + + void WaitEach(); + void WaitOnce(); + void WaitNext(); + void Signal(); + +private: + pthread_cond_t available; + pthread_mutex_t mutex; + int read, write; +}; + +#endif + diff --git a/sc4pd/headers/server/SC_SynthDef.h b/sc4pd/headers/server/SC_SynthDef.h new file mode 100644 index 0000000..89d5e47 --- /dev/null +++ b/sc4pd/headers/server/SC_SynthDef.h @@ -0,0 +1,43 @@ +/* + 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 +*/ + +#ifndef _SynthDef_ +#define _SynthDef_ + +#include "SC_Types.h" +#include "sc_msg_iter.h" + +typedef void (*NodeDtorFunc)(struct Node* inNode); + +struct NodeDef +{ + int32 mName[kSCNameLen]; + int32 mHash; + + size_t mAllocSize; +}; +typedef struct NodeDef NodeDef; + +extern NodeDef gGroupNodeDef; + +void GroupNodeDef_Init(); +void NodeDef_Dump(NodeDef *inNodeDef); + +#endif diff --git a/sc4pd/headers/server/SC_UnitDef.h b/sc4pd/headers/server/SC_UnitDef.h new file mode 100644 index 0000000..0f75490 --- /dev/null +++ b/sc4pd/headers/server/SC_UnitDef.h @@ -0,0 +1,69 @@ +/* + 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 +*/ + +#ifndef _UnitDef_ +#define _UnitDef_ + +#include "SC_Types.h" +#include "SC_Unit.h" +#include "HashTable.h" + +struct PlugInCmd +{ + int32 mCmdName[kSCNameLen]; + int32 mHash; + PlugInCmdFunc mFunc; + void *mUserData; +}; + +struct UnitCmd +{ + int32 mCmdName[kSCNameLen]; + int32 mHash; + UnitCmdFunc mFunc; +}; + +struct UnitDef +{ + int32 mUnitDefName[kSCNameLen]; + int32 mHash; + + size_t mAllocSize; + UnitCtorFunc mUnitCtorFunc; + UnitDtorFunc mUnitDtorFunc; + + HashTable<UnitCmd, Malloc>* mCmds; + uint32 mFlags; +}; + +extern "C" { +bool UnitDef_Create(char *inName, size_t inAllocSize, + UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags); +bool UnitDef_AddCmd(char *inUnitDefName, char *inCmdName, UnitCmdFunc inFunc); +bool PlugIn_DefineCmd(char *inCmdName, PlugInCmdFunc inFunc, void *inUserData); +} + +int Unit_DoCmd(World *inWorld, int inSize, char *inData); + +inline int32* GetKey(UnitCmd *inCmd) { return inCmd->mCmdName; } +inline int32 GetHash(UnitCmd *inCmd) { return inCmd->mHash; } + + +#endif diff --git a/sc4pd/headers/server/SC_UnitSpec.h b/sc4pd/headers/server/SC_UnitSpec.h new file mode 100644 index 0000000..c72e103 --- /dev/null +++ b/sc4pd/headers/server/SC_UnitSpec.h @@ -0,0 +1,41 @@ +/* + 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 +*/ + +#ifndef _SC_UnitSpec_ +#define _SC_UnitSpec_ + +#include <ctype.h> // for size_t + +#include "SC_Unit.h" + +struct UnitSpec +{ + struct UnitDef* mUnitDef; + int16 mCalcRate; + uint16 mNumInputs, mNumOutputs; + int16 mSpecialIndex; + struct InputSpec* mInputSpec; + struct OutputSpec* mOutputSpec; + struct Rate* mRateInfo; + size_t mAllocSize; +}; +typedef struct UnitSpec UnitSpec; + +#endif diff --git a/sc4pd/headers/server/SC_WireSpec.h b/sc4pd/headers/server/SC_WireSpec.h new file mode 100644 index 0000000..33ea15c --- /dev/null +++ b/sc4pd/headers/server/SC_WireSpec.h @@ -0,0 +1,47 @@ +/* + 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 +*/ + +#ifndef _SC_WireSpec_ +#define _SC_WireSpec_ + +#include "SC_Types.h" + +struct InputSpec +{ + // read from file: + int16 mFromUnitIndex; + int16 mFromOutputIndex; + // computed: + int16 mWireIndex; +}; +typedef struct InputSpec InputSpec; + +struct OutputSpec +{ + // read from file: + int16 mCalcRate; + // computed: + int16 mWireIndex; + int16 mBufferIndex; + int16 mNumConsumers; +}; +typedef struct OutputSpec OutputSpec; + +#endif |