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