diff stk/src/Stk.cpp @ 0:4606bd505630 tip

first import
author Fiore Martin <f.martin@qmul.ac.uk>
date Sat, 13 Jun 2015 15:08:10 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/Stk.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,340 @@
+/***************************************************/
+/*! \class Stk
+    \brief STK base class
+
+    Nearly all STK classes inherit from this class.
+    The global sample rate can be queried and
+    modified via Stk.  In addition, this class
+    provides error handling and byte-swapping
+    functions.
+
+    The Synthesis ToolKit in C++ (STK) is a set of open source audio
+    signal processing and algorithmic synthesis classes written in the
+    C++ programming language. STK was designed to facilitate rapid
+    development of music synthesis and audio processing software, with
+    an emphasis on cross-platform functionality, realtime control,
+    ease of use, and educational example code.  STK currently runs
+    with realtime support (audio and MIDI) on Linux, Macintosh OS X,
+    and Windows computer platforms. Generic, non-realtime support has
+    been tested under NeXTStep, Sun, and other platforms and should
+    work with any standard C++ compiler.
+
+    STK WWW site: http://ccrma.stanford.edu/software/stk/
+
+    The Synthesis ToolKit in C++ (STK)
+    Copyright (c) 1995--2014 Perry R. Cook and Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/***************************************************/
+
+#include "../include/Stk.h"
+#include <stdlib.h>
+
+namespace stk {
+
+StkFloat Stk :: srate_ = (StkFloat) SRATE;
+std::string Stk :: rawwavepath_ = RAWWAVE_PATH;
+const Stk::StkFormat Stk :: STK_SINT8   = 0x1;
+const Stk::StkFormat Stk :: STK_SINT16  = 0x2;
+const Stk::StkFormat Stk :: STK_SINT24  = 0x4;
+const Stk::StkFormat Stk :: STK_SINT32  = 0x8;
+const Stk::StkFormat Stk :: STK_FLOAT32 = 0x10;
+const Stk::StkFormat Stk :: STK_FLOAT64 = 0x20;
+bool Stk :: showWarnings_ = true;
+bool Stk :: printErrors_ = true;
+std::vector<Stk *> Stk :: alertList_;
+std::ostringstream Stk :: oStream_;
+
+Stk :: Stk( void )
+  : ignoreSampleRateChange_(false)
+{
+}
+
+Stk :: ~Stk( void )
+{
+}
+
+void Stk :: setSampleRate( StkFloat rate )
+{
+  if ( rate > 0.0 && rate != srate_ ) {
+    StkFloat oldRate = srate_;
+    srate_ = rate;
+
+    for ( unsigned int i=0; i<alertList_.size(); i++ )
+      alertList_[i]->sampleRateChanged( srate_, oldRate );
+  }
+}
+
+void Stk :: sampleRateChanged( StkFloat /*newRate*/, StkFloat /*oldRate*/ )
+{
+  // This function should be reimplemented in classes that need to
+  // make internal variable adjustments in response to a global sample
+  // rate change.
+}
+
+void Stk :: addSampleRateAlert( Stk *ptr )
+{
+  for ( unsigned int i=0; i<alertList_.size(); i++ )
+    if ( alertList_[i] == ptr ) return;
+
+  alertList_.push_back( ptr );
+}
+
+void Stk :: removeSampleRateAlert( Stk *ptr )
+{
+  for ( unsigned int i=0; i<alertList_.size(); i++ ) {
+    if ( alertList_[i] == ptr ) {
+      alertList_.erase( alertList_.begin() + i );
+      return;
+    }
+  }
+}
+
+void Stk :: setRawwavePath( std::string path )
+{
+  if ( !path.empty() )
+    rawwavepath_ = path;
+
+  // Make sure the path includes a "/"
+  if ( rawwavepath_[rawwavepath_.length()-1] != '/' )
+    rawwavepath_ += "/";
+}
+
+void Stk :: swap16(unsigned char *ptr)
+{
+  unsigned char val;
+
+  // Swap 1st and 2nd bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+void Stk :: swap32(unsigned char *ptr)
+{
+  unsigned char val;
+
+  // Swap 1st and 4th bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+3);
+  *(ptr+3) = val;
+
+  //Swap 2nd and 3rd bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+void Stk :: swap64(unsigned char *ptr)
+{
+  unsigned char val;
+
+  // Swap 1st and 8th bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+7);
+  *(ptr+7) = val;
+
+  // Swap 2nd and 7th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+5);
+  *(ptr+5) = val;
+
+  // Swap 3rd and 6th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+3);
+  *(ptr+3) = val;
+
+  // Swap 4th and 5th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+  #include <unistd.h>
+#elif defined(__OS_WINDOWS__)
+  #include <windows.h>
+#endif
+
+void Stk :: sleep(unsigned long milliseconds)
+{
+#if defined(__OS_WINDOWS__)
+  Sleep((DWORD) milliseconds);
+#elif (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+  usleep( (unsigned long) (milliseconds * 1000.0) );
+#endif
+}
+
+void Stk :: handleError( StkError::Type type ) const
+{
+  handleError( oStream_.str(), type );
+  oStream_.str( std::string() ); // reset the ostringstream buffer
+}
+
+void Stk :: handleError( const char *message, StkError::Type type )
+{
+  std::string msg( message );
+  handleError( msg, type );
+}
+
+void Stk :: handleError( std::string message, StkError::Type type )
+{
+  if ( type == StkError::WARNING || type == StkError::STATUS ) {
+    if ( !showWarnings_ ) return;
+    std::cerr << '\n' << message << '\n' << std::endl;
+  }
+  else if (type == StkError::DEBUG_PRINT) {
+#if defined(_STK_DEBUG_)
+    std::cerr << '\n' << message << '\n' << std::endl;
+#endif
+  }
+  else {
+    if ( printErrors_ ) {
+      // Print error message before throwing.
+      std::cerr << '\n' << message << '\n' << std::endl;
+    }
+    throw StkError(message, type);
+  }
+}
+
+//
+// StkFrames definitions
+//
+
+StkFrames :: StkFrames( unsigned int nFrames, unsigned int nChannels )
+  : data_( 0 ), nFrames_( nFrames ), nChannels_( nChannels )
+{
+  size_ = nFrames_ * nChannels_;
+  bufferSize_ = size_;
+
+  if ( size_ > 0 ) {
+    data_ = (StkFloat *) calloc( size_, sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames: memory allocation error in constructor!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+  }
+
+  dataRate_ = Stk::sampleRate();
+}
+
+StkFrames :: StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels )
+  : data_( 0 ), nFrames_( nFrames ), nChannels_( nChannels )
+{
+  size_ = nFrames_ * nChannels_;
+  bufferSize_ = size_;
+  if ( size_ > 0 ) {
+    data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames: memory allocation error in constructor!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+    for ( long i=0; i<(long)size_; i++ ) data_[i] = value;
+  }
+
+  dataRate_ = Stk::sampleRate();
+}
+
+StkFrames :: ~StkFrames()
+{
+  if ( data_ ) free( data_ );
+}
+
+StkFrames :: StkFrames( const StkFrames& f )
+  : data_(0), size_(0), bufferSize_(0)
+{
+  resize( f.frames(), f.channels() );
+  dataRate_ = Stk::sampleRate();
+  for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i];
+}
+
+StkFrames& StkFrames :: operator= ( const StkFrames& f )
+{
+  data_ = 0;
+  size_ = 0;
+  bufferSize_ = 0;
+  resize( f.frames(), f.channels() );
+  dataRate_ = Stk::sampleRate();
+  for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i];
+  return *this;
+}
+
+void StkFrames :: resize( size_t nFrames, unsigned int nChannels )
+{
+  nFrames_ = nFrames;
+  nChannels_ = nChannels;
+
+  size_ = nFrames_ * nChannels_;
+  if ( size_ > bufferSize_ ) {
+    if ( data_ ) free( data_ );
+    data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames::resize: memory allocation error!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+    bufferSize_ = size_;
+  }
+}
+
+void StkFrames :: resize( size_t nFrames, unsigned int nChannels, StkFloat value )
+{
+  this->resize( nFrames, nChannels );
+
+  for ( size_t i=0; i<size_; i++ ) data_[i] = value;
+}
+
+StkFloat StkFrames :: interpolate( StkFloat frame, unsigned int channel ) const
+{
+#if defined(_STK_DEBUG_)
+  if ( frame < 0.0 || frame > (StkFloat) ( nFrames_ - 1 ) || channel >= nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::interpolate: invalid frame (" << frame << ") or channel (" << channel << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  size_t iIndex = ( size_t ) frame;                    // integer part of index
+  StkFloat output, alpha = frame - (StkFloat) iIndex;  // fractional part of index
+
+  iIndex = iIndex * nChannels_ + channel;
+  output = data_[ iIndex ];
+  if ( alpha > 0.0 )
+    output += ( alpha * ( data_[ iIndex + nChannels_ ] - output ) );
+
+  return output;
+}
+
+} // stk namespace