1 /***************************************************/
2 /*! \class Stk
3     \brief STK base class
4 
5     Nearly all STK classes inherit from this class.
6     The global sample rate can be queried and
7     modified via Stk.  In addition, this class
8     provides error handling and byte-swapping
9     functions.
10 
11     by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
12 */
13 /***************************************************/
14 
15 #include "Stk.h"
16 #include <stdlib.h>
17 
18 using namespace Nyq;
19 
20 StkFloat Stk :: srate_ = (StkFloat) SRATE;
21 std::string Stk :: rawwavepath_ = RAWWAVE_PATH;
22 const Stk::StkFormat Stk :: STK_SINT8   = 0x1;
23 const Stk::StkFormat Stk :: STK_SINT16  = 0x2;
24 const Stk::StkFormat Stk :: STK_SINT24  = 0x4;
25 const Stk::StkFormat Stk :: STK_SINT32  = 0x8;
26 const Stk::StkFormat Stk :: STK_FLOAT32 = 0x10;
27 const Stk::StkFormat Stk :: STK_FLOAT64 = 0x20;
28 bool Stk :: showWarnings_ = false;
29 bool Stk :: printErrors_ = true;
30 
Stk(void)31 Stk :: Stk(void)
32 {
33 }
34 
~Stk(void)35 Stk :: ~Stk(void)
36 {
37 }
38 
setRawwavePath(std::string path)39 void Stk :: setRawwavePath( std::string path )
40 {
41   if ( !path.empty() )
42     rawwavepath_ = path;
43 
44   // Make sure the path includes a "/"
45   if ( rawwavepath_[rawwavepath_.length()-1] != '/' )
46     rawwavepath_ += "/";
47 }
48 
swap16(unsigned char * ptr)49 void Stk :: swap16(unsigned char *ptr)
50 {
51   unsigned char val;
52 
53   // Swap 1st and 2nd bytes
54   val = *(ptr);
55   *(ptr) = *(ptr+1);
56   *(ptr+1) = val;
57 }
58 
swap32(unsigned char * ptr)59 void Stk :: swap32(unsigned char *ptr)
60 {
61   unsigned char val;
62 
63   // Swap 1st and 4th bytes
64   val = *(ptr);
65   *(ptr) = *(ptr+3);
66   *(ptr+3) = val;
67 
68   //Swap 2nd and 3rd bytes
69   ptr += 1;
70   val = *(ptr);
71   *(ptr) = *(ptr+1);
72   *(ptr+1) = val;
73 }
74 
swap64(unsigned char * ptr)75 void Stk :: swap64(unsigned char *ptr)
76 {
77   unsigned char val;
78 
79   // Swap 1st and 8th bytes
80   val = *(ptr);
81   *(ptr) = *(ptr+7);
82   *(ptr+7) = val;
83 
84   // Swap 2nd and 7th bytes
85   ptr += 1;
86   val = *(ptr);
87   *(ptr) = *(ptr+5);
88   *(ptr+5) = val;
89 
90   // Swap 3rd and 6th bytes
91   ptr += 1;
92   val = *(ptr);
93   *(ptr) = *(ptr+3);
94   *(ptr+3) = val;
95 
96   // Swap 4th and 5th bytes
97   ptr += 1;
98   val = *(ptr);
99   *(ptr) = *(ptr+1);
100   *(ptr+1) = val;
101 }
102 
103 #if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
104   #include <unistd.h>
105 #elif defined(__OS_WINDOWS__)
106   #include <windows.h>
107 #endif
108 
sleep(unsigned long milliseconds)109 void Stk :: sleep(unsigned long milliseconds)
110 {
111 #if defined(__OS_WINDOWS__)
112   Sleep((DWORD) milliseconds);
113 #elif (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
114   usleep( (unsigned long) (milliseconds * 1000.0) );
115 #endif
116 }
117 
handleError(StkError::Type type)118 void Stk :: handleError( StkError::Type type )
119 {
120   handleError( errorString_.str(), type );
121   errorString_.str( std::string() ); // reset the ostringstream buffer
122 }
123 
handleError(const char * message,StkError::Type type)124 void Stk :: handleError( const char *message, StkError::Type type )
125 {
126   std::string msg( message );
127   handleError( msg, type );
128 }
129 
handleError(std::string message,StkError::Type type)130 void Stk :: handleError( std::string message, StkError::Type type )
131 {
132   if ( type == StkError::WARNING || type == StkError::STATUS ) {
133     if ( !showWarnings_ ) return;
134     std::cerr << '\n' << message << '\n' << std::endl;
135   }
136   else if (type == StkError::DEBUG_WARNING) {
137 #if defined(_STK_DEBUG_)
138     std::cerr << '\n' << message << '\n' << std::endl;
139 #endif
140   }
141   else {
142     if ( printErrors_ ) {
143       // Print error message before throwing.
144       std::cerr << '\n' << message << '\n' << std::endl;
145     }
146     throw StkError(message, type);
147   }
148 }
149 
150 //
151 // StkFrames definitions
152 //
153 
StkFrames(unsigned int nFrames,unsigned int nChannels,bool interleaved)154 StkFrames :: StkFrames( unsigned int nFrames, unsigned int nChannels, bool interleaved )
155   : nFrames_( nFrames ), nChannels_( nChannels ), interleaved_( interleaved )
156 {
157   size_ = nFrames_ * nChannels_;
158   bufferSize_ = size_;
159 
160   if ( size_ > 0 ) {
161     data_ = (StkFloat *) calloc( size_, sizeof( StkFloat ) );
162 #if defined(_STK_DEBUG_)
163     if ( data_ == NULL ) {
164       std::string error = "StkFrames: memory allocation error in constructor!";
165       Stk::handleError( error, StkError::MEMORY_ALLOCATION );
166     }
167 #endif
168   }
169   else data_ = 0;
170 
171   dataRate_ = Stk::sampleRate();
172 }
173 
StkFrames(const StkFloat & value,unsigned int nFrames,unsigned int nChannels,bool interleaved)174 StkFrames :: StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels, bool interleaved )
175   : nFrames_( nFrames ), nChannels_( nChannels ), interleaved_( interleaved )
176 {
177   size_ = nFrames_ * nChannels_;
178   bufferSize_ = size_;
179   if ( size_ > 0 ) {
180     data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
181 #if defined(_STK_DEBUG_)
182     if ( data_ == NULL ) {
183       std::string error = "StkFrames: memory allocation error in constructor!";
184       Stk::handleError( error, StkError::MEMORY_ALLOCATION );
185     }
186 #endif
187     for ( long i=0; i<(long)size_; i++ ) data_[i] = value;
188   }
189   else data_ = 0;
190 
191   dataRate_ = Stk::sampleRate();
192 }
193 
~StkFrames()194 StkFrames :: ~StkFrames()
195 {
196   if ( data_ ) free( data_ );
197 }
198 
empty() const199 bool StkFrames :: empty() const
200 {
201   if ( size_ > 0 ) return false;
202   else return true;
203 }
204 
resize(size_t nFrames,unsigned int nChannels)205 void StkFrames :: resize( size_t nFrames, unsigned int nChannels )
206 {
207   nFrames_ = nFrames;
208   nChannels_ = nChannels;
209 
210   size_ = nFrames_ * nChannels_;
211   if ( size_ > bufferSize_ ) {
212     if ( data_ ) free( data_ );
213     data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
214 #if defined(_STK_DEBUG_)
215     if ( data_ == NULL ) {
216       std::string error = "StkFrames::resize: memory allocation error!";
217       Stk::handleError( error, StkError::MEMORY_ALLOCATION );
218     }
219 #endif
220     bufferSize_ = size_;
221   }
222 }
223 
resize(size_t nFrames,unsigned int nChannels,StkFloat value)224 void StkFrames :: resize( size_t nFrames, unsigned int nChannels, StkFloat value )
225 {
226   this->resize( nFrames, nChannels );
227 
228   for ( size_t i=0; i<size_; i++ ) data_[i] = value;
229 }
230 
operator [](size_t n)231 StkFloat& StkFrames :: operator[] ( size_t n )
232 {
233 #if defined(_STK_DEBUG_)
234     if ( n >= size_ ) {
235       std::ostringstream error;
236       error << "StkFrames::operator[]: invalid index (" << n << ") value!";
237       Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
238     }
239 #endif
240 
241   return data_[n];
242 }
243 
operator [](size_t n) const244 StkFloat StkFrames :: operator[] ( size_t n ) const
245 {
246 #if defined(_STK_DEBUG_)
247     if ( n >= size_ ) {
248       std::ostringstream error;
249       error << "StkFrames::operator[]: invalid index (" << n << ") value!";
250       Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
251     }
252 #endif
253 
254   return data_[n];
255 }
256 
operator ()(size_t frame,unsigned int channel)257 StkFloat& StkFrames :: operator() ( size_t frame, unsigned int channel )
258 {
259 #if defined(_STK_DEBUG_)
260     if ( frame >= nFrames_ || channel >= nChannels_ ) {
261       std::ostringstream error;
262       error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!";
263       Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
264     }
265 #endif
266 
267   if ( interleaved_ )
268     return data_[ frame * nChannels_ + channel ];
269   else
270     return data_[ channel * nFrames_ + frame ];
271 }
272 
operator ()(size_t frame,unsigned int channel) const273 StkFloat StkFrames :: operator() ( size_t frame, unsigned int channel ) const
274 {
275 #if defined(_STK_DEBUG_)
276     if ( frame >= nFrames_ || channel >= nChannels_ ) {
277       std::ostringstream error;
278       error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!";
279       Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
280     }
281 #endif
282 
283   if ( interleaved_ )
284     return data_[ frame * nChannels_ + channel ];
285   else
286     return data_[ channel * nFrames_ + frame ];
287 }
288 
interpolate(StkFloat frame,unsigned int channel) const289 StkFloat StkFrames :: interpolate( StkFloat frame, unsigned int channel ) const
290 {
291 #if defined(_STK_DEBUG_)
292     if ( frame >= (StkFloat) nFrames_ || channel >= nChannels_ ) {
293       std::ostringstream error;
294       error << "StkFrames::interpolate: invalid frame (" << frame << ") or channel (" << channel << ") value!";
295       Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
296     }
297 #endif
298 
299   size_t iIndex = ( size_t ) frame;                    // integer part of index
300   StkFloat output, alpha = frame - (StkFloat) iIndex;  // fractional part of index
301 
302   if ( interleaved_ ) {
303     iIndex = iIndex * nChannels_ + channel;
304     output = data_[ iIndex ];
305     output += ( alpha * ( data_[ iIndex + nChannels_ ] - output ) );
306   }
307   else {
308     iIndex += channel * nFrames_;
309     output = data_[ iIndex ];
310     output += ( alpha * ( data_[ iIndex++ ] - output ) );
311   }
312 
313   return output;
314 }
315