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