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,46 +0,0 @@
1
- #ifndef STK_WVIN_H
2
- #define STK_WVIN_H
3
-
4
- #include "Stk.h"
5
-
6
- namespace stk {
7
-
8
- /***************************************************/
9
- /*! \class WvIn
10
- \brief STK audio input abstract base class.
11
-
12
- This class provides common functionality for a variety of audio
13
- data input subclasses.
14
-
15
- by Perry R. Cook and Gary P. Scavone, 1995--2014.
16
- */
17
- /***************************************************/
18
-
19
- class WvIn : public Stk
20
- {
21
- public:
22
- //! Return the number of audio channels in the data or stream.
23
- unsigned int channelsOut( void ) const { return data_.channels(); };
24
-
25
- //! Return an StkFrames reference to the last computed sample frame.
26
- /*!
27
- If no file data is loaded, an empty container is returned.
28
- */
29
- const StkFrames& lastFrame( void ) const { return lastFrame_; };
30
-
31
- //! Compute one sample frame and return the specified \c channel value.
32
- virtual StkFloat tick( unsigned int channel = 0 ) = 0;
33
-
34
- //! Fill the StkFrames object with computed sample frames, starting at the specified channel and return the same reference.
35
- virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ) = 0;
36
-
37
- protected:
38
-
39
- StkFrames data_;
40
- StkFrames lastFrame_;
41
-
42
- };
43
-
44
- } // stk namespace
45
-
46
- #endif
@@ -1,78 +0,0 @@
1
- /***************************************************/
2
- /*! \class Blit
3
- \brief STK band-limited impulse train class.
4
-
5
- This class generates a band-limited impulse train using a
6
- closed-form algorithm reported by Stilson and Smith in "Alias-Free
7
- Digital Synthesis of Classic Analog Waveforms", 1996. The user
8
- can specify both the fundamental frequency of the impulse train
9
- and the number of harmonics contained in the resulting signal.
10
-
11
- The signal is normalized so that the peak value is +/-1.0.
12
-
13
- If nHarmonics is 0, then the signal will contain all harmonics up
14
- to half the sample rate. Note, however, that this setting may
15
- produce aliasing in the signal when the frequency is changing (no
16
- automatic modification of the number of harmonics is performed by
17
- the setFrequency() function).
18
-
19
- Original code by Robin Davies, 2005.
20
- Revisions by Gary Scavone for STK, 2005.
21
- */
22
- /***************************************************/
23
-
24
- #include "Blit.h"
25
-
26
- namespace stk {
27
-
28
- Blit:: Blit( StkFloat frequency )
29
- {
30
- if ( frequency <= 0.0 ) {
31
- oStream_ << "Blit::Blit: argument (" << frequency << ") must be positive!";
32
- handleError( StkError::FUNCTION_ARGUMENT );
33
- }
34
-
35
- nHarmonics_ = 0;
36
- this->setFrequency( frequency );
37
- this->reset();
38
- }
39
-
40
- Blit :: ~Blit()
41
- {
42
- }
43
-
44
- void Blit :: reset()
45
- {
46
- phase_ = 0.0;
47
- lastFrame_[0] = 0.0;
48
- }
49
-
50
- void Blit :: setFrequency( StkFloat frequency )
51
- {
52
- if ( frequency <= 0.0 ) {
53
- oStream_ << "Blit::setFrequency: argument (" << frequency << ") must be positive!";
54
- handleError( StkError::WARNING ); return;
55
- }
56
-
57
- p_ = Stk::sampleRate() / frequency;
58
- rate_ = PI / p_;
59
- this->updateHarmonics();
60
- }
61
-
62
- void Blit :: setHarmonics( unsigned int nHarmonics )
63
- {
64
- nHarmonics_ = nHarmonics;
65
- this->updateHarmonics();
66
- }
67
-
68
- void Blit :: updateHarmonics( void )
69
- {
70
- if ( nHarmonics_ <= 0 ) {
71
- unsigned int maxHarmonics = (unsigned int) floor( 0.5 * p_ );
72
- m_ = 2 * maxHarmonics + 1;
73
- }
74
- else
75
- m_ = 2 * nHarmonics_ + 1;
76
- }
77
-
78
- } // stk namespace
@@ -1,91 +0,0 @@
1
- /***************************************************/
2
- /*! \class BlitSaw
3
- \brief STK band-limited sawtooth wave class.
4
-
5
- This class generates a band-limited sawtooth waveform using a
6
- closed-form algorithm reported by Stilson and Smith in "Alias-Free
7
- Digital Synthesis of Classic Analog Waveforms", 1996. The user
8
- can specify both the fundamental frequency of the sawtooth and the
9
- number of harmonics contained in the resulting signal.
10
-
11
- If nHarmonics is 0, then the signal will contain all harmonics up
12
- to half the sample rate. Note, however, that this setting may
13
- produce aliasing in the signal when the frequency is changing (no
14
- automatic modification of the number of harmonics is performed by
15
- the setFrequency() function).
16
-
17
- Based on initial code of Robin Davies, 2005.
18
- Modified algorithm code by Gary Scavone, 2005.
19
- */
20
- /***************************************************/
21
-
22
- #include "BlitSaw.h"
23
-
24
- namespace stk {
25
-
26
- BlitSaw:: BlitSaw( StkFloat frequency )
27
- {
28
- if ( frequency <= 0.0 ) {
29
- oStream_ << "BlitSaw::BlitSaw: argument (" << frequency << ") must be positive!";
30
- handleError( StkError::FUNCTION_ARGUMENT );
31
- }
32
-
33
- nHarmonics_ = 0;
34
- this->reset();
35
- this->setFrequency( frequency );
36
- }
37
-
38
- BlitSaw :: ~BlitSaw()
39
- {
40
- }
41
-
42
- void BlitSaw :: reset()
43
- {
44
- phase_ = 0.0f;
45
- state_ = 0.0;
46
- lastFrame_[0] = 0.0;
47
- }
48
-
49
- void BlitSaw :: setFrequency( StkFloat frequency )
50
- {
51
- if ( frequency <= 0.0 ) {
52
- oStream_ << "BlitSaw::setFrequency: argument (" << frequency << ") must be positive!";
53
- handleError( StkError::WARNING ); return;
54
- }
55
-
56
- p_ = Stk::sampleRate() / frequency;
57
- C2_ = 1 / p_;
58
- rate_ = PI * C2_;
59
- this->updateHarmonics();
60
- }
61
-
62
- void BlitSaw :: setHarmonics( unsigned int nHarmonics )
63
- {
64
- nHarmonics_ = nHarmonics;
65
- this->updateHarmonics();
66
-
67
- // I found that the initial DC offset could be minimized with an
68
- // initial state setting as given below. This initialization should
69
- // only happen before starting the oscillator for the first time
70
- // (but after setting the frequency and number of harmonics). I
71
- // struggled a bit to decide where best to put this and finally
72
- // settled on here. In general, the user shouldn't be messing with
73
- // the number of harmonics once the oscillator is running because
74
- // this is automatically taken care of in the setFrequency()
75
- // function. (GPS - 1 October 2005)
76
- state_ = -0.5 * a_;
77
- }
78
-
79
- void BlitSaw :: updateHarmonics( void )
80
- {
81
- if ( nHarmonics_ <= 0 ) {
82
- unsigned int maxHarmonics = (unsigned int) floor( 0.5 * p_ );
83
- m_ = 2 * maxHarmonics + 1;
84
- }
85
- else
86
- m_ = 2 * nHarmonics_ + 1;
87
-
88
- a_ = m_ / p_;
89
- }
90
-
91
- } // stk namespace
@@ -1,95 +0,0 @@
1
- /***************************************************/
2
- /*! \class BlitSquare
3
- \brief STK band-limited square wave class.
4
-
5
- This class generates a band-limited square wave signal. It is
6
- derived in part from the approach reported by Stilson and Smith in
7
- "Alias-Free Digital Synthesis of Classic Analog Waveforms", 1996.
8
- The algorithm implemented in this class uses a SincM function with
9
- an even M value to achieve a bipolar bandlimited impulse train.
10
- This signal is then integrated to achieve a square waveform. The
11
- integration process has an associated DC offset so a DC blocking
12
- filter is applied at the output.
13
-
14
- The user can specify both the fundamental frequency of the
15
- waveform and the number of harmonics contained in the resulting
16
- signal.
17
-
18
- If nHarmonics is 0, then the signal will contain all harmonics up
19
- to half the sample rate. Note, however, that this setting may
20
- produce aliasing in the signal when the frequency is changing (no
21
- automatic modification of the number of harmonics is performed by
22
- the setFrequency() function). Also note that the harmonics of a
23
- square wave fall at odd integer multiples of the fundamental, so
24
- aliasing will happen with a lower fundamental than with the other
25
- Blit waveforms. This class is not guaranteed to be well behaved
26
- in the presence of significant aliasing.
27
-
28
- Based on initial code of Robin Davies, 2005
29
- Modified algorithm code by Gary Scavone, 2005 - 2010.
30
- */
31
- /***************************************************/
32
-
33
- #include "BlitSquare.h"
34
-
35
- namespace stk {
36
-
37
- BlitSquare:: BlitSquare( StkFloat frequency )
38
- {
39
- if ( frequency <= 0.0 ) {
40
- oStream_ << "BlitSquare::BlitSquare: argument (" << frequency << ") must be positive!";
41
- handleError( StkError::FUNCTION_ARGUMENT );
42
- }
43
-
44
- nHarmonics_ = 0;
45
- this->setFrequency( frequency );
46
- this->reset();
47
- }
48
-
49
- BlitSquare :: ~BlitSquare()
50
- {
51
- }
52
-
53
- void BlitSquare :: reset()
54
- {
55
- phase_ = 0.0;
56
- lastFrame_[0] = 0.0;
57
- dcbState_ = 0.0;
58
- lastBlitOutput_ = 0;
59
- }
60
-
61
- void BlitSquare :: setFrequency( StkFloat frequency )
62
- {
63
- if ( frequency <= 0.0 ) {
64
- oStream_ << "BlitSquare::setFrequency: argument (" << frequency << ") must be positive!";
65
- handleError( StkError::WARNING ); return;
66
- }
67
-
68
- // By using an even value of the parameter M, we get a bipolar blit
69
- // waveform at half the blit frequency. Thus, we need to scale the
70
- // frequency value here by 0.5. (GPS, 2006).
71
- p_ = 0.5 * Stk::sampleRate() / frequency;
72
- rate_ = PI / p_;
73
- this->updateHarmonics();
74
- }
75
-
76
- void BlitSquare :: setHarmonics( unsigned int nHarmonics )
77
- {
78
- nHarmonics_ = nHarmonics;
79
- this->updateHarmonics();
80
- }
81
-
82
- void BlitSquare :: updateHarmonics( void )
83
- {
84
- // Make sure we end up with an even value of the parameter M here.
85
- if ( nHarmonics_ <= 0 ) {
86
- unsigned int maxHarmonics = (unsigned int) floor( 0.5 * p_ );
87
- m_ = 2 * (maxHarmonics + 1);
88
- }
89
- else
90
- m_ = 2 * (nHarmonics_ + 1);
91
-
92
- a_ = m_ / p_;
93
- }
94
-
95
- } // stk namespace
@@ -1,903 +0,0 @@
1
- /***************************************************/
2
- /*! \class FileRead
3
- \brief STK audio file input class.
4
-
5
- This class provides input support for various
6
- audio file formats. Multi-channel (>2)
7
- soundfiles are supported. The file data is
8
- returned via an external StkFrames object
9
- passed to the read() function. This class
10
- does not store its own copy of the file data,
11
- rather the data is read directly from disk.
12
-
13
- FileRead currently supports uncompressed WAV,
14
- AIFF/AIFC, SND (AU), MAT-file (Matlab), and
15
- STK RAW file formats. Signed integer (8-,
16
- 16-, 24- and 32-bit) and floating-point (32- and
17
- 64-bit) data types are supported. Compressed
18
- data types are not supported.
19
-
20
- STK RAW files have no header and are assumed to
21
- contain a monophonic stream of 16-bit signed
22
- integers in big-endian byte order at a sample
23
- rate of 22050 Hz. MAT-file data should be saved
24
- in an array with each data channel filling a
25
- matrix row. The sample rate for MAT-files should
26
- be specified in a variable named "fs". If no
27
- such variable is found, the sample rate is
28
- assumed to be 44100 Hz.
29
-
30
- by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
31
- */
32
- /***************************************************/
33
-
34
- #include "FileRead.h"
35
- #include <sys/stat.h>
36
- #include <sys/types.h>
37
- #include <cstring>
38
- #include <cmath>
39
- #include <cstdio>
40
-
41
- namespace stk {
42
-
43
- FileRead :: FileRead()
44
- : fd_(0), fileSize_(0), channels_(0), dataType_(0), fileRate_(0.0)
45
- {
46
- }
47
-
48
- FileRead :: FileRead( std::string fileName, bool typeRaw, unsigned int nChannels,
49
- StkFormat format, StkFloat rate )
50
- : fd_(0)
51
- {
52
- open( fileName, typeRaw, nChannels, format, rate );
53
- }
54
-
55
- FileRead :: ~FileRead()
56
- {
57
- if ( fd_ )
58
- fclose( fd_ );
59
- }
60
-
61
- void FileRead :: close( void )
62
- {
63
- if ( fd_ ) fclose( fd_ );
64
- fd_ = 0;
65
- wavFile_ = false;
66
- fileSize_ = 0;
67
- channels_ = 0;
68
- dataType_ = 0;
69
- fileRate_ = 0.0;
70
- }
71
-
72
- bool FileRead :: isOpen( void )
73
- {
74
- if ( fd_ ) return true;
75
- else return false;
76
- }
77
-
78
- void FileRead :: open( std::string fileName, bool typeRaw, unsigned int nChannels,
79
- StkFormat format, StkFloat rate )
80
- {
81
- // If another file is open, close it.
82
- close();
83
-
84
- // Try to open the file.
85
- fd_ = fopen( fileName.c_str(), "rb" );
86
- if ( !fd_ ) {
87
- oStream_ << "FileRead::open: could not open or find file (" << fileName << ")!";
88
- handleError( StkError::FILE_NOT_FOUND );
89
- }
90
-
91
- // Attempt to determine file type from header (unless RAW).
92
- bool result = false;
93
- if ( typeRaw )
94
- result = getRawInfo( fileName.c_str(), nChannels, format, rate );
95
- else {
96
- char header[12];
97
- if ( fread( &header, 4, 3, fd_ ) != 3 ) goto error;
98
- if ( !strncmp( header, "RIFF", 4 ) &&
99
- !strncmp( &header[8], "WAVE", 4 ) )
100
- result = getWavInfo( fileName.c_str() );
101
- else if ( !strncmp( header, ".snd", 4 ) )
102
- result = getSndInfo( fileName.c_str() );
103
- else if ( !strncmp( header, "FORM", 4 ) &&
104
- ( !strncmp( &header[8], "AIFF", 4 ) || !strncmp(&header[8], "AIFC", 4) ) )
105
- result = getAifInfo( fileName.c_str() );
106
- else {
107
- if ( fseek( fd_, 126, SEEK_SET ) == -1 ) goto error;
108
- if ( fread( &header, 2, 1, fd_ ) != 1 ) goto error;
109
- if ( !strncmp( header, "MI", 2 ) ||
110
- !strncmp( header, "IM", 2 ) )
111
- result = getMatInfo( fileName.c_str() );
112
- else {
113
- oStream_ << "FileRead::open: file (" << fileName << ") format unknown.";
114
- handleError( StkError::FILE_UNKNOWN_FORMAT );
115
- }
116
- }
117
- }
118
-
119
- // If here, we had a file type candidate but something else went wrong.
120
- if ( result == false )
121
- handleError( StkError::FILE_ERROR );
122
-
123
- // Check for empty files.
124
- if ( fileSize_ == 0 ) {
125
- oStream_ << "FileRead::open: file (" << fileName << ") data size is zero!";
126
- handleError( StkError::FILE_ERROR );
127
- }
128
-
129
- return;
130
-
131
- error:
132
- oStream_ << "FileRead::open: error reading file (" << fileName << ")!";
133
- handleError( StkError::FILE_ERROR );
134
- }
135
-
136
- bool FileRead :: getRawInfo( const char *fileName, unsigned int nChannels, StkFormat format, StkFloat rate )
137
- {
138
- // Use the system call "stat" to determine the file length.
139
- struct stat filestat;
140
- if ( stat(fileName, &filestat) == -1 ) {
141
- oStream_ << "FileRead: Could not stat RAW file (" << fileName << ").";
142
- return false;
143
- }
144
- if ( nChannels == 0 ) {
145
- oStream_ << "FileRead: number of channels can't be 0 (" << fileName << ").";
146
- return false;
147
- }
148
-
149
- // Rawwave files have no header and by default, are assumed to
150
- // contain a monophonic stream of 16-bit signed integers in
151
- // big-endian byte order at a sample rate of 22050 Hz. However,
152
- // different parameters can be specified if desired.
153
- dataOffset_ = 0;
154
- channels_ = nChannels;
155
- dataType_ = format;
156
- fileRate_ = rate;
157
- int sampleBytes = 0;
158
- if ( format == STK_SINT8 ) sampleBytes = 1;
159
- else if ( format == STK_SINT16 ) sampleBytes = 2;
160
- else if ( format == STK_SINT32 || format == STK_FLOAT32 ) sampleBytes = 4;
161
- else if ( format == STK_FLOAT64 ) sampleBytes = 8;
162
- else {
163
- oStream_ << "FileRead: StkFormat " << format << " is invalid (" << fileName << ").";
164
- return false;
165
- }
166
-
167
- fileSize_ = (long) filestat.st_size / sampleBytes / channels_; // length in frames
168
-
169
- byteswap_ = false;
170
- #ifdef __LITTLE_ENDIAN__
171
- byteswap_ = true;
172
- #endif
173
-
174
- return true;
175
- }
176
-
177
- bool FileRead :: getWavInfo( const char *fileName )
178
- {
179
- // Find "format" chunk ... it must come before the "data" chunk.
180
- char id[4];
181
- SINT32 chunkSize;
182
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
183
- while ( strncmp(id, "fmt ", 4) ) {
184
- if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
185
- #ifndef __LITTLE_ENDIAN__
186
- swap32((unsigned char *)&chunkSize);
187
- #endif
188
- if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
189
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
190
- }
191
-
192
- // Check that the data is not compressed.
193
- unsigned short format_tag;
194
- if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error; // Read fmt chunk size.
195
- if ( fread(&format_tag, 2, 1, fd_) != 1 ) goto error;
196
- #ifndef __LITTLE_ENDIAN__
197
- swap16((unsigned char *)&format_tag);
198
- swap32((unsigned char *)&chunkSize);
199
- #endif
200
- if ( format_tag == 0xFFFE ) { // WAVE_FORMAT_EXTENSIBLE
201
- dataOffset_ = ftell(fd_);
202
- if ( fseek(fd_, 14, SEEK_CUR) == -1 ) goto error;
203
- unsigned short extSize;
204
- if ( fread(&extSize, 2, 1, fd_) != 1 ) goto error;
205
- #ifndef __LITTLE_ENDIAN__
206
- swap16((unsigned char *)&extSize);
207
- #endif
208
- if ( extSize == 0 ) goto error;
209
- if ( fseek(fd_, 6, SEEK_CUR) == -1 ) goto error;
210
- if ( fread(&format_tag, 2, 1, fd_) != 1 ) goto error;
211
- #ifndef __LITTLE_ENDIAN__
212
- swap16((unsigned char *)&format_tag);
213
- #endif
214
- if ( fseek(fd_, dataOffset_, SEEK_SET) == -1 ) goto error;
215
- }
216
- if ( format_tag != 1 && format_tag != 3 ) { // PCM = 1, FLOAT = 3
217
- oStream_ << "FileRead: "<< fileName << " contains an unsupported data format type (" << format_tag << ").";
218
- return false;
219
- }
220
-
221
- // Get number of channels from the header.
222
- SINT16 temp;
223
- if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
224
- #ifndef __LITTLE_ENDIAN__
225
- swap16((unsigned char *)&temp);
226
- #endif
227
- channels_ = (unsigned int ) temp;
228
-
229
- // Get file sample rate from the header.
230
- SINT32 srate;
231
- if ( fread(&srate, 4, 1, fd_) != 1 ) goto error;
232
- #ifndef __LITTLE_ENDIAN__
233
- swap32((unsigned char *)&srate);
234
- #endif
235
- fileRate_ = (StkFloat) srate;
236
-
237
- // Determine the data type.
238
- dataType_ = 0;
239
- if ( fseek(fd_, 6, SEEK_CUR) == -1 ) goto error; // Locate bits_per_sample info.
240
- if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
241
- #ifndef __LITTLE_ENDIAN__
242
- swap16((unsigned char *)&temp);
243
- #endif
244
- if ( format_tag == 1 ) {
245
- if ( temp == 8 )
246
- dataType_ = STK_SINT8;
247
- else if ( temp == 16 )
248
- dataType_ = STK_SINT16;
249
- else if ( temp == 24 )
250
- dataType_ = STK_SINT24;
251
- else if ( temp == 32 )
252
- dataType_ = STK_SINT32;
253
- }
254
- else if ( format_tag == 3 ) {
255
- if ( temp == 32 )
256
- dataType_ = STK_FLOAT32;
257
- else if ( temp == 64 )
258
- dataType_ = STK_FLOAT64;
259
- }
260
- if ( dataType_ == 0 ) {
261
- oStream_ << "FileRead: " << temp << " bits per sample with data format " << format_tag << " are not supported (" << fileName << ").";
262
- return false;
263
- }
264
-
265
- // Jump over any remaining part of the "fmt" chunk.
266
- if ( fseek(fd_, chunkSize-16, SEEK_CUR) == -1 ) goto error;
267
-
268
- // Find "data" chunk ... it must come after the "fmt" chunk.
269
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
270
-
271
- while ( strncmp(id, "data", 4) ) {
272
- if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
273
- #ifndef __LITTLE_ENDIAN__
274
- swap32((unsigned char *)&chunkSize);
275
- #endif
276
- chunkSize += chunkSize % 2; // chunk sizes must be even
277
- if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
278
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
279
- }
280
-
281
- // Get length of data from the header.
282
- SINT32 bytes;
283
- if ( fread(&bytes, 4, 1, fd_) != 1 ) goto error;
284
- #ifndef __LITTLE_ENDIAN__
285
- swap32((unsigned char *)&bytes);
286
- #endif
287
- fileSize_ = bytes / temp / channels_; // sample frames
288
- fileSize_ *= 8; // sample frames
289
-
290
- dataOffset_ = ftell(fd_);
291
- byteswap_ = false;
292
- #ifndef __LITTLE_ENDIAN__
293
- byteswap_ = true;
294
- #endif
295
-
296
- wavFile_ = true;
297
- return true;
298
-
299
- error:
300
- oStream_ << "FileRead: error reading WAV file (" << fileName << ").";
301
- return false;
302
- }
303
-
304
- bool FileRead :: getSndInfo( const char *fileName )
305
- {
306
- // Determine the data type.
307
- UINT32 format;
308
- if ( fseek(fd_, 12, SEEK_SET) == -1 ) goto error; // Locate format
309
- if ( fread(&format, 4, 1, fd_) != 1 ) goto error;
310
- #ifdef __LITTLE_ENDIAN__
311
- swap32((unsigned char *)&format);
312
- #endif
313
-
314
- if (format == 2) dataType_ = STK_SINT8;
315
- else if (format == 3) dataType_ = STK_SINT16;
316
- else if (format == 4) dataType_ = STK_SINT24;
317
- else if (format == 5) dataType_ = STK_SINT32;
318
- else if (format == 6) dataType_ = STK_FLOAT32;
319
- else if (format == 7) dataType_ = STK_FLOAT64;
320
- else {
321
- oStream_ << "FileRead: data format in file " << fileName << " is not supported.";
322
- return false;
323
- }
324
-
325
- // Get file sample rate from the header.
326
- UINT32 srate;
327
- if ( fread(&srate, 4, 1, fd_) != 1 ) goto error;
328
- #ifdef __LITTLE_ENDIAN__
329
- swap32((unsigned char *)&srate);
330
- #endif
331
- fileRate_ = (StkFloat) srate;
332
-
333
- // Get number of channels from the header.
334
- UINT32 chans;
335
- if ( fread(&chans, 4, 1, fd_) != 1 ) goto error;
336
- #ifdef __LITTLE_ENDIAN__
337
- swap32((unsigned char *)&chans);
338
- #endif
339
- channels_ = chans;
340
-
341
- UINT32 offset;
342
- if ( fseek(fd_, 4, SEEK_SET) == -1 ) goto error;
343
- if ( fread(&offset, 4, 1, fd_) != 1 ) goto error;
344
- #ifdef __LITTLE_ENDIAN__
345
- swap32((unsigned char *)&offset);
346
- #endif
347
- dataOffset_ = offset;
348
-
349
- // Get length of data from the header.
350
- if ( fread(&fileSize_, 4, 1, fd_) != 1 ) goto error;
351
- #ifdef __LITTLE_ENDIAN__
352
- swap32((unsigned char *)&fileSize_);
353
- #endif
354
- // Convert to sample frames.
355
- if ( dataType_ == STK_SINT8 )
356
- fileSize_ /= channels_;
357
- if ( dataType_ == STK_SINT16 )
358
- fileSize_ /= 2 * channels_;
359
- else if ( dataType_ == STK_SINT24 )
360
- fileSize_ /= 3 * channels_;
361
- else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )
362
- fileSize_ /= 4 * channels_;
363
- else if ( dataType_ == STK_FLOAT64 )
364
- fileSize_ /= 8 * channels_;
365
-
366
- byteswap_ = false;
367
- #ifdef __LITTLE_ENDIAN__
368
- byteswap_ = true;
369
- #endif
370
-
371
- return true;
372
-
373
- error:
374
- oStream_ << "FileRead: Error reading SND file (" << fileName << ").";
375
- return false;
376
- }
377
-
378
- bool FileRead :: getAifInfo( const char *fileName )
379
- {
380
- bool aifc = false;
381
- char id[4];
382
-
383
- // Determine whether this is AIFF or AIFC.
384
- if ( fseek(fd_, 8, SEEK_SET) == -1 ) goto error;
385
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
386
- if ( !strncmp(id, "AIFC", 4) ) aifc = true;
387
-
388
- // Find "common" chunk
389
- SINT32 chunkSize;
390
- if ( fread(&id, 4, 1, fd_) != 1) goto error;
391
- while ( strncmp(id, "COMM", 4) ) {
392
- if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
393
- #ifdef __LITTLE_ENDIAN__
394
- swap32((unsigned char *)&chunkSize);
395
- #endif
396
- chunkSize += chunkSize % 2; // chunk sizes must be even
397
- if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
398
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
399
- }
400
-
401
- // Get number of channels from the header.
402
- SINT16 temp;
403
- if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error; // Jump over chunk size
404
- if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
405
- #ifdef __LITTLE_ENDIAN__
406
- swap16((unsigned char *)&temp);
407
- #endif
408
- channels_ = temp;
409
-
410
- // Get length of data from the header.
411
- SINT32 frames;
412
- if ( fread(&frames, 4, 1, fd_) != 1 ) goto error;
413
- #ifdef __LITTLE_ENDIAN__
414
- swap32((unsigned char *)&frames);
415
- #endif
416
- fileSize_ = frames; // sample frames
417
-
418
- // Read the number of bits per sample.
419
- if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
420
- #ifdef __LITTLE_ENDIAN__
421
- swap16((unsigned char *)&temp);
422
- #endif
423
-
424
- // Get file sample rate from the header. For AIFF files, this value
425
- // is stored in a 10-byte, IEEE Standard 754 floating point number,
426
- // so we need to convert it first.
427
- unsigned char srate[10];
428
- unsigned char exp;
429
- unsigned long mantissa;
430
- unsigned long last;
431
- if ( fread(&srate, 10, 1, fd_) != 1 ) goto error;
432
- mantissa = (unsigned long) *(unsigned long *)(srate+2);
433
- #ifdef __LITTLE_ENDIAN__
434
- swap32((unsigned char *)&mantissa);
435
- #endif
436
- exp = 30 - *(srate+1);
437
- last = 0;
438
- while (exp--) {
439
- last = mantissa;
440
- mantissa >>= 1;
441
- }
442
- if (last & 0x00000001) mantissa++;
443
- fileRate_ = (StkFloat) mantissa;
444
-
445
- byteswap_ = false;
446
- #ifdef __LITTLE_ENDIAN__
447
- byteswap_ = true;
448
- #endif
449
-
450
- // Determine the data format.
451
- dataType_ = 0;
452
- if ( aifc == false ) {
453
- if ( temp <= 8 ) dataType_ = STK_SINT8;
454
- else if ( temp <= 16 ) dataType_ = STK_SINT16;
455
- else if ( temp <= 24 ) dataType_ = STK_SINT24;
456
- else if ( temp <= 32 ) dataType_ = STK_SINT32;
457
- }
458
- else {
459
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
460
- if ( !strncmp(id, "sowt", 4) ) { // uncompressed little-endian
461
- if ( byteswap_ == false ) byteswap_ = true;
462
- else byteswap_ = false;
463
- }
464
- if ( !strncmp(id, "NONE", 4) || !strncmp(id, "sowt", 4) ) {
465
- if ( temp <= 8 ) dataType_ = STK_SINT8;
466
- else if ( temp <= 16 ) dataType_ = STK_SINT16;
467
- else if ( temp <= 24 ) dataType_ = STK_SINT24;
468
- else if ( temp <= 32 ) dataType_ = STK_SINT32;
469
- }
470
- else if ( (!strncmp(id, "fl32", 4) || !strncmp(id, "FL32", 4)) && temp == 32 ) dataType_ = STK_FLOAT32;
471
- else if ( (!strncmp(id, "fl64", 4) || !strncmp(id, "FL64", 4)) && temp == 64 ) dataType_ = STK_FLOAT64;
472
- }
473
- if ( dataType_ == 0 ) {
474
- oStream_ << "FileRead: AIFF/AIFC file (" << fileName << ") has unsupported data type (" << id << ").";
475
- return false;
476
- }
477
-
478
- // Start at top to find data (SSND) chunk ... chunk order is undefined.
479
- if ( fseek(fd_, 12, SEEK_SET) == -1 ) goto error;
480
-
481
- // Find data (SSND) chunk
482
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
483
- while ( strncmp(id, "SSND", 4) ) {
484
- if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
485
- #ifdef __LITTLE_ENDIAN__
486
- swap32((unsigned char *)&chunkSize);
487
- #endif
488
- chunkSize += chunkSize % 2; // chunk sizes must be even
489
- if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
490
- if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
491
- }
492
-
493
- // Skip over chunk size, offset, and blocksize fields
494
- if ( fseek(fd_, 12, SEEK_CUR) == -1 ) goto error;
495
-
496
- dataOffset_ = ftell(fd_);
497
- return true;
498
-
499
- error:
500
- oStream_ << "FileRead: Error reading AIFF file (" << fileName << ").";
501
- return false;
502
- }
503
-
504
- bool FileRead :: findNextMatArray( SINT32 *chunkSize, SINT32 *rows, SINT32 *columns, SINT32 *nametype )
505
- {
506
- // Look for the next data array element. The file pointer should be
507
- // at the data element type when this function is called.
508
- SINT32 datatype;
509
- *chunkSize = 0;
510
- do {
511
- if ( fseek(fd_, *chunkSize, SEEK_CUR) == -1 ) return false;
512
- if ( fread(&datatype, 4, 1, fd_) != 1 ) return false;
513
- if ( byteswap_ ) swap32((unsigned char *)&datatype);
514
- if ( fread(chunkSize, 4, 1, fd_) != 1 ) return false;
515
- if ( byteswap_ ) swap32((unsigned char *)chunkSize);
516
- } while ( datatype != 14 );
517
-
518
- // Check dimension subelement size to make sure 2D
519
- if ( fseek(fd_, 20, SEEK_CUR) == -1 ) return false;
520
- SINT32 size;
521
- if ( fread(&size, 4, 1, fd_) != 1 ) return false;
522
- if ( byteswap_ ) swap32((unsigned char *)&size);
523
- if ( size != 8 ) return false;
524
-
525
- // Read dimensions data
526
- if ( fread(rows, 4, 1, fd_) != 1 ) return false;
527
- if ( byteswap_ ) swap32((unsigned char *)rows);
528
- if ( fread(columns, 4, 1, fd_) != 1 ) return false;
529
- if ( byteswap_ ) swap32((unsigned char *)columns);
530
-
531
- // Read array name subelement type
532
- if ( fread(nametype, 4, 1, fd_) != 1 ) return false;
533
- if ( byteswap_ ) swap32((unsigned char *)nametype);
534
-
535
- return true;
536
- }
537
-
538
- bool FileRead :: getMatInfo( const char *fileName )
539
- {
540
- // MAT-file formatting information is available at:
541
- // http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf
542
-
543
- // Verify this is a version 5 MAT-file format.
544
- char head[5];
545
- if ( fseek(fd_, 0, SEEK_SET) == -1 ) goto error;
546
- if ( fread(&head, 4, 1, fd_) != 1 ) goto error;
547
- // If any of the first 4 characters of the header = 0, then this is
548
- // a Version 4 MAT-file.
549
- head[4] = '\0';
550
- if ( strstr(head, "0") ) {
551
- oStream_ << "FileRead: " << fileName << " appears to be a Version 4 MAT-file, which is not currently supported.";
552
- return false;
553
- }
554
-
555
- // Determine the endian-ness of the file.
556
- char mi[2];
557
- byteswap_ = false;
558
- // Locate "M" and "I" characters in header.
559
- if ( fseek(fd_, 126, SEEK_SET) == -1 ) goto error;
560
- if ( fread(&mi, 2, 1, fd_) != 1) goto error;
561
- #ifdef __LITTLE_ENDIAN__
562
- if ( !strncmp(mi, "MI", 2) )
563
- byteswap_ = true;
564
- else if ( strncmp(mi, "IM", 2) ) goto error;
565
- #else
566
- if ( !strncmp(mi, "IM", 2))
567
- byteswap_ = true;
568
- else if ( strncmp(mi, "MI", 2) ) goto error;
569
- #endif
570
-
571
- // We are expecting a data element containing the audio data and an
572
- // optional data element containing the sample rate (with an array
573
- // name of "fs"). Both elements should be stored as a Matlab array
574
- // type (14).
575
-
576
- bool doneParsing, haveData, haveSampleRate;
577
- SINT32 chunkSize, rows, columns, nametype;
578
- long dataoffset;
579
- doneParsing = false;
580
- haveData = false;
581
- haveSampleRate = false;
582
- while ( !doneParsing ) {
583
-
584
- dataoffset = ftell( fd_ ); // save location in file
585
- if ( findNextMatArray( &chunkSize, &rows, &columns, &nametype ) == false ) {
586
- // No more Matlab array type chunks found.
587
- if ( !haveData ) {
588
- oStream_ << "FileRead: No audio data found in MAT-file (" << fileName << ").";
589
- return false;
590
- }
591
- else if ( !haveSampleRate ) {
592
- fileRate_ = 44100.0;
593
- oStream_ << "FileRead: No sample rate found ... assuming 44100.0";
594
- handleError( StkError::WARNING );
595
- return true;
596
- }
597
- else return true;
598
- }
599
-
600
- if ( !haveSampleRate && rows == 1 && columns == 1 ) { // Parse for sample rate.
601
-
602
- SINT32 namesize = 4;
603
- if ( nametype == 1 ) { // array name > 4 characters
604
- if ( fread(&namesize, 4, 1, fd_) != 1 ) goto error;
605
- if ( byteswap_ ) swap32((unsigned char *)&namesize);
606
- if ( namesize != 2 ) goto tryagain; // expecting name = "fs"
607
- namesize = 8; // field must be padded to multiple of 8 bytes
608
- }
609
- char name[3]; name[2] = '\0';
610
- if ( fread(&name, 2, 1, fd_) != 1) goto error;
611
- if ( strncmp(name, "fs", 2) ) goto tryagain;
612
-
613
- // Jump to real part data subelement, which is likely to be in a
614
- // small data format.
615
- if ( fseek(fd_, namesize-2, SEEK_CUR) == -1 ) goto error;
616
- UINT32 type;
617
- StkFloat srate;
618
- if ( fread(&type, 4, 1, fd_) != 1 ) goto error;
619
- if ( byteswap_ ) swap32((unsigned char *)&type);
620
- if ( (type & 0xffff0000) != 0 ) // small data format
621
- type = (type & 0x0000ffff);
622
- else
623
- if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error;
624
- if ( type == 1 ) { // SINT8
625
- signed char rate;
626
- if ( fread(&rate, 1, 1, fd_) != 1 ) goto error;
627
- srate = (StkFloat) rate;
628
- }
629
- else if ( type == 2 ) { // UINT8
630
- unsigned char rate;
631
- if ( fread(&rate, 1, 1, fd_) != 1 ) goto error;
632
- srate = (StkFloat) rate;
633
- }
634
- else if ( type == 3 ) { // SINT16
635
- SINT16 rate;
636
- if ( fread(&rate, 2, 1, fd_) != 1 ) goto error;
637
- if ( byteswap_ ) swap16((unsigned char *)&rate);
638
- srate = (StkFloat) rate;
639
- }
640
- else if ( type == 4 ) { // UINT16
641
- UINT16 rate;
642
- if ( fread(&rate, 2, 1, fd_) != 1 ) goto error;
643
- if ( byteswap_ ) swap16((unsigned char *)&rate);
644
- srate = (StkFloat) rate;
645
- }
646
- else if ( type == 5 ) { // SINT32
647
- SINT32 rate;
648
- if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
649
- if ( byteswap_ ) swap32((unsigned char *)&rate);
650
- srate = (StkFloat) rate;
651
- }
652
- else if ( type == 6 ) { // UINT32
653
- UINT32 rate;
654
- if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
655
- if ( byteswap_ ) swap32((unsigned char *)&rate);
656
- srate = (StkFloat) rate;
657
- }
658
- else if ( type == 7 ) { // FLOAT32
659
- FLOAT32 rate;
660
- if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
661
- if ( byteswap_ ) swap32((unsigned char *)&rate);
662
- srate = (StkFloat) rate;
663
- }
664
- else if ( type == 9 ) { // FLOAT64
665
- FLOAT64 rate;
666
- if ( fread(&rate, 8, 1, fd_) != 1 ) goto error;
667
- if ( byteswap_ ) swap64((unsigned char *)&rate);
668
- srate = (StkFloat) rate;
669
- }
670
- else
671
- goto tryagain;
672
-
673
- if ( srate > 0 ) fileRate_ = srate;
674
- haveSampleRate = true;
675
- }
676
- else if ( !haveData ) { // Parse for data.
677
-
678
- // Assume channels = smaller of rows or columns.
679
- if ( rows < columns ) {
680
- channels_ = rows;
681
- fileSize_ = columns;
682
- }
683
- else {
684
- oStream_ << "FileRead: Transpose the MAT-file array so that audio channels fill matrix rows (not columns).";
685
- return false;
686
- }
687
-
688
- SINT32 namesize = 4;
689
- if ( nametype == 1 ) { // array name > 4 characters
690
- if ( fread(&namesize, 4, 1, fd_) != 1 ) goto error;
691
- if ( byteswap_ ) swap32((unsigned char *)&namesize);
692
- namesize = (SINT32) ceil((float)namesize / 8);
693
- if ( fseek( fd_, namesize*8, SEEK_CUR) == -1 ) goto error; // jump over array name
694
- }
695
- else {
696
- if ( fseek( fd_, 4, SEEK_CUR ) == -1 ) goto error;
697
- }
698
-
699
- // Now at real part data subelement
700
- SINT32 type;
701
- if ( fread(&type, 4, 1, fd_) != 1 ) goto error;
702
- if ( byteswap_ ) swap32((unsigned char *)&type);
703
- if ( type == 1 ) dataType_ = STK_SINT8;
704
- else if ( type == 3 ) dataType_ = STK_SINT16;
705
- else if ( type == 5 ) dataType_ = STK_SINT32;
706
- else if ( type == 7 ) dataType_ = STK_FLOAT32;
707
- else if ( type == 9 ) dataType_ = STK_FLOAT64;
708
- else {
709
- oStream_ << "FileRead: The MAT-file array data format (" << type << ") is not supported.";
710
- return false;
711
- }
712
-
713
- // Jump to the data.
714
- if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error;
715
- dataOffset_ = ftell(fd_);
716
- haveData = true;
717
- }
718
-
719
- tryagain:
720
- if ( haveData && haveSampleRate ) doneParsing = true;
721
- else // jump to end of data element and keep trying
722
- if ( fseek( fd_, dataoffset+chunkSize+8, SEEK_SET) == -1 ) goto error;
723
- }
724
-
725
- return true;
726
-
727
- error:
728
- oStream_ << "FileRead: Error reading MAT-file (" << fileName << ") header.";
729
- return false;
730
- }
731
-
732
- void FileRead :: read( StkFrames& buffer, unsigned long startFrame, bool doNormalize )
733
- {
734
- // Make sure we have an open file.
735
- if ( fd_ == 0 ) {
736
- oStream_ << "FileRead::read: a file is not open!";
737
- Stk::handleError( StkError::WARNING ); return;
738
- }
739
-
740
- // Check the buffer size.
741
- unsigned long nFrames = buffer.frames();
742
- if ( nFrames == 0 ) {
743
- oStream_ << "FileRead::read: StkFrames buffer size is zero ... no data read!";
744
- Stk::handleError( StkError::WARNING ); return;
745
- }
746
-
747
- if ( buffer.channels() != channels_ ) {
748
- oStream_ << "FileRead::read: StkFrames argument has incompatible number of channels!";
749
- Stk::handleError( StkError::FUNCTION_ARGUMENT );
750
- }
751
-
752
- if ( startFrame >= fileSize_ ) {
753
- oStream_ << "FileRead::read: startFrame argument is greater than or equal to the file size!";
754
- Stk::handleError( StkError::FUNCTION_ARGUMENT );
755
- }
756
-
757
- // Check for file end.
758
- if ( startFrame + nFrames > fileSize_ )
759
- nFrames = fileSize_ - startFrame;
760
-
761
- long i, nSamples = (long) ( nFrames * channels_ );
762
- unsigned long offset = startFrame * channels_;
763
-
764
- // Read samples into StkFrames data buffer.
765
- if ( dataType_ == STK_SINT16 ) {
766
- SINT16 *buf = (SINT16 *) &buffer[0];
767
- if ( fseek( fd_, dataOffset_+(offset*2), SEEK_SET ) == -1 ) goto error;
768
- if ( fread( buf, nSamples * 2, 1, fd_ ) != 1 ) goto error;
769
- if ( byteswap_ ) {
770
- SINT16 *ptr = buf;
771
- for ( i=nSamples-1; i>=0; i-- )
772
- swap16( (unsigned char *) ptr++ );
773
- }
774
- if ( doNormalize ) {
775
- StkFloat gain = 1.0 / 32768.0;
776
- for ( i=nSamples-1; i>=0; i-- )
777
- buffer[i] = buf[i] * gain;
778
- }
779
- else {
780
- for ( i=nSamples-1; i>=0; i-- )
781
- buffer[i] = buf[i];
782
- }
783
- }
784
- else if ( dataType_ == STK_SINT32 ) {
785
- SINT32 *buf = (SINT32 *) &buffer[0];
786
- if ( fseek( fd_, dataOffset_+(offset*4 ), SEEK_SET ) == -1 ) goto error;
787
- if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error;
788
- if ( byteswap_ ) {
789
- SINT32 *ptr = buf;
790
- for ( i=nSamples-1; i>=0; i-- )
791
- swap32( (unsigned char *) ptr++ );
792
- }
793
- if ( doNormalize ) {
794
- StkFloat gain = 1.0 / 2147483648.0;
795
- for ( i=nSamples-1; i>=0; i-- )
796
- buffer[i] = buf[i] * gain;
797
- }
798
- else {
799
- for ( i=nSamples-1; i>=0; i-- )
800
- buffer[i] = buf[i];
801
- }
802
- }
803
- else if ( dataType_ == STK_FLOAT32 ) {
804
- FLOAT32 *buf = (FLOAT32 *) &buffer[0];
805
- if ( fseek( fd_, dataOffset_+(offset*4), SEEK_SET ) == -1 ) goto error;
806
- if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error;
807
- if ( byteswap_ ) {
808
- FLOAT32 *ptr = buf;
809
- for ( i=nSamples-1; i>=0; i-- )
810
- swap32( (unsigned char *) ptr++ );
811
- }
812
- for ( i=nSamples-1; i>=0; i-- )
813
- buffer[i] = buf[i];
814
- }
815
- else if ( dataType_ == STK_FLOAT64 ) {
816
- FLOAT64 *buf = (FLOAT64 *) &buffer[0];
817
- if ( fseek( fd_, dataOffset_+(offset*8), SEEK_SET ) == -1 ) goto error;
818
- if ( fread( buf, nSamples * 8, 1, fd_ ) != 1 ) goto error;
819
- if ( byteswap_ ) {
820
- FLOAT64 *ptr = buf;
821
- for ( i=nSamples-1; i>=0; i-- )
822
- swap64( (unsigned char *) ptr++ );
823
- }
824
- for ( i=nSamples-1; i>=0; i-- )
825
- buffer[i] = buf[i];
826
- }
827
- else if ( dataType_ == STK_SINT8 && wavFile_ ) { // 8-bit WAV data is unsigned!
828
- unsigned char *buf = (unsigned char *) &buffer[0];
829
- if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error;
830
- if ( fread( buf, nSamples, 1, fd_) != 1 ) goto error;
831
- if ( doNormalize ) {
832
- StkFloat gain = 1.0 / 128.0;
833
- for ( i=nSamples-1; i>=0; i-- )
834
- buffer[i] = ( buf[i] - 128 ) * gain;
835
- }
836
- else {
837
- for ( i=nSamples-1; i>=0; i-- )
838
- buffer[i] = buf[i] - 128.0;
839
- }
840
- }
841
- else if ( dataType_ == STK_SINT8 ) { // signed 8-bit data
842
- char *buf = (char *) &buffer[0];
843
- if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error;
844
- if ( fread( buf, nSamples, 1, fd_ ) != 1 ) goto error;
845
- if ( doNormalize ) {
846
- StkFloat gain = 1.0 / 128.0;
847
- for ( i=nSamples-1; i>=0; i-- )
848
- buffer[i] = buf[i] * gain;
849
- }
850
- else {
851
- for ( i=nSamples-1; i>=0; i-- )
852
- buffer[i] = buf[i];
853
- }
854
- }
855
- else if ( dataType_ == STK_SINT24 ) {
856
- // 24-bit values are harder to import efficiently since there is
857
- // no native 24-bit type. The following routine works but is much
858
- // less efficient than that used for the other data types.
859
- SINT32 temp;
860
- unsigned char *ptr = (unsigned char *) &temp;
861
- StkFloat gain = 1.0 / 2147483648.0;
862
- if ( fseek(fd_, dataOffset_+(offset*3), SEEK_SET ) == -1 ) goto error;
863
- for ( i=0; i<nSamples; i++ ) {
864
- #ifdef __LITTLE_ENDIAN__
865
- if ( byteswap_ ) {
866
- if ( fread( ptr, 3, 1, fd_ ) != 1 ) goto error;
867
- temp &= 0x00ffffff;
868
- swap32( (unsigned char *) ptr );
869
- }
870
- else {
871
- if ( fread( ptr+1, 3, 1, fd_ ) != 1 ) goto error;
872
- temp &= 0xffffff00;
873
- }
874
- #else
875
- if ( byteswap_ ) {
876
- if ( fread( ptr+1, 3, 1, fd_ ) != 1 ) goto error;
877
- temp &= 0xffffff00;
878
- swap32( (unsigned char *) ptr );
879
- }
880
- else {
881
- if ( fread( ptr, 3, 1, fd_ ) != 1 ) goto error;
882
- temp &= 0x00ffffff;
883
- }
884
- #endif
885
-
886
- if ( doNormalize ) {
887
- buffer[i] = (StkFloat) temp * gain; // "gain" also includes 1 / 256 factor.
888
- }
889
- else
890
- buffer[i] = (StkFloat) temp / 256; // right shift without affecting the sign bit
891
- }
892
- }
893
-
894
- buffer.setDataRate( fileRate_ );
895
-
896
- return;
897
-
898
- error:
899
- oStream_ << "FileRead: Error reading file data.";
900
- handleError( StkError::FILE_ERROR);
901
- }
902
-
903
- } // stk namespace