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