beeps 0.1.11 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.doc/ext/beeps/beeps.cpp +2 -5
  3. data/.doc/ext/beeps/file_in.cpp +0 -5
  4. data/.doc/ext/beeps/native.cpp +0 -4
  5. data/.doc/ext/beeps/processor.cpp +1 -5
  6. data/.doc/ext/beeps/sawtooth_wave.cpp +0 -5
  7. data/.doc/ext/beeps/sine_wave.cpp +0 -5
  8. data/.doc/ext/beeps/sound.cpp +0 -5
  9. data/.doc/ext/beeps/square_wave.cpp +0 -5
  10. data/README.md +1 -1
  11. data/Rakefile +15 -12
  12. data/VERSION +1 -1
  13. data/beeps.gemspec +5 -7
  14. data/ext/beeps/beeps.cpp +2 -5
  15. data/ext/beeps/defs.h +3 -2
  16. data/ext/beeps/extconf.rb +2 -3
  17. data/ext/beeps/file_in.cpp +0 -5
  18. data/ext/beeps/native.cpp +0 -4
  19. data/ext/beeps/processor.cpp +1 -5
  20. data/ext/beeps/sawtooth_wave.cpp +0 -5
  21. data/ext/beeps/sine_wave.cpp +0 -5
  22. data/ext/beeps/sound.cpp +0 -5
  23. data/ext/beeps/square_wave.cpp +0 -5
  24. data/include/beeps.h +5 -0
  25. data/include/beeps/debug.h +23 -0
  26. data/include/beeps/exception.h +6 -2
  27. data/include/beeps/processor.h +9 -6
  28. data/include/beeps/ruby/beeps.h +1 -0
  29. data/include/beeps/signals.h +2 -9
  30. data/include/beeps/sound.h +2 -1
  31. data/lib/beeps/module.rb +4 -19
  32. data/lib/beeps/processor.rb +16 -20
  33. data/src/beeps.cpp +3 -64
  34. data/src/exception.cpp +0 -3
  35. data/src/openal.cpp +63 -174
  36. data/src/openal.h +15 -4
  37. data/src/processor.cpp +5 -5
  38. data/src/signals.cpp +21 -19
  39. data/src/signals.h +23 -0
  40. data/src/sound.cpp +173 -14
  41. data/src/sound.h +17 -0
  42. metadata +30 -73
  43. data/include/beeps/openal.h +0 -34
  44. data/src/stk/include/Blit.h +0 -151
  45. data/src/stk/include/BlitSaw.h +0 -148
  46. data/src/stk/include/BlitSquare.h +0 -170
  47. data/src/stk/include/FileRead.h +0 -141
  48. data/src/stk/include/FileWvIn.h +0 -195
  49. data/src/stk/include/Generator.h +0 -50
  50. data/src/stk/include/SineWave.h +0 -159
  51. data/src/stk/include/Stk.h +0 -589
  52. data/src/stk/include/WvIn.h +0 -46
  53. data/src/stk/src/Blit.cpp +0 -78
  54. data/src/stk/src/BlitSaw.cpp +0 -91
  55. data/src/stk/src/BlitSquare.cpp +0 -95
  56. data/src/stk/src/FileRead.cpp +0 -903
  57. data/src/stk/src/FileWvIn.cpp +0 -260
  58. data/src/stk/src/SineWave.cpp +0 -78
  59. data/src/stk/src/Stk.cpp +0 -395
@@ -1,260 +0,0 @@
1
- /***************************************************/
2
- /*! \class FileWvIn
3
- \brief STK audio file input class.
4
-
5
- This class inherits from WvIn. It provides a "tick-level"
6
- interface to the FileRead class. It also provides variable-rate
7
- playback functionality. Audio file support is provided by the
8
- FileRead class. Linear interpolation is used for fractional read
9
- rates.
10
-
11
- FileWvIn supports multi-channel data. It is important to
12
- distinguish the tick() method that computes a single frame (and
13
- returns only the specified sample of a multi-channel frame) from
14
- the overloaded one that takes an StkFrames object for
15
- multi-channel and/or multi-frame data.
16
-
17
- FileWvIn will either load the entire content of an audio file into
18
- local memory or incrementally read file data from disk in chunks.
19
- This behavior is controlled by the optional constructor arguments
20
- \e chunkThreshold and \e chunkSize. File sizes greater than \e
21
- chunkThreshold (in sample frames) will be read incrementally in
22
- chunks of \e chunkSize each (also in sample frames).
23
-
24
- When the file end is reached, subsequent calls to the tick()
25
- functions return zeros and isFinished() returns \e true.
26
-
27
- See the FileRead class for a description of the supported audio
28
- file formats.
29
-
30
- by Perry R. Cook and Gary P. Scavone, 1995--2014.
31
- */
32
- /***************************************************/
33
-
34
- #include "FileWvIn.h"
35
- #include <cmath>
36
-
37
- namespace stk {
38
-
39
- FileWvIn :: FileWvIn( unsigned long chunkThreshold, unsigned long chunkSize )
40
- : finished_(true), interpolate_(false), time_(0.0), rate_(0.0),
41
- chunkThreshold_(chunkThreshold), chunkSize_(chunkSize)
42
- {
43
- Stk::addSampleRateAlert( this );
44
- }
45
-
46
- FileWvIn :: FileWvIn( std::string fileName, bool raw, bool doNormalize,
47
- unsigned long chunkThreshold, unsigned long chunkSize )
48
- : finished_(true), interpolate_(false), time_(0.0), rate_(0.0),
49
- chunkThreshold_(chunkThreshold), chunkSize_(chunkSize)
50
- {
51
- openFile( fileName, raw, doNormalize );
52
- Stk::addSampleRateAlert( this );
53
- }
54
-
55
- FileWvIn :: ~FileWvIn()
56
- {
57
- this->closeFile();
58
- Stk::removeSampleRateAlert( this );
59
- }
60
-
61
- void FileWvIn :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
62
- {
63
- if ( !ignoreSampleRateChange_ )
64
- this->setRate( oldRate * rate_ / newRate );
65
- }
66
-
67
- void FileWvIn :: closeFile( void )
68
- {
69
- if ( file_.isOpen() ) file_.close();
70
- finished_ = true;
71
- lastFrame_.resize( 0, 0 );
72
- }
73
-
74
- void FileWvIn :: openFile( std::string fileName, bool raw, bool doNormalize )
75
- {
76
- // Call close() in case another file is already open.
77
- this->closeFile();
78
-
79
- // Attempt to open the file ... an error might be thrown here.
80
- file_.open( fileName, raw );
81
-
82
- // Determine whether chunking or not.
83
- if ( file_.fileSize() > chunkThreshold_ ) {
84
- chunking_ = true;
85
- chunkPointer_ = 0;
86
- data_.resize( chunkSize_, file_.channels() );
87
- if ( doNormalize ) normalizing_ = true;
88
- else normalizing_ = false;
89
- }
90
- else {
91
- chunking_ = false;
92
- data_.resize( (size_t) file_.fileSize(), file_.channels() );
93
- }
94
-
95
- // Load all or part of the data.
96
- file_.read( data_, 0, doNormalize );
97
-
98
- // Resize our lastFrame container.
99
- lastFrame_.resize( 1, file_.channels() );
100
-
101
- // Set default rate based on file sampling rate.
102
- this->setRate( data_.dataRate() / Stk::sampleRate() );
103
-
104
- if ( doNormalize & !chunking_ ) this->normalize();
105
-
106
- this->reset();
107
- }
108
-
109
- void FileWvIn :: reset(void)
110
- {
111
- time_ = (StkFloat) 0.0;
112
- for ( unsigned int i=0; i<lastFrame_.size(); i++ ) lastFrame_[i] = 0.0;
113
- finished_ = false;
114
- }
115
-
116
- void FileWvIn :: normalize(void)
117
- {
118
- this->normalize( 1.0 );
119
- }
120
-
121
- // Normalize all channels equally by the greatest magnitude in all of the data.
122
- void FileWvIn :: normalize( StkFloat peak )
123
- {
124
- // When chunking, the "normalization" scaling is performed by FileRead.
125
- if ( chunking_ ) return;
126
-
127
- size_t i;
128
- StkFloat max = 0.0;
129
-
130
- for ( i=0; i<data_.size(); i++ ) {
131
- if ( fabs( data_[i] ) > max )
132
- max = (StkFloat) fabs((double) data_[i]);
133
- }
134
-
135
- if ( max > 0.0 ) {
136
- max = 1.0 / max;
137
- max *= peak;
138
- for ( i=0; i<data_.size(); i++ )
139
- data_[i] *= max;
140
- }
141
- }
142
-
143
- void FileWvIn :: setRate( StkFloat rate )
144
- {
145
- rate_ = rate;
146
-
147
- // If negative rate and at beginning of sound, move pointer to end
148
- // of sound.
149
- if ( (rate_ < 0) && (time_ == 0.0) ) time_ = file_.fileSize() - 1.0;
150
-
151
- if ( fmod( rate_, 1.0 ) != 0.0 ) interpolate_ = true;
152
- else interpolate_ = false;
153
- }
154
-
155
- void FileWvIn :: addTime( StkFloat time )
156
- {
157
- // Add an absolute time in samples
158
- time_ += time;
159
-
160
- if ( time_ < 0.0 ) time_ = 0.0;
161
- if ( time_ > file_.fileSize() - 1.0 ) {
162
- time_ = file_.fileSize() - 1.0;
163
- for ( unsigned int i=0; i<lastFrame_.size(); i++ ) lastFrame_[i] = 0.0;
164
- finished_ = true;
165
- }
166
- }
167
-
168
- StkFloat FileWvIn :: tick( unsigned int channel )
169
- {
170
- #if defined(_STK_DEBUG_)
171
- if ( channel >= data_.channels() ) {
172
- oStream_ << "FileWvIn::tick(): channel argument and soundfile data are incompatible!";
173
- handleError( StkError::FUNCTION_ARGUMENT );
174
- }
175
- #endif
176
-
177
- if ( finished_ ) return 0.0;
178
-
179
- if ( time_ < 0.0 || time_ > (StkFloat) ( file_.fileSize() - 1.0 ) ) {
180
- for ( unsigned int i=0; i<lastFrame_.size(); i++ ) lastFrame_[i] = 0.0;
181
- finished_ = true;
182
- return 0.0;
183
- }
184
-
185
- StkFloat tyme = time_;
186
- if ( chunking_ ) {
187
-
188
- // Check the time address vs. our current buffer limits.
189
- if ( ( time_ < (StkFloat) chunkPointer_ ) ||
190
- ( time_ > (StkFloat) ( chunkPointer_ + chunkSize_ - 1 ) ) ) {
191
-
192
- while ( time_ < (StkFloat) chunkPointer_ ) { // negative rate
193
- chunkPointer_ -= chunkSize_ - 1; // overlap chunks by one frame
194
- if ( chunkPointer_ < 0 ) chunkPointer_ = 0;
195
- }
196
- while ( time_ > (StkFloat) ( chunkPointer_ + chunkSize_ - 1 ) ) { // positive rate
197
- chunkPointer_ += chunkSize_ - 1; // overlap chunks by one frame
198
- if ( chunkPointer_ + chunkSize_ > file_.fileSize() ) // at end of file
199
- chunkPointer_ = file_.fileSize() - chunkSize_;
200
- }
201
-
202
- // Load more data.
203
- file_.read( data_, chunkPointer_, normalizing_ );
204
- }
205
-
206
- // Adjust index for the current buffer.
207
- tyme -= chunkPointer_;
208
- }
209
-
210
- if ( interpolate_ ) {
211
- for ( unsigned int i=0; i<lastFrame_.size(); i++ )
212
- lastFrame_[i] = data_.interpolate( tyme, i );
213
- }
214
- else {
215
- for ( unsigned int i=0; i<lastFrame_.size(); i++ )
216
- lastFrame_[i] = data_( (size_t) tyme, i );
217
- }
218
-
219
- // Increment time, which can be negative.
220
- time_ += rate_;
221
-
222
- return lastFrame_[channel];
223
- }
224
-
225
- StkFrames& FileWvIn :: tick( StkFrames& frames, unsigned int channel)
226
- {
227
- if ( !file_.isOpen() ) {
228
- #if defined(_STK_DEBUG_)
229
- oStream_ << "FileWvIn::tick(): no file data is loaded!";
230
- handleError( StkError::DEBUG_PRINT );
231
- #endif
232
- return frames;
233
- }
234
-
235
- unsigned int nChannels = lastFrame_.channels();
236
- #if defined(_STK_DEBUG_)
237
- if ( channel > frames.channels() - nChannels ) {
238
- oStream_ << "FileWvIn::tick(): channel and StkFrames arguments are incompatible!";
239
- handleError( StkError::FUNCTION_ARGUMENT );
240
- }
241
- #endif
242
-
243
- StkFloat *samples = &frames[channel];
244
- unsigned int j, hop = frames.channels() - nChannels;
245
- if ( nChannels == 1 ) {
246
- for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
247
- *samples++ = tick();
248
- }
249
- else {
250
- for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
251
- *samples++ = tick();
252
- for ( j=1; j<nChannels; j++ )
253
- *samples++ = lastFrame_[j];
254
- }
255
- }
256
- return frames;
257
-
258
- }
259
-
260
- } // stk namespace
@@ -1,78 +0,0 @@
1
- /***************************************************/
2
- /*! \class SineWave
3
- \brief STK sinusoid oscillator class.
4
-
5
- This class computes and saves a static sine "table" that can be
6
- shared by multiple instances. It has an interface similar to the
7
- WaveLoop class but inherits from the Generator class. Output
8
- values are computed using linear interpolation.
9
-
10
- The "table" length, set in SineWave.h, is 2048 samples by default.
11
-
12
- by Perry R. Cook and Gary P. Scavone, 1995--2014.
13
- */
14
- /***************************************************/
15
-
16
- #include "SineWave.h"
17
- #include <cmath>
18
-
19
- namespace stk {
20
-
21
- StkFrames SineWave :: table_;
22
-
23
- SineWave :: SineWave( void )
24
- : time_(0.0), rate_(1.0), phaseOffset_(0.0)
25
- {
26
- if ( table_.empty() ) {
27
- table_.resize( TABLE_SIZE + 1, 1 );
28
- StkFloat temp = 1.0 / TABLE_SIZE;
29
- for ( unsigned long i=0; i<=TABLE_SIZE; i++ )
30
- table_[i] = sin( TWO_PI * i * temp );
31
- }
32
-
33
- Stk::addSampleRateAlert( this );
34
- }
35
-
36
- SineWave :: ~SineWave()
37
- {
38
- Stk::removeSampleRateAlert( this );
39
- }
40
-
41
- void SineWave :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
42
- {
43
- if ( !ignoreSampleRateChange_ )
44
- this->setRate( oldRate * rate_ / newRate );
45
- }
46
-
47
- void SineWave :: reset( void )
48
- {
49
- time_ = 0.0;
50
- lastFrame_[0] = 0;
51
- }
52
-
53
- void SineWave :: setFrequency( StkFloat frequency )
54
- {
55
- // This is a looping frequency.
56
- this->setRate( TABLE_SIZE * frequency / Stk::sampleRate() );
57
- }
58
-
59
- void SineWave :: addTime( StkFloat time )
60
- {
61
- // Add an absolute time in samples.
62
- time_ += time;
63
- }
64
-
65
- void SineWave :: addPhase( StkFloat phase )
66
- {
67
- // Add a time in cycles (one cycle = TABLE_SIZE).
68
- time_ += TABLE_SIZE * phase;
69
- }
70
-
71
- void SineWave :: addPhaseOffset( StkFloat phaseOffset )
72
- {
73
- // Add a phase offset relative to any previous offset value.
74
- time_ += ( phaseOffset - phaseOffset_ ) * TABLE_SIZE;
75
- phaseOffset_ = phaseOffset;
76
- }
77
-
78
- } // stk namespace
@@ -1,395 +0,0 @@
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
- The Synthesis ToolKit in C++ (STK) is a set of open source audio
12
- signal processing and algorithmic synthesis classes written in the
13
- C++ programming language. STK was designed to facilitate rapid
14
- development of music synthesis and audio processing software, with
15
- an emphasis on cross-platform functionality, realtime control,
16
- ease of use, and educational example code. STK currently runs
17
- with realtime support (audio and MIDI) on Linux, Macintosh OS X,
18
- and Windows computer platforms. Generic, non-realtime support has
19
- been tested under NeXTStep, Sun, and other platforms and should
20
- work with any standard C++ compiler.
21
-
22
- STK WWW site: http://ccrma.stanford.edu/software/stk/
23
-
24
- The Synthesis ToolKit in C++ (STK)
25
- Copyright (c) 1995--2014 Perry R. Cook and Gary P. Scavone
26
-
27
- Permission is hereby granted, free of charge, to any person
28
- obtaining a copy of this software and associated documentation files
29
- (the "Software"), to deal in the Software without restriction,
30
- including without limitation the rights to use, copy, modify, merge,
31
- publish, distribute, sublicense, and/or sell copies of the Software,
32
- and to permit persons to whom the Software is furnished to do so,
33
- subject to the following conditions:
34
-
35
- The above copyright notice and this permission notice shall be
36
- included in all copies or substantial portions of the Software.
37
-
38
- Any person wishing to distribute modifications to the Software is
39
- asked to send the modifications to the original developer so that
40
- they can be incorporated into the canonical version. This is,
41
- however, not a binding provision of this license.
42
-
43
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
44
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
45
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
46
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
47
- ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
48
- CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
49
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50
- */
51
- /***************************************************/
52
-
53
- #include "Stk.h"
54
- #include <stdlib.h>
55
-
56
- namespace stk {
57
-
58
- StkFloat Stk :: srate_ = (StkFloat) SRATE;
59
- std::string Stk :: rawwavepath_ = RAWWAVE_PATH;
60
- const Stk::StkFormat Stk :: STK_SINT8 = 0x1;
61
- const Stk::StkFormat Stk :: STK_SINT16 = 0x2;
62
- const Stk::StkFormat Stk :: STK_SINT24 = 0x4;
63
- const Stk::StkFormat Stk :: STK_SINT32 = 0x8;
64
- const Stk::StkFormat Stk :: STK_FLOAT32 = 0x10;
65
- const Stk::StkFormat Stk :: STK_FLOAT64 = 0x20;
66
- bool Stk :: showWarnings_ = true;
67
- bool Stk :: printErrors_ = true;
68
- std::vector<Stk *> Stk :: alertList_;
69
- std::ostringstream Stk :: oStream_;
70
-
71
- Stk :: Stk( void )
72
- : ignoreSampleRateChange_(false)
73
- {
74
- }
75
-
76
- Stk :: ~Stk( void )
77
- {
78
- }
79
-
80
- void Stk :: setSampleRate( StkFloat rate )
81
- {
82
- if ( rate > 0.0 && rate != srate_ ) {
83
- StkFloat oldRate = srate_;
84
- srate_ = rate;
85
-
86
- for ( unsigned int i=0; i<alertList_.size(); i++ )
87
- alertList_[i]->sampleRateChanged( srate_, oldRate );
88
- }
89
- }
90
-
91
- void Stk :: sampleRateChanged( StkFloat /*newRate*/, StkFloat /*oldRate*/ )
92
- {
93
- // This function should be reimplemented in classes that need to
94
- // make internal variable adjustments in response to a global sample
95
- // rate change.
96
- }
97
-
98
- void Stk :: addSampleRateAlert( Stk *ptr )
99
- {
100
- for ( unsigned int i=0; i<alertList_.size(); i++ )
101
- if ( alertList_[i] == ptr ) return;
102
-
103
- alertList_.push_back( ptr );
104
- }
105
-
106
- void Stk :: removeSampleRateAlert( Stk *ptr )
107
- {
108
- for ( unsigned int i=0; i<alertList_.size(); i++ ) {
109
- if ( alertList_[i] == ptr ) {
110
- alertList_.erase( alertList_.begin() + i );
111
- return;
112
- }
113
- }
114
- }
115
-
116
- void Stk :: setRawwavePath( std::string path )
117
- {
118
- if ( !path.empty() )
119
- rawwavepath_ = path;
120
-
121
- // Make sure the path includes a "/"
122
- if ( rawwavepath_[rawwavepath_.length()-1] != '/' )
123
- rawwavepath_ += "/";
124
- }
125
-
126
- void Stk :: swap16(unsigned char *ptr)
127
- {
128
- unsigned char val;
129
-
130
- // Swap 1st and 2nd bytes
131
- val = *(ptr);
132
- *(ptr) = *(ptr+1);
133
- *(ptr+1) = val;
134
- }
135
-
136
- void Stk :: swap32(unsigned char *ptr)
137
- {
138
- unsigned char val;
139
-
140
- // Swap 1st and 4th bytes
141
- val = *(ptr);
142
- *(ptr) = *(ptr+3);
143
- *(ptr+3) = val;
144
-
145
- //Swap 2nd and 3rd bytes
146
- ptr += 1;
147
- val = *(ptr);
148
- *(ptr) = *(ptr+1);
149
- *(ptr+1) = val;
150
- }
151
-
152
- void Stk :: swap64(unsigned char *ptr)
153
- {
154
- unsigned char val;
155
-
156
- // Swap 1st and 8th bytes
157
- val = *(ptr);
158
- *(ptr) = *(ptr+7);
159
- *(ptr+7) = val;
160
-
161
- // Swap 2nd and 7th bytes
162
- ptr += 1;
163
- val = *(ptr);
164
- *(ptr) = *(ptr+5);
165
- *(ptr+5) = val;
166
-
167
- // Swap 3rd and 6th bytes
168
- ptr += 1;
169
- val = *(ptr);
170
- *(ptr) = *(ptr+3);
171
- *(ptr+3) = val;
172
-
173
- // Swap 4th and 5th bytes
174
- ptr += 1;
175
- val = *(ptr);
176
- *(ptr) = *(ptr+1);
177
- *(ptr+1) = val;
178
- }
179
-
180
- #if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
181
- #include <unistd.h>
182
- #elif defined(__OS_WINDOWS__)
183
- #include <windows.h>
184
- #endif
185
-
186
- void Stk :: sleep(unsigned long milliseconds)
187
- {
188
- #if defined(__OS_WINDOWS__)
189
- Sleep((DWORD) milliseconds);
190
- #elif (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
191
- usleep( (unsigned long) (milliseconds * 1000.0) );
192
- #endif
193
- }
194
-
195
- void Stk :: handleError( StkError::Type type ) const
196
- {
197
- handleError( oStream_.str(), type );
198
- oStream_.str( std::string() ); // reset the ostringstream buffer
199
- }
200
-
201
- void Stk :: handleError( const char *message, StkError::Type type )
202
- {
203
- std::string msg( message );
204
- handleError( msg, type );
205
- }
206
-
207
- void Stk :: handleError( std::string message, StkError::Type type )
208
- {
209
- if ( type == StkError::WARNING || type == StkError::STATUS ) {
210
- if ( !showWarnings_ ) return;
211
- std::cerr << '\n' << message << '\n' << std::endl;
212
- }
213
- else if (type == StkError::DEBUG_PRINT) {
214
- #if defined(_STK_DEBUG_)
215
- std::cerr << '\n' << message << '\n' << std::endl;
216
- #endif
217
- }
218
- else {
219
- if ( printErrors_ ) {
220
- // Print error message before throwing.
221
- std::cerr << '\n' << message << '\n' << std::endl;
222
- }
223
- throw StkError(message, type);
224
- }
225
- }
226
-
227
- //
228
- // StkFrames definitions
229
- //
230
-
231
- StkFrames :: StkFrames( unsigned int nFrames, unsigned int nChannels )
232
- : data_( 0 ), nFrames_( nFrames ), nChannels_( nChannels )
233
- {
234
- size_ = nFrames_ * nChannels_;
235
- bufferSize_ = size_;
236
-
237
- if ( size_ > 0 ) {
238
- data_ = (StkFloat *) calloc( size_, sizeof( StkFloat ) );
239
- #if defined(_STK_DEBUG_)
240
- if ( data_ == NULL ) {
241
- std::string error = "StkFrames: memory allocation error in constructor!";
242
- Stk::handleError( error, StkError::MEMORY_ALLOCATION );
243
- }
244
- #endif
245
- }
246
-
247
- dataRate_ = Stk::sampleRate();
248
- }
249
-
250
- StkFrames :: StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels )
251
- : data_( 0 ), nFrames_( nFrames ), nChannels_( nChannels )
252
- {
253
- size_ = nFrames_ * nChannels_;
254
- bufferSize_ = size_;
255
- if ( size_ > 0 ) {
256
- data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
257
- #if defined(_STK_DEBUG_)
258
- if ( data_ == NULL ) {
259
- std::string error = "StkFrames: memory allocation error in constructor!";
260
- Stk::handleError( error, StkError::MEMORY_ALLOCATION );
261
- }
262
- #endif
263
- for ( long i=0; i<(long)size_; i++ ) data_[i] = value;
264
- }
265
-
266
- dataRate_ = Stk::sampleRate();
267
- }
268
-
269
- StkFrames :: ~StkFrames()
270
- {
271
- if ( data_ ) free( data_ );
272
- }
273
-
274
- StkFrames :: StkFrames( const StkFrames& f )
275
- : data_(0), size_(0), bufferSize_(0)
276
- {
277
- resize( f.frames(), f.channels() );
278
- dataRate_ = Stk::sampleRate();
279
- for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i];
280
- }
281
-
282
- StkFrames& StkFrames :: operator= ( const StkFrames& f )
283
- {
284
- if ( data_ ) free( data_ );
285
- data_ = 0;
286
- size_ = 0;
287
- bufferSize_ = 0;
288
- resize( f.frames(), f.channels() );
289
- dataRate_ = Stk::sampleRate();
290
- for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i];
291
- return *this;
292
- }
293
-
294
- void StkFrames :: resize( size_t nFrames, unsigned int nChannels )
295
- {
296
- nFrames_ = nFrames;
297
- nChannels_ = nChannels;
298
-
299
- size_ = nFrames_ * nChannels_;
300
- if ( size_ > bufferSize_ ) {
301
- if ( data_ ) free( data_ );
302
- data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
303
- #if defined(_STK_DEBUG_)
304
- if ( data_ == NULL ) {
305
- std::string error = "StkFrames::resize: memory allocation error!";
306
- Stk::handleError( error, StkError::MEMORY_ALLOCATION );
307
- }
308
- #endif
309
- bufferSize_ = size_;
310
- }
311
- }
312
-
313
- void StkFrames :: resize( size_t nFrames, unsigned int nChannels, StkFloat value )
314
- {
315
- this->resize( nFrames, nChannels );
316
-
317
- for ( size_t i=0; i<size_; i++ ) data_[i] = value;
318
- }
319
-
320
- StkFrames& StkFrames::getChannel(unsigned int sourceChannel,StkFrames& destinationFrames, unsigned int destinationChannel) const
321
- {
322
- #if defined(_STK_DEBUG_)
323
- if (sourceChannel > channels() - 1) {
324
- std::ostringstream error;
325
- error << "StkFrames::getChannel invalid sourceChannel (" << sourceChannel << ")";
326
- Stk::handleError( error.str(), StkError::FUNCTION_ARGUMENT);
327
- }
328
- if (destinationChannel > destinationFrames.channels() - 1) {
329
- std::ostringstream error;
330
- error << "StkFrames::getChannel invalid destinationChannel (" << destinationChannel << ")";
331
- Stk::handleError( error.str(), StkError::FUNCTION_ARGUMENT );
332
- }
333
- if (destinationFrames.frames() < frames()) {
334
- std::ostringstream error;
335
- error << "StkFrames::getChannel destination.frames() < frames()";
336
- Stk::handleError( error.str(), StkError::MEMORY_ACCESS);
337
- }
338
- #endif
339
- int sourceHop = nChannels_;
340
- int destinationHop = destinationFrames.nChannels_;
341
- for (int i = sourceChannel, j= destinationChannel; i < nFrames_ * nChannels_; i+=sourceHop,j+=destinationHop) {
342
- destinationFrames[j] = data_[i];
343
- }
344
- return destinationFrames;
345
-
346
- }
347
-
348
- void StkFrames::setChannel(unsigned int destinationChannel, const stk::StkFrames &sourceFrames,unsigned int sourceChannel)
349
- {
350
- #if defined(_STK_DEBUG_)
351
- if (sourceChannel > sourceFrames.channels() - 1) {
352
- std::ostringstream error;
353
- error << "StkFrames::setChannel invalid sourceChannel (" << sourceChannel << ")";
354
- Stk::handleError( error.str(), StkError::FUNCTION_ARGUMENT);
355
- }
356
- if (destinationChannel > channels() - 1) {
357
- std::ostringstream error;
358
- error << "StkFrames::setChannel invalid channel (" << destinationChannel << ")";
359
- Stk::handleError( error.str(), StkError::FUNCTION_ARGUMENT );
360
- }
361
- if (sourceFrames.frames() != frames()) {
362
- std::ostringstream error;
363
- error << "StkFrames::setChannel sourceFrames.frames() != frames()";
364
- Stk::handleError( error.str(), StkError::MEMORY_ACCESS);
365
- }
366
- #endif
367
- unsigned int sourceHop = sourceFrames.nChannels_;
368
- unsigned int destinationHop = nChannels_;
369
- for (int i = destinationChannel,j = sourceChannel ; i < nFrames_ * nChannels_; i+=destinationHop,j+=sourceHop) {
370
- data_[i] = sourceFrames[j];
371
- }
372
- }
373
-
374
- StkFloat StkFrames :: interpolate( StkFloat frame, unsigned int channel ) const
375
- {
376
- #if defined(_STK_DEBUG_)
377
- if ( frame < 0.0 || frame > (StkFloat) ( nFrames_ - 1 ) || channel >= nChannels_ ) {
378
- std::ostringstream error;
379
- error << "StkFrames::interpolate: invalid frame (" << frame << ") or channel (" << channel << ") value!";
380
- Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
381
- }
382
- #endif
383
-
384
- size_t iIndex = ( size_t ) frame; // integer part of index
385
- StkFloat output, alpha = frame - (StkFloat) iIndex; // fractional part of index
386
-
387
- iIndex = iIndex * nChannels_ + channel;
388
- output = data_[ iIndex ];
389
- if ( alpha > 0.0 )
390
- output += ( alpha * ( data_[ iIndex + nChannels_ ] - output ) );
391
-
392
- return output;
393
- }
394
-
395
- } // stk namespace