CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

CGestalt.h
Go to the documentation of this file.
1 ///
2 /// CGestalt.h -- the CSL 5.0 CGestalt (system utility) class specification,
3 /// system constants, logging, and utility methods; SAFE_MALLOC/SAFE_FREE macros
4 /// The logging system has a number of print methods that use the printf var-args format
5 /// and can be filtered on verbosity.
6 /// There's a variety of random-number functions.
7 /// The timer sleep methods are interruptable with a global flag.
8 ///
9 /// The MVC Observer/Subject or dependency pattern classes are also here.
10 ///
11 /// See the copyright notice and acknowledgment of authors in the file COPYRIGHT
12 ///
13
14 #ifndef CSL_Gestalt_H
15 #define CSL_Gestalt_H
16
17 #include "CSL_Types.h" // The system default values are defined there
18
19 #include <stdarg.h> // for va_arg, vaList, etc.
20 #include <string>
21
22 #ifdef USE_JUCE
23 #include "../JuceLibraryCode/JuceHeader.h"
24 using namespace juce;
25 #else
26 #include <sys/time.h>
27 #endif
28
29 namespace csl {
30
31 ///
32 /// The CSL system defaults class
33 ///
34
35 class CGestalt {
36
37 public: // Accessor (getter/setter) methods
38
39 static unsigned frameRate(); ///< default frame rate
40 static void setFrameRate(unsigned frameRate);
41 static sample framePeriod(); ///< default frame rate
42
43 static unsigned numInChannels(); ///< default number of input channels
44 static void setNumInChannels(unsigned numChannels);
45
46 static unsigned numOutChannels(); ///< default number of output channels
47 static void setNumOutChannels(unsigned numChannels);
48
49 static unsigned blockSize(); ///< the default block size
50 static void setBlockSize(unsigned blockSize);
51
52 static unsigned maxBufferFrames(); ///< the max num frames that can be requested
53 static void setMaxBufferFrames(unsigned numFrames);
54
55 static unsigned maxSndFileFrames(); ///< the max num frames that can be cached
56 static void setMaxSndFileFrames(unsigned numFrames);
57
58 static unsigned sndFileFrames(); ///< the default num frames that are cached
59 static void setSndFileFrames(unsigned numFrames);
60
61 static unsigned verbosity(); ///< the default logging verbosity
62 static void setVerbosity(unsigned verbosity); // (0 = only fatal errors, 1 = warnings,
63 // 2 = most msgs, 3 = include info msgs)
64
65 static unsigned loggingPeriod(); ///< the default logging period
66 static void setLoggingPeriod(unsigned loggingPeriod);
67
68 static unsigned outPort(); ///< the default RemoteIO output port
69 static void setOutPort(unsigned outPort);
70
71 static std::string dataFolder(); ///< the default directory for test data
72 static void setDataFolder(std::string dFolder); ///< typ. "~/Code/CSL/CSL_Data/"
73
74 static bool stopNow(); ///< flag to stop threads and timers
75 static void setStopNow();
76 static void clearStopNow();
77
78 static std::string initFileText(char key); ///< read/write the init file (typ. ~/.cslrc)
79 static void storeToInitFile(char key, std::string data);
80
81 static std::string sndFileName(); ///< pick a new sound file name to use based on OUT_SFILE_NAME
82
83 };
84
85 /////////////////////////////////////////////////////////////////////////
86 ///
87 /// Useful Macros
88 ///
89
90 /// SAFE_MALLOC = safe malloc using new operator
91 /// used like: SAFE_MALLOC(mSampleBuffer, sample, mWindowSize);
92
93 #define SAFE_MALLOC(ptr, type, len) \
94 ptr = new type[len]; \
95 if ((char *) ptr == NULL) \
96 throw MemoryError("can't allocate buffer")
97
98 /// Matrix allocate
99 /// SAFE_MATMALLOC(mRealSpectrum, FloatArray, mNumFrames, float, mWinSize);
100 /// SAFE_MATMALLOC(mSpectBands, FloatArray, mNumFrames, float, NUM_BANDS)
101
102 #define SAFE_MATMALLOC(ptr, mtype, num, type, len) \
103 ptr = new mtype[num]; \
104 if ((char *) ptr == NULL) \
105 throw MemoryError("can't allocate buffer"); \
106 for (unsigned i = 0; i < num; i++) { \
107 ptr[i] = new type[len]; \
108 if ((char *) ptr[i] == NULL) \
109 throw MemoryError("can't allocate buffer"); \
110 }
111
112 /// Structure allocate
113 /// SAFE_STRUCTMALLOC(mRealSpectrum, FloatArray, mNumFrames, float);
114
115 #define SAFE_STRUCTMALLOC(ptr, mtype, num, type) \
116 ptr = new mtype[num]; \
117 if ((char *) ptr == NULL) \
118 throw MemoryError("can't allocate buffer"); \
119 for (unsigned i = 0; i < num; i++) { \
120 ptr[i] = new type; \
121 if ((char *) ptr[i] == NULL) \
122 throw MemoryError("can't allocate buffer"); \
123 }
124
125 // Safe free and matrix version
126
127 #define SAFE_FREE(ptr) \
128 if (ptr) \
129 delete[] ptr
130
131 #define SAFE_MATFREE(ptr, num) \
132 for (unsigned i = 0; i < num; i++) { \
133 if (ptr[i]) \
134 delete[] ptr[i]; \
135 } \
136 delete[] ptr
137
138 /////////////////////////////////////////////////////////////////////////
139 ///
140 /// Logging functions are standard C functions
141 ///
142
143 #ifdef CSL_ENUMS
144 typedef enum { ///< Enumeration for log message severity level
145 kLogInfo, ///< you can filter on this.
146 kLogWarning,
147 kLogError,
148 kLogFatal
149 } LogLevel;
150 #else
151 #define kLogInfo 0
152 #define kLogWarning 1
153 #define kLogError 2
154 #define kLogFatal 3
155 typedef int LogLevel;
156 #endif
157
158 ///
159 /// These are the public logging messages
160 ///
161
162 void logMsg(const char * format, ...); ///< default is kLogInfo severity
163 void logMsg(LogLevel level, const char* format, ...);
164
165 void logLine(); ///< Log the file & line #
166 void logURL(); ///< log file/line as a URL
167
168 // These two are private -- for handling var-args
169
170 void vlogMsg(const char * format, va_list args);
171 void vlogMsg(LogLevel level, const char * format, va_list args);
172
173 /////////////////////////////////////////////////////////////////////////
174 ///
175 /// Misc. global functions in the csl namespace
176 ///
177
178 /// Sleep for micro-seconds, milli-seconds or seconds
179 /// These are interruptable and return true if interrupted; false for normal termination
180
181 bool sleepUsec(float dur); ///< sleep for dur usec, msec or sec
182 bool sleepMsec(float dur);
183 bool sleepSec(float dur);
184
185 Timestamp timeNow(); ///< high-accuracy system or IO time in ticks
186 float fTimeNow(); ///< system or IO time in seconds
187
188 /// Which kind of accurate timer to use?
189
190 // #define C_TIME Time::getHighResolutionTicks()
191 #define C_TIME juce::Time::getMillisecondCounter()
192
193 ///
194 /// A variety of useful random-number functions
195 ///
196
197 float fRandZ(void); ///< 0 - 1 (name: zero)
198 float fRand1(void); ///< -1 - 1 (one)
199 float fRandV(float val); ///< 0 - v (val)
200
201 float fRandM(float minV, float maxV); ///< min - max (min/max)
202 float fRandR(float base, float range); ///< b +- (r * b) (range)
203 float fRandB(float base, float range); ///< b +- r (base)
204
205 /// Integer rands
206
207 int iRandV(int val); ///< 0 - v (val)
208 int iRandM(int minV, int maxV); ///< min - max (min/max)
209 int iRandB(int base, int range); ///< b +- r (base)
210
211 // Bool coin-toss rands
212
213 bool coin(); ///< Answer true or false
214 bool coin(float bias); ///< Answer with a bias (1 --> always true)
215
216
217 /// MIDI Conversions
218
219 /// keyToFreq -- converts from MIDI key numbers (1 - 127) to frequency in Hz.
220
221 float keyToFreq(unsigned midiKey);
222
223 /// freqToKey -- converts from frequency in Hz to MIDI key #
224
225 unsigned freqToKey(float frequency);
226
227
228 /////////////////////////////////////////////////////////////////////////
229 ///
230 /// MVC Observer/Subject or dependency pattern
231 /// Advanced version with filtered observer updates
232 ///
233
234 class Observer; ///< Forward declaration
235 typedef std::vector <Observer *> ObserverVector;
236
237 ///
238 /// The Model/Observable/Subject class; instances of its subclasses should send themselves,
239 /// this->changed(some_data);
240 /// on "relevant" state changes; the code they inherit (from Model) manages updating the list
241 /// of observer/dependent objects in that they each receive
242 /// update(some_data);
243 /// and can access the model-passed data (the model might pass "this").
244 ///
245 /// Note the addition of timers, so observers can request no more than a certain rate of updates.
246
247 class Model {
248 public:
249 Model() : mHasObservers(false), mHasObserverMap(false), mUpdateTime(0), mPeriod(0) { }; ///< constructor
250 virtual ~Model() { /* no-op */ }; ///< (possibly notify obersvers on my death)
251
252 void attachObserver(Observer *); ///< register/remove observers
253 void detachObserver(Observer *);
254
255 void changed(void * argument); ///< this is what I send to myself to notify my observers;
256 /// It's not overridden in general.
257 /// It results in the observers receiving update() calls
258 ///< override evaluate to filter updates to the observer map
259 virtual int evaluate(void * argument) { return 0; };
260
261 private:
262 ObserverVector mObservers; ///< the private vector of observers
263 std::map<int, ObserverVector> mObsMap; ///< the private map-by-key of observers
264 bool mHasObservers; ///< whether there are any observers (for fast checking)
265 bool mHasObserverMap; ///< whether there are any observers (for fast checking)
266 float mUpdateTime; ///< when I last updated
267 float mPeriod; ///< update rate in sec
268 };
269
270 ///
271 /// CSL Observer/Dependent/Monitor class -- instances receive update() messages from "models"
272 /// and handle some argument, which may be the model's "this" pointer, or any other data.
273 ///
274 /// Subclasses must override the update() method to do their stuff -- grabbing a data buffer,
275 /// operating on their model, or displaying something.
276 /// The mPeriod is the requested period for updates.
277 /// The mKey is an int value for the model's evaluate() function to filter updates
278 /// i.e., if the model implements evaluate(void*), and its return value is non-zero and
279 /// matches the observer's key, then an update will be sent. An example of using this is
280 /// a MIDI IO object's channel filtering for MIDI listeners (observers).
281 ///
282
283 class Observer {
284 public:
285 Observer() { mPeriod = 0; mKey = 0; }; ///< constructor
286 virtual ~Observer() { }; ///< virtual destructor (don't notify or delete
287 /// observers in this version)
288 float mPeriod; ///< max update rate
289 int mKey; ///< key selector (e.g., MIDI chan)
290 /// I receive update() mesages from my model;
291 virtual void update(void * arg) = 0; ///< this will be implemented in subclasses.
292 };
293
294 } // end of namespace
295
296 #endif