Mercurial > hg > apm2s
comparison stk/include/Stk.h @ 0:4606bd505630 tip
first import
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Sat, 13 Jun 2015 15:08:10 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4606bd505630 |
---|---|
1 #ifndef STK_STK_H | |
2 #define STK_STK_H | |
3 | |
4 #include <string> | |
5 #include <cstring> | |
6 #include <iostream> | |
7 #include <sstream> | |
8 #include <vector> | |
9 //#include <cstdlib> | |
10 | |
11 /*! \namespace stk | |
12 \brief The STK namespace. | |
13 | |
14 Most Stk classes are defined within the STK namespace. Exceptions | |
15 to this include the classes RtAudio and RtMidi. | |
16 */ | |
17 namespace stk { | |
18 | |
19 /***************************************************/ | |
20 /*! \class Stk | |
21 \brief STK base class | |
22 | |
23 Nearly all STK classes inherit from this class. | |
24 The global sample rate and rawwave path variables | |
25 can be queried and modified via Stk. In addition, | |
26 this class provides error handling and | |
27 byte-swapping functions. | |
28 | |
29 The Synthesis ToolKit in C++ (STK) is a set of open source audio | |
30 signal processing and algorithmic synthesis classes written in the | |
31 C++ programming language. STK was designed to facilitate rapid | |
32 development of music synthesis and audio processing software, with | |
33 an emphasis on cross-platform functionality, realtime control, | |
34 ease of use, and educational example code. STK currently runs | |
35 with realtime support (audio and MIDI) on Linux, Macintosh OS X, | |
36 and Windows computer platforms. Generic, non-realtime support has | |
37 been tested under NeXTStep, Sun, and other platforms and should | |
38 work with any standard C++ compiler. | |
39 | |
40 STK WWW site: http://ccrma.stanford.edu/software/stk/ | |
41 | |
42 The Synthesis ToolKit in C++ (STK) | |
43 Copyright (c) 1995--2014 Perry R. Cook and Gary P. Scavone | |
44 | |
45 Permission is hereby granted, free of charge, to any person | |
46 obtaining a copy of this software and associated documentation files | |
47 (the "Software"), to deal in the Software without restriction, | |
48 including without limitation the rights to use, copy, modify, merge, | |
49 publish, distribute, sublicense, and/or sell copies of the Software, | |
50 and to permit persons to whom the Software is furnished to do so, | |
51 subject to the following conditions: | |
52 | |
53 The above copyright notice and this permission notice shall be | |
54 included in all copies or substantial portions of the Software. | |
55 | |
56 Any person wishing to distribute modifications to the Software is | |
57 asked to send the modifications to the original developer so that | |
58 they can be incorporated into the canonical version. This is, | |
59 however, not a binding provision of this license. | |
60 | |
61 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
62 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
63 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
64 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
65 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
66 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
67 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
68 */ | |
69 /***************************************************/ | |
70 | |
71 //#define _STK_DEBUG_ | |
72 | |
73 // Most data in STK is passed and calculated with the | |
74 // following user-definable floating-point type. You | |
75 // can change this to "float" if you prefer or perhaps | |
76 // a "long double" in the future. | |
77 typedef double StkFloat; | |
78 | |
79 //! STK error handling class. | |
80 /*! | |
81 This is a fairly abstract exception handling class. There could | |
82 be sub-classes to take care of more specific error conditions ... or | |
83 not. | |
84 */ | |
85 class StkError | |
86 { | |
87 public: | |
88 enum Type { | |
89 STATUS, | |
90 WARNING, | |
91 DEBUG_PRINT, | |
92 MEMORY_ALLOCATION, | |
93 MEMORY_ACCESS, | |
94 FUNCTION_ARGUMENT, | |
95 FILE_NOT_FOUND, | |
96 FILE_UNKNOWN_FORMAT, | |
97 FILE_ERROR, | |
98 PROCESS_THREAD, | |
99 PROCESS_SOCKET, | |
100 PROCESS_SOCKET_IPADDR, | |
101 AUDIO_SYSTEM, | |
102 MIDI_SYSTEM, | |
103 UNSPECIFIED | |
104 }; | |
105 | |
106 protected: | |
107 std::string message_; | |
108 Type type_; | |
109 | |
110 public: | |
111 //! The constructor. | |
112 StkError(const std::string& message, Type type = StkError::UNSPECIFIED) | |
113 : message_(message), type_(type) {} | |
114 | |
115 //! The destructor. | |
116 virtual ~StkError(void) {}; | |
117 | |
118 //! Prints thrown error message to stderr. | |
119 virtual void printMessage(void) { std::cerr << '\n' << message_ << "\n\n"; } | |
120 | |
121 //! Returns the thrown error message type. | |
122 virtual const Type& getType(void) { return type_; } | |
123 | |
124 //! Returns the thrown error message string. | |
125 virtual const std::string& getMessage(void) { return message_; } | |
126 | |
127 //! Returns the thrown error message as a C string. | |
128 virtual const char *getMessageCString(void) { return message_.c_str(); } | |
129 }; | |
130 | |
131 | |
132 class Stk | |
133 { | |
134 public: | |
135 | |
136 typedef unsigned long StkFormat; | |
137 static const StkFormat STK_SINT8; /*!< -128 to +127 */ | |
138 static const StkFormat STK_SINT16; /*!< -32768 to +32767 */ | |
139 static const StkFormat STK_SINT24; /*!< Lower 3 bytes of 32-bit signed integer. */ | |
140 static const StkFormat STK_SINT32; /*!< -2147483648 to +2147483647. */ | |
141 static const StkFormat STK_FLOAT32; /*!< Normalized between plus/minus 1.0. */ | |
142 static const StkFormat STK_FLOAT64; /*!< Normalized between plus/minus 1.0. */ | |
143 | |
144 //! Static method that returns the current STK sample rate. | |
145 static StkFloat sampleRate( void ) { return srate_; } | |
146 | |
147 //! Static method that sets the STK sample rate. | |
148 /*! | |
149 The sample rate set using this method is queried by all STK | |
150 classes that depend on its value. It is initialized to the | |
151 default SRATE set in Stk.h. Many STK classes use the sample rate | |
152 during instantiation. Therefore, if you wish to use a rate that | |
153 is different from the default rate, it is imperative that it be | |
154 set \e BEFORE STK objects are instantiated. A few classes that | |
155 make use of the global STK sample rate are automatically notified | |
156 when the rate changes so that internal class data can be | |
157 appropriately updated. However, this has not been fully | |
158 implemented. Specifically, classes that appropriately update | |
159 their own data when either a setFrequency() or noteOn() function | |
160 is called do not currently receive the automatic notification of | |
161 rate change. If the user wants a specific class instance to | |
162 ignore such notifications, perhaps in a multi-rate context, the | |
163 function Stk::ignoreSampleRateChange() should be called. | |
164 */ | |
165 static void setSampleRate( StkFloat rate ); | |
166 | |
167 //! A function to enable/disable the automatic updating of class data when the STK sample rate changes. | |
168 /*! | |
169 This function allows the user to enable or disable class data | |
170 updates in response to global sample rate changes on a class by | |
171 class basis. | |
172 */ | |
173 void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; }; | |
174 | |
175 //! Static method that returns the current rawwave path. | |
176 static std::string rawwavePath(void) { return rawwavepath_; } | |
177 | |
178 //! Static method that sets the STK rawwave path. | |
179 static void setRawwavePath( std::string path ); | |
180 | |
181 //! Static method that byte-swaps a 16-bit data type. | |
182 static void swap16( unsigned char *ptr ); | |
183 | |
184 //! Static method that byte-swaps a 32-bit data type. | |
185 static void swap32( unsigned char *ptr ); | |
186 | |
187 //! Static method that byte-swaps a 64-bit data type. | |
188 static void swap64( unsigned char *ptr ); | |
189 | |
190 //! Static cross-platform method to sleep for a number of milliseconds. | |
191 static void sleep( unsigned long milliseconds ); | |
192 | |
193 //! Static method to check whether a value is within a specified range. | |
194 static bool inRange( StkFloat value, StkFloat min, StkFloat max ) { | |
195 if ( value < min ) return false; | |
196 else if ( value > max ) return false; | |
197 else return true; | |
198 } | |
199 | |
200 //! Static function for error reporting and handling using c-strings. | |
201 static void handleError( const char *message, StkError::Type type ); | |
202 | |
203 //! Static function for error reporting and handling using c++ strings. | |
204 static void handleError( std::string message, StkError::Type type ); | |
205 | |
206 //! Toggle display of WARNING and STATUS messages. | |
207 static void showWarnings( bool status ) { showWarnings_ = status; } | |
208 | |
209 //! Toggle display of error messages before throwing exceptions. | |
210 static void printErrors( bool status ) { printErrors_ = status; } | |
211 | |
212 private: | |
213 static StkFloat srate_; | |
214 static std::string rawwavepath_; | |
215 static bool showWarnings_; | |
216 static bool printErrors_; | |
217 static std::vector<Stk *> alertList_; | |
218 | |
219 protected: | |
220 | |
221 static std::ostringstream oStream_; | |
222 bool ignoreSampleRateChange_; | |
223 | |
224 //! Default constructor. | |
225 Stk( void ); | |
226 | |
227 //! Class destructor. | |
228 virtual ~Stk( void ); | |
229 | |
230 //! This function should be implemented in subclasses that depend on the sample rate. | |
231 virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate ); | |
232 | |
233 //! Add class pointer to list for sample rate change notification. | |
234 void addSampleRateAlert( Stk *ptr ); | |
235 | |
236 //! Remove class pointer from list for sample rate change notification. | |
237 void removeSampleRateAlert( Stk *ptr ); | |
238 | |
239 //! Internal function for error reporting that assumes message in \c oStream_ variable. | |
240 void handleError( StkError::Type type ) const; | |
241 }; | |
242 | |
243 | |
244 /***************************************************/ | |
245 /*! \class StkFrames | |
246 \brief An STK class to handle vectorized audio data. | |
247 | |
248 This class can hold single- or multi-channel audio data. The data | |
249 type is always StkFloat and the channel format is always | |
250 interleaved. In an effort to maintain efficiency, no | |
251 out-of-bounds checks are performed in this class unless | |
252 _STK_DEBUG_ is defined. | |
253 | |
254 Internally, the data is stored in a one-dimensional C array. An | |
255 indexing operator is available to set and retrieve data values. | |
256 Alternately, one can use pointers to access the data, using the | |
257 index operator to get an address for a particular location in the | |
258 data: | |
259 | |
260 StkFloat* ptr = &myStkFrames[0]; | |
261 | |
262 Note that this class can also be used as a table with interpolating | |
263 lookup. | |
264 | |
265 Possible future improvements in this class could include functions | |
266 to convert to and return other data types. | |
267 | |
268 by Perry R. Cook and Gary P. Scavone, 1995--2014. | |
269 */ | |
270 /***************************************************/ | |
271 | |
272 class StkFrames | |
273 { | |
274 public: | |
275 | |
276 //! The default constructor initializes the frame data structure to size zero. | |
277 StkFrames( unsigned int nFrames = 0, unsigned int nChannels = 0 ); | |
278 | |
279 //! Overloaded constructor that initializes the frame data to the specified size with \c value. | |
280 StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels ); | |
281 | |
282 //! The destructor. | |
283 ~StkFrames(); | |
284 | |
285 // A copy constructor. | |
286 StkFrames( const StkFrames& f ); | |
287 | |
288 // Assignment operator that returns a reference to self. | |
289 StkFrames& operator= ( const StkFrames& f ); | |
290 | |
291 //! Subscript operator that returns a reference to element \c n of self. | |
292 /*! | |
293 The result can be used as an lvalue. This reference is valid | |
294 until the resize function is called or the array is destroyed. The | |
295 index \c n must be between 0 and size less one. No range checking | |
296 is performed unless _STK_DEBUG_ is defined. | |
297 */ | |
298 StkFloat& operator[] ( size_t n ); | |
299 | |
300 //! Subscript operator that returns the value at element \c n of self. | |
301 /*! | |
302 The index \c n must be between 0 and size less one. No range | |
303 checking is performed unless _STK_DEBUG_ is defined. | |
304 */ | |
305 StkFloat operator[] ( size_t n ) const; | |
306 | |
307 //! Assignment by sum operator into self. | |
308 /*! | |
309 The dimensions of the argument are expected to be the same as | |
310 self. No range checking is performed unless _STK_DEBUG_ is | |
311 defined. | |
312 */ | |
313 void operator+= ( StkFrames& f ); | |
314 | |
315 //! Assignment by product operator into self. | |
316 /*! | |
317 The dimensions of the argument are expected to be the same as | |
318 self. No range checking is performed unless _STK_DEBUG_ is | |
319 defined. | |
320 */ | |
321 void operator*= ( StkFrames& f ); | |
322 | |
323 //! Channel / frame subscript operator that returns a reference. | |
324 /*! | |
325 The result can be used as an lvalue. This reference is valid | |
326 until the resize function is called or the array is destroyed. The | |
327 \c frame index must be between 0 and frames() - 1. The \c channel | |
328 index must be between 0 and channels() - 1. No range checking is | |
329 performed unless _STK_DEBUG_ is defined. | |
330 */ | |
331 StkFloat& operator() ( size_t frame, unsigned int channel ); | |
332 | |
333 //! Channel / frame subscript operator that returns a value. | |
334 /*! | |
335 The \c frame index must be between 0 and frames() - 1. The \c | |
336 channel index must be between 0 and channels() - 1. No range checking | |
337 is performed unless _STK_DEBUG_ is defined. | |
338 */ | |
339 StkFloat operator() ( size_t frame, unsigned int channel ) const; | |
340 | |
341 //! Return an interpolated value at the fractional frame index and channel. | |
342 /*! | |
343 This function performs linear interpolation. The \c frame | |
344 index must be between 0.0 and frames() - 1. The \c channel index | |
345 must be between 0 and channels() - 1. No range checking is | |
346 performed unless _STK_DEBUG_ is defined. | |
347 */ | |
348 StkFloat interpolate( StkFloat frame, unsigned int channel = 0 ) const; | |
349 | |
350 //! Returns the total number of audio samples represented by the object. | |
351 size_t size() const { return size_; }; | |
352 | |
353 //! Returns \e true if the object size is zero and \e false otherwise. | |
354 bool empty() const; | |
355 | |
356 //! Resize self to represent the specified number of channels and frames. | |
357 /*! | |
358 Changes the size of self based on the number of frames and | |
359 channels. No element assignment is performed. No memory | |
360 deallocation occurs if the new size is smaller than the previous | |
361 size. Further, no new memory is allocated when the new size is | |
362 smaller or equal to a previously allocated size. | |
363 */ | |
364 void resize( size_t nFrames, unsigned int nChannels = 1 ); | |
365 | |
366 //! Resize self to represent the specified number of channels and frames and perform element initialization. | |
367 /*! | |
368 Changes the size of self based on the number of frames and | |
369 channels, and assigns \c value to every element. No memory | |
370 deallocation occurs if the new size is smaller than the previous | |
371 size. Further, no new memory is allocated when the new size is | |
372 smaller or equal to a previously allocated size. | |
373 */ | |
374 void resize( size_t nFrames, unsigned int nChannels, StkFloat value ); | |
375 | |
376 //! Return the number of channels represented by the data. | |
377 unsigned int channels( void ) const { return nChannels_; }; | |
378 | |
379 //! Return the number of sample frames represented by the data. | |
380 unsigned int frames( void ) const { return (unsigned int)nFrames_; }; | |
381 | |
382 //! Set the sample rate associated with the StkFrames data. | |
383 /*! | |
384 By default, this value is set equal to the current STK sample | |
385 rate at the time of instantiation. | |
386 */ | |
387 void setDataRate( StkFloat rate ) { dataRate_ = rate; }; | |
388 | |
389 //! Return the sample rate associated with the StkFrames data. | |
390 /*! | |
391 By default, this value is set equal to the current STK sample | |
392 rate at the time of instantiation. | |
393 */ | |
394 StkFloat dataRate( void ) const { return dataRate_; }; | |
395 | |
396 private: | |
397 | |
398 StkFloat *data_; | |
399 StkFloat dataRate_; | |
400 size_t nFrames_; | |
401 unsigned int nChannels_; | |
402 size_t size_; | |
403 size_t bufferSize_; | |
404 | |
405 }; | |
406 | |
407 inline bool StkFrames :: empty() const | |
408 { | |
409 if ( size_ > 0 ) return false; | |
410 else return true; | |
411 } | |
412 | |
413 inline StkFloat& StkFrames :: operator[] ( size_t n ) | |
414 { | |
415 #if defined(_STK_DEBUG_) | |
416 if ( n >= size_ ) { | |
417 std::ostringstream error; | |
418 error << "StkFrames::operator[]: invalid index (" << n << ") value!"; | |
419 Stk::handleError( error.str(), StkError::MEMORY_ACCESS ); | |
420 } | |
421 #endif | |
422 | |
423 return data_[n]; | |
424 } | |
425 | |
426 inline StkFloat StkFrames :: operator[] ( size_t n ) const | |
427 { | |
428 #if defined(_STK_DEBUG_) | |
429 if ( n >= size_ ) { | |
430 std::ostringstream error; | |
431 error << "StkFrames::operator[]: invalid index (" << n << ") value!"; | |
432 Stk::handleError( error.str(), StkError::MEMORY_ACCESS ); | |
433 } | |
434 #endif | |
435 | |
436 return data_[n]; | |
437 } | |
438 | |
439 inline StkFloat& StkFrames :: operator() ( size_t frame, unsigned int channel ) | |
440 { | |
441 #if defined(_STK_DEBUG_) | |
442 if ( frame >= nFrames_ || channel >= nChannels_ ) { | |
443 std::ostringstream error; | |
444 error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!"; | |
445 Stk::handleError( error.str(), StkError::MEMORY_ACCESS ); | |
446 } | |
447 #endif | |
448 | |
449 return data_[ frame * nChannels_ + channel ]; | |
450 } | |
451 | |
452 inline StkFloat StkFrames :: operator() ( size_t frame, unsigned int channel ) const | |
453 { | |
454 #if defined(_STK_DEBUG_) | |
455 if ( frame >= nFrames_ || channel >= nChannels_ ) { | |
456 std::ostringstream error; | |
457 error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!"; | |
458 Stk::handleError( error.str(), StkError::MEMORY_ACCESS ); | |
459 } | |
460 #endif | |
461 | |
462 return data_[ frame * nChannels_ + channel ]; | |
463 } | |
464 | |
465 inline void StkFrames :: operator+= ( StkFrames& f ) | |
466 { | |
467 #if defined(_STK_DEBUG_) | |
468 if ( f.frames() != nFrames_ || f.channels() != nChannels_ ) { | |
469 std::ostringstream error; | |
470 error << "StkFrames::operator+=: frames argument must be of equal dimensions!"; | |
471 Stk::handleError( error.str(), StkError::MEMORY_ACCESS ); | |
472 } | |
473 #endif | |
474 | |
475 StkFloat *fptr = &f[0]; | |
476 StkFloat *dptr = data_; | |
477 for ( unsigned int i=0; i<size_; i++ ) | |
478 *dptr++ += *fptr++; | |
479 } | |
480 | |
481 inline void StkFrames :: operator*= ( StkFrames& f ) | |
482 { | |
483 #if defined(_STK_DEBUG_) | |
484 if ( f.frames() != nFrames_ || f.channels() != nChannels_ ) { | |
485 std::ostringstream error; | |
486 error << "StkFrames::operator*=: frames argument must be of equal dimensions!"; | |
487 Stk::handleError( error.str(), StkError::MEMORY_ACCESS ); | |
488 } | |
489 #endif | |
490 | |
491 StkFloat *fptr = &f[0]; | |
492 StkFloat *dptr = data_; | |
493 for ( unsigned int i=0; i<size_; i++ ) | |
494 *dptr++ *= *fptr++; | |
495 } | |
496 | |
497 // Here are a few other useful typedefs. | |
498 typedef unsigned short UINT16; | |
499 typedef unsigned int UINT32; | |
500 typedef signed short SINT16; | |
501 typedef signed int SINT32; | |
502 typedef float FLOAT32; | |
503 typedef double FLOAT64; | |
504 | |
505 // The default sampling rate. | |
506 const StkFloat SRATE = 44100.0; | |
507 | |
508 // The default real-time audio input and output buffer size. If | |
509 // clicks are occuring in the input and/or output sound stream, a | |
510 // larger buffer size may help. Larger buffer sizes, however, produce | |
511 // more latency. | |
512 const unsigned int RT_BUFFER_SIZE = 512; | |
513 | |
514 // The default rawwave path value is set with the preprocessor | |
515 // definition RAWWAVE_PATH. This can be specified as an argument to | |
516 // the configure script, in an integrated development environment, or | |
517 // below. The global STK rawwave path variable can be dynamically set | |
518 // with the Stk::setRawwavePath() function. This value is | |
519 // concatenated to the beginning of all references to rawwave files in | |
520 // the various STK core classes (ex. Clarinet.cpp). If you wish to | |
521 // move the rawwaves directory to a different location in your file | |
522 // system, you will need to set this path definition appropriately. | |
523 #if !defined(RAWWAVE_PATH) | |
524 #define RAWWAVE_PATH "../../rawwaves/" | |
525 #endif | |
526 | |
527 #ifndef PI | |
528 const StkFloat PI = 3.14159265358979; | |
529 #endif | |
530 const StkFloat TWO_PI = 2 * PI; | |
531 const StkFloat ONE_OVER_128 = 0.0078125; | |
532 | |
533 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_MM__) | |
534 #define __OS_WINDOWS__ | |
535 #define __STK_REALTIME__ | |
536 #elif defined(__LINUX_OSS__) || defined(__LINUX_ALSA__) || defined(__UNIX_JACK__) | |
537 #define __OS_LINUX__ | |
538 #define __STK_REALTIME__ | |
539 #elif defined(__IRIX_AL__) | |
540 #define __OS_IRIX__ | |
541 #elif defined(__MACOSX_CORE__) || defined(__UNIX_JACK__) | |
542 #define __OS_MACOSX__ | |
543 #define __STK_REALTIME__ | |
544 #endif | |
545 | |
546 } // stk namespace | |
547 | |
548 #endif |