beeps 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.doc/ext/beeps/beeps.cpp +46 -0
  3. data/.doc/ext/beeps/file_in.cpp +59 -0
  4. data/.doc/ext/beeps/native.cpp +41 -0
  5. data/.doc/ext/beeps/processor.cpp +49 -0
  6. data/.doc/ext/beeps/sawtooth_wave.cpp +66 -0
  7. data/.doc/ext/beeps/sine_wave.cpp +66 -0
  8. data/.doc/ext/beeps/sound.cpp +69 -0
  9. data/.doc/ext/beeps/square_wave.cpp +66 -0
  10. data/README.md +4 -0
  11. data/Rakefile +27 -0
  12. data/VERSION +1 -0
  13. data/beeps.gemspec +43 -0
  14. data/ext/beeps/beeps.cpp +48 -0
  15. data/ext/beeps/defs.h +13 -0
  16. data/ext/beeps/extconf.rb +25 -0
  17. data/ext/beeps/file_in.cpp +61 -0
  18. data/ext/beeps/native.cpp +41 -0
  19. data/ext/beeps/processor.cpp +50 -0
  20. data/ext/beeps/sawtooth_wave.cpp +69 -0
  21. data/ext/beeps/sine_wave.cpp +69 -0
  22. data/ext/beeps/sound.cpp +72 -0
  23. data/ext/beeps/square_wave.cpp +69 -0
  24. data/include/beeps.h +12 -0
  25. data/include/beeps/beeps.h +25 -0
  26. data/include/beeps/defs.h +23 -0
  27. data/include/beeps/exception.h +47 -0
  28. data/include/beeps/openal.h +34 -0
  29. data/include/beeps/processor.h +132 -0
  30. data/include/beeps/ruby.h +10 -0
  31. data/include/beeps/ruby/beeps.h +21 -0
  32. data/include/beeps/ruby/processor.h +86 -0
  33. data/include/beeps/ruby/sound.h +42 -0
  34. data/include/beeps/signals.h +53 -0
  35. data/include/beeps/sound.h +44 -0
  36. data/lib/beeps.rb +9 -0
  37. data/lib/beeps/autoinit.rb +10 -0
  38. data/lib/beeps/beeps.rb +49 -0
  39. data/lib/beeps/ext.rb +4 -0
  40. data/lib/beeps/module.rb +49 -0
  41. data/lib/beeps/processor.rb +60 -0
  42. data/lib/beeps/sound.rb +19 -0
  43. data/src/beeps.cpp +93 -0
  44. data/src/exception.cpp +43 -0
  45. data/src/openal.cpp +216 -0
  46. data/src/openal.h +25 -0
  47. data/src/processor.cpp +201 -0
  48. data/src/signals.cpp +90 -0
  49. data/src/sound.cpp +125 -0
  50. data/src/stk/include/Blit.h +151 -0
  51. data/src/stk/include/BlitSaw.h +148 -0
  52. data/src/stk/include/BlitSquare.h +170 -0
  53. data/src/stk/include/FileRead.h +141 -0
  54. data/src/stk/include/FileWvIn.h +195 -0
  55. data/src/stk/include/Generator.h +50 -0
  56. data/src/stk/include/SineWave.h +159 -0
  57. data/src/stk/include/Stk.h +589 -0
  58. data/src/stk/include/WvIn.h +46 -0
  59. data/src/stk/src/Blit.cpp +78 -0
  60. data/src/stk/src/BlitSaw.cpp +91 -0
  61. data/src/stk/src/BlitSquare.cpp +95 -0
  62. data/src/stk/src/FileRead.cpp +903 -0
  63. data/src/stk/src/FileWvIn.cpp +260 -0
  64. data/src/stk/src/SineWave.cpp +78 -0
  65. data/src/stk/src/Stk.cpp +395 -0
  66. data/test/helper.rb +17 -0
  67. data/test/test_beeps.rb +18 -0
  68. data/test/test_sound.rb +26 -0
  69. metadata +177 -0
@@ -0,0 +1,170 @@
1
+ #ifndef STK_BLITSQUARE_H
2
+ #define STK_BLITSQUARE_H
3
+
4
+ #include "Generator.h"
5
+ #include <cmath>
6
+ #include <limits>
7
+
8
+ namespace stk {
9
+
10
+ /***************************************************/
11
+ /*! \class BlitSquare
12
+ \brief STK band-limited square wave class.
13
+
14
+ This class generates a band-limited square wave signal. It is
15
+ derived in part from the approach reported by Stilson and Smith in
16
+ "Alias-Free Digital Synthesis of Classic Analog Waveforms", 1996.
17
+ The algorithm implemented in this class uses a SincM function with
18
+ an even M value to achieve a bipolar bandlimited impulse train.
19
+ This signal is then integrated to achieve a square waveform. The
20
+ integration process has an associated DC offset so a DC blocking
21
+ filter is applied at the output.
22
+
23
+ The user can specify both the fundamental frequency of the
24
+ waveform and the number of harmonics contained in the resulting
25
+ signal.
26
+
27
+ If nHarmonics is 0, then the signal will contain all harmonics up
28
+ to half the sample rate. Note, however, that this setting may
29
+ produce aliasing in the signal when the frequency is changing (no
30
+ automatic modification of the number of harmonics is performed by
31
+ the setFrequency() function). Also note that the harmonics of a
32
+ square wave fall at odd integer multiples of the fundamental, so
33
+ aliasing will happen with a lower fundamental than with the other
34
+ Blit waveforms. This class is not guaranteed to be well behaved
35
+ in the presence of significant aliasing.
36
+
37
+ Based on initial code of Robin Davies, 2005.
38
+ Modified algorithm code by Gary Scavone, 2005 - 2006.
39
+ */
40
+ /***************************************************/
41
+
42
+ class BlitSquare: public Generator
43
+ {
44
+ public:
45
+ //! Default constructor that initializes BLIT frequency to 220 Hz.
46
+ BlitSquare( StkFloat frequency = 220.0 );
47
+
48
+ //! Class destructor.
49
+ ~BlitSquare();
50
+
51
+ //! Resets the oscillator state and phase to 0.
52
+ void reset();
53
+
54
+ //! Set the phase of the signal.
55
+ /*!
56
+ Set the phase of the signal, in the range 0 to 1.
57
+ */
58
+ void setPhase( StkFloat phase ) { phase_ = PI * phase; };
59
+
60
+ //! Get the current phase of the signal.
61
+ /*!
62
+ Get the phase of the signal, in the range [0 to 1.0).
63
+ */
64
+ StkFloat getPhase() const { return phase_ / PI; };
65
+
66
+ //! Set the impulse train rate in terms of a frequency in Hz.
67
+ void setFrequency( StkFloat frequency );
68
+
69
+ //! Set the number of harmonics generated in the signal.
70
+ /*!
71
+ This function sets the number of harmonics contained in the
72
+ resulting signal. It is equivalent to (2 * M) + 1 in the BLIT
73
+ algorithm. The default value of 0 sets the algorithm for maximum
74
+ harmonic content (harmonics up to half the sample rate). This
75
+ parameter is not checked against the current sample rate and
76
+ fundamental frequency. Thus, aliasing can result if one or more
77
+ harmonics for a given fundamental frequency exceeds fs / 2. This
78
+ behavior was chosen over the potentially more problematic solution
79
+ of automatically modifying the M parameter, which can produce
80
+ audible clicks in the signal.
81
+ */
82
+ void setHarmonics( unsigned int nHarmonics = 0 );
83
+
84
+ //! Return the last computed output value.
85
+ StkFloat lastOut( void ) const { return lastFrame_[0]; };
86
+
87
+ //! Compute and return one output sample.
88
+ StkFloat tick( void );
89
+
90
+ //! Fill a channel of the StkFrames object with computed outputs.
91
+ /*!
92
+ The \c channel argument must be less than the number of
93
+ channels in the StkFrames argument (the first channel is specified
94
+ by 0). However, range checking is only performed if _STK_DEBUG_
95
+ is defined during compilation, in which case an out-of-range value
96
+ will trigger an StkError exception.
97
+ */
98
+ StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
99
+
100
+ protected:
101
+
102
+ void updateHarmonics( void );
103
+
104
+ unsigned int nHarmonics_;
105
+ unsigned int m_;
106
+ StkFloat rate_;
107
+ StkFloat phase_;
108
+ StkFloat p_;
109
+ StkFloat a_;
110
+ StkFloat lastBlitOutput_;
111
+ StkFloat dcbState_;
112
+ };
113
+
114
+ inline StkFloat BlitSquare :: tick( void )
115
+ {
116
+ StkFloat temp = lastBlitOutput_;
117
+
118
+ // A fully optimized version of this would replace the two sin calls
119
+ // with a pair of fast sin oscillators, for which stable fast
120
+ // two-multiply algorithms are well known. In the spirit of STK,
121
+ // which favors clarity over performance, the optimization has
122
+ // not been made here.
123
+
124
+ // Avoid a divide by zero, or use of a denomralized divisor
125
+ // at the sinc peak, which has a limiting value of 1.0.
126
+ StkFloat denominator = sin( phase_ );
127
+ if ( fabs( denominator ) < std::numeric_limits<StkFloat>::epsilon() ) {
128
+ // Inexact comparison safely distinguishes betwen *close to zero*, and *close to PI*.
129
+ if ( phase_ < 0.1f || phase_ > TWO_PI - 0.1f )
130
+ lastBlitOutput_ = a_;
131
+ else
132
+ lastBlitOutput_ = -a_;
133
+ }
134
+ else {
135
+ lastBlitOutput_ = sin( m_ * phase_ );
136
+ lastBlitOutput_ /= p_ * denominator;
137
+ }
138
+
139
+ lastBlitOutput_ += temp;
140
+
141
+ // Now apply DC blocker.
142
+ lastFrame_[0] = lastBlitOutput_ - dcbState_ + 0.999 * lastFrame_[0];
143
+ dcbState_ = lastBlitOutput_;
144
+
145
+ phase_ += rate_;
146
+ if ( phase_ >= TWO_PI ) phase_ -= TWO_PI;
147
+
148
+ return lastFrame_[0];
149
+ }
150
+
151
+ inline StkFrames& BlitSquare :: tick( StkFrames& frames, unsigned int channel )
152
+ {
153
+ #if defined(_STK_DEBUG_)
154
+ if ( channel >= frames.channels() ) {
155
+ oStream_ << "BlitSquare::tick(): channel and StkFrames arguments are incompatible!";
156
+ handleError( StkError::FUNCTION_ARGUMENT );
157
+ }
158
+ #endif
159
+
160
+ StkFloat *samples = &frames[channel];
161
+ unsigned int hop = frames.channels();
162
+ for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
163
+ *samples = BlitSquare::tick();
164
+
165
+ return frames;
166
+ }
167
+
168
+ } // stk namespace
169
+
170
+ #endif
@@ -0,0 +1,141 @@
1
+ #ifndef STK_FILEREAD_H
2
+ #define STK_FILEREAD_H
3
+
4
+ #include "Stk.h"
5
+
6
+ namespace stk {
7
+
8
+ /***************************************************/
9
+ /*! \class FileRead
10
+ \brief STK audio file input class.
11
+
12
+ This class provides input support for various
13
+ audio file formats. Multi-channel (>2)
14
+ soundfiles are supported. The file data is
15
+ returned via an external StkFrames object
16
+ passed to the read() function. This class
17
+ does not store its own copy of the file data,
18
+ rather the data is read directly from disk.
19
+
20
+ FileRead currently supports uncompressed WAV,
21
+ AIFF/AIFC, SND (AU), MAT-file (Matlab), and
22
+ STK RAW file formats. Signed integer (8-,
23
+ 16-, 24-, and 32-bit) and floating-point (32- and
24
+ 64-bit) data types are supported. Compressed
25
+ data types are not supported.
26
+
27
+ STK RAW files have no header and are assumed to
28
+ contain a monophonic stream of 16-bit signed
29
+ integers in big-endian byte order at a sample
30
+ rate of 22050 Hz. MAT-file data should be saved
31
+ in an array with each data channel filling a
32
+ matrix row. The sample rate for MAT-files should
33
+ be specified in a variable named "fs". If no
34
+ such variable is found, the sample rate is
35
+ assumed to be 44100 Hz.
36
+
37
+ by Perry R. Cook and Gary P. Scavone, 1995--2014.
38
+ */
39
+ /***************************************************/
40
+
41
+ class FileRead : public Stk
42
+ {
43
+ public:
44
+ //! Default constructor.
45
+ FileRead( void );
46
+
47
+ //! Overloaded constructor that opens a file during instantiation.
48
+ /*!
49
+ An StkError will be thrown if the file is not found or its
50
+ format is unknown or unsupported. The optional arguments allow a
51
+ headerless file type to be supported. If \c typeRaw is false (the
52
+ default), the subsequent parameters are ignored.
53
+ */
54
+ FileRead( std::string fileName, bool typeRaw = false, unsigned int nChannels = 1,
55
+ StkFormat format = STK_SINT16, StkFloat rate = 22050.0 );
56
+
57
+ //! Class destructor.
58
+ ~FileRead( void );
59
+
60
+ //! Open the specified file and determine its formatting.
61
+ /*!
62
+ An StkError will be thrown if the file is not found or its
63
+ format is unknown or unsupported. The optional arguments allow a
64
+ headerless file type to be supported. If \c typeRaw is false (the
65
+ default), the subsequent parameters are ignored.
66
+ */
67
+ void open( std::string fileName, bool typeRaw = false, unsigned int nChannels = 1,
68
+ StkFormat format = STK_SINT16, StkFloat rate = 22050.0 );
69
+
70
+ //! If a file is open, close it.
71
+ void close( void );
72
+
73
+ //! Returns \e true if a file is currently open.
74
+ bool isOpen( void );
75
+
76
+ //! Return the file size in sample frames.
77
+ unsigned long fileSize( void ) const { return fileSize_; };
78
+
79
+ //! Return the number of audio channels in the file.
80
+ unsigned int channels( void ) const { return channels_; };
81
+
82
+ //! Return the data format of the file.
83
+ StkFormat format( void ) const { return dataType_; };
84
+
85
+ //! Return the file sample rate in Hz.
86
+ /*!
87
+ WAV, SND, and AIF formatted files specify a sample rate in
88
+ their headers. By definition, STK RAW files have a sample rate of
89
+ 22050 Hz. MAT-files are assumed to have a rate of 44100 Hz.
90
+ */
91
+ StkFloat fileRate( void ) const { return fileRate_; };
92
+
93
+ //! Read sample frames from the file into an StkFrames object.
94
+ /*!
95
+ The number of sample frames to read will be determined from the
96
+ number of frames of the StkFrames argument. If this size is
97
+ larger than the available data in the file (given the file size
98
+ and starting frame index), the extra frames will be unaffected
99
+ (the StkFrames object will not be resized). Optional parameters
100
+ are provided to specify the starting sample frame within the file
101
+ (default = 0) and whether to normalize the data with respect to
102
+ fixed-point limits (default = true). An StkError will be thrown
103
+ if a file error occurs or if the number of channels in the
104
+ StkFrames argument is not equal to that in the file.
105
+ */
106
+ void read( StkFrames& buffer, unsigned long startFrame = 0, bool doNormalize = true );
107
+
108
+ protected:
109
+
110
+ // Get STK RAW file information.
111
+ bool getRawInfo( const char *fileName, unsigned int nChannels,
112
+ StkFormat format, StkFloat rate );
113
+
114
+ // Get WAV file header information.
115
+ bool getWavInfo( const char *fileName );
116
+
117
+ // Get SND (AU) file header information.
118
+ bool getSndInfo( const char *fileName );
119
+
120
+ // Get AIFF file header information.
121
+ bool getAifInfo( const char *fileName );
122
+
123
+ // Get MAT-file header information.
124
+ bool getMatInfo( const char *fileName );
125
+
126
+ // Helper function for MAT-file parsing.
127
+ bool findNextMatArray( SINT32 *chunkSize, SINT32 *rows, SINT32 *columns, SINT32 *nametype );
128
+
129
+ FILE *fd_;
130
+ bool byteswap_;
131
+ bool wavFile_;
132
+ unsigned long fileSize_;
133
+ unsigned long dataOffset_;
134
+ unsigned int channels_;
135
+ StkFormat dataType_;
136
+ StkFloat fileRate_;
137
+ };
138
+
139
+ } // stk namespace
140
+
141
+ #endif
@@ -0,0 +1,195 @@
1
+ #ifndef STK_FILEWVIN_H
2
+ #define STK_FILEWVIN_H
3
+
4
+ #include "WvIn.h"
5
+ #include "FileRead.h"
6
+
7
+ namespace stk {
8
+
9
+ /***************************************************/
10
+ /*! \class FileWvIn
11
+ \brief STK audio file input class.
12
+
13
+ This class inherits from WvIn. It provides a "tick-level"
14
+ interface to the FileRead class. It also provides variable-rate
15
+ playback functionality. Audio file support is provided by the
16
+ FileRead class. Linear interpolation is used for fractional read
17
+ rates.
18
+
19
+ FileWvIn supports multi-channel data. It is important to
20
+ distinguish the tick() method that computes a single frame (and
21
+ returns only the specified sample of a multi-channel frame) from
22
+ the overloaded one that takes an StkFrames object for
23
+ multi-channel and/or multi-frame data.
24
+
25
+ FileWvIn will either load the entire content of an audio file into
26
+ local memory or incrementally read file data from disk in chunks.
27
+ This behavior is controlled by the optional constructor arguments
28
+ \e chunkThreshold and \e chunkSize. File sizes greater than \e
29
+ chunkThreshold (in sample frames) will be read incrementally in
30
+ chunks of \e chunkSize each (also in sample frames).
31
+
32
+ When the file end is reached, subsequent calls to the tick()
33
+ functions return zeros and isFinished() returns \e true.
34
+
35
+ See the FileRead class for a description of the supported audio
36
+ file formats.
37
+
38
+ by Perry R. Cook and Gary P. Scavone, 1995--2014.
39
+ */
40
+ /***************************************************/
41
+
42
+ class FileWvIn : public WvIn
43
+ {
44
+ public:
45
+ //! Default constructor.
46
+ FileWvIn( unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
47
+
48
+ //! Overloaded constructor for file input.
49
+ /*!
50
+ An StkError will be thrown if the file is not found, its format is
51
+ unknown, or a read error occurs.
52
+ */
53
+ FileWvIn( std::string fileName, bool raw = false, bool doNormalize = true,
54
+ unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
55
+
56
+ //! Class destructor.
57
+ ~FileWvIn( void );
58
+
59
+ //! Open the specified file and load its data.
60
+ /*!
61
+ Data from a previously opened file will be overwritten by this
62
+ function. An StkError will be thrown if the file is not found,
63
+ its format is unknown, or a read error occurs. If the file data
64
+ is to be loaded incrementally from disk and normalization is
65
+ specified, a scaling will be applied with respect to fixed-point
66
+ limits. If the data format is floating-point, no scaling is
67
+ performed.
68
+ */
69
+ virtual void openFile( std::string fileName, bool raw = false, bool doNormalize = true );
70
+
71
+ //! Close a file if one is open.
72
+ virtual void closeFile( void );
73
+
74
+ //! Clear outputs and reset time (file) pointer to zero.
75
+ virtual void reset( void );
76
+
77
+ //! Normalize data to a maximum of +-1.0.
78
+ /*!
79
+ This function has no effect when data is incrementally loaded
80
+ from disk.
81
+ */
82
+ virtual void normalize( void );
83
+
84
+ //! Normalize data to a maximum of \e +-peak.
85
+ /*!
86
+ This function has no effect when data is incrementally loaded
87
+ from disk.
88
+ */
89
+ virtual void normalize( StkFloat peak );
90
+
91
+ //! Return the file size in sample frames.
92
+ virtual unsigned long getSize( void ) const { return file_.fileSize(); };
93
+
94
+ //! Return the input file sample rate in Hz (not the data read rate).
95
+ /*!
96
+ WAV, SND, and AIF formatted files specify a sample rate in
97
+ their headers. STK RAW files have a sample rate of 22050 Hz
98
+ by definition. MAT-files are assumed to have a rate of 44100 Hz.
99
+ */
100
+ virtual StkFloat getFileRate( void ) const { return data_.dataRate(); };
101
+
102
+ //! Query whether a file is open.
103
+ bool isOpen( void ) { return file_.isOpen(); };
104
+
105
+ //! Query whether reading is complete.
106
+ bool isFinished( void ) const { return finished_; };
107
+
108
+ //! Set the data read rate in samples. The rate can be negative.
109
+ /*!
110
+ If the rate value is negative, the data is read in reverse order.
111
+ */
112
+ virtual void setRate( StkFloat rate );
113
+
114
+ //! Increment the read pointer by \e time samples.
115
+ /*!
116
+ Note that this function will not modify the interpolation flag status.
117
+ */
118
+ virtual void addTime( StkFloat time );
119
+
120
+ //! Turn linear interpolation on/off.
121
+ /*!
122
+ Interpolation is automatically off when the read rate is
123
+ an integer value. If interpolation is turned off for a
124
+ fractional rate, the time index is truncated to an integer
125
+ value.
126
+ */
127
+ void setInterpolate( bool doInterpolate ) { interpolate_ = doInterpolate; };
128
+
129
+ //! Return the specified channel value of the last computed frame.
130
+ /*!
131
+ If no file is loaded, the returned value is 0.0. The \c
132
+ channel argument must be less than the number of output channels,
133
+ which can be determined with the channelsOut() function (the first
134
+ channel is specified by 0). However, range checking is only
135
+ performed if _STK_DEBUG_ is defined during compilation, in which
136
+ case an out-of-range value will trigger an StkError exception. \sa
137
+ lastFrame()
138
+ */
139
+ StkFloat lastOut( unsigned int channel = 0 );
140
+
141
+ //! Compute a sample frame and return the specified \c channel value.
142
+ /*!
143
+ For multi-channel files, use the lastFrame() function to get
144
+ all values from the computed frame. If no file data is loaded,
145
+ the returned value is 0.0. The \c channel argument must be less
146
+ than the number of channels in the file data (the first channel is
147
+ specified by 0). However, range checking is only performed if
148
+ _STK_DEBUG_ is defined during compilation, in which case an
149
+ out-of-range value will trigger an StkError exception.
150
+ */
151
+ virtual StkFloat tick( unsigned int channel = 0 );
152
+
153
+ //! Fill the StkFrames object with computed sample frames, starting at the specified channel and return the same reference.
154
+ /*!
155
+ The \c channel argument plus the number of input channels must
156
+ be less than the number of channels in the StkFrames argument (the
157
+ first channel is specified by 0). However, range checking is only
158
+ performed if _STK_DEBUG_ is defined during compilation, in which
159
+ case an out-of-range value will trigger an StkError exception.
160
+ */
161
+ virtual StkFrames& tick( StkFrames& frames,unsigned int channel = 0 );
162
+
163
+ protected:
164
+
165
+ void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
166
+
167
+ FileRead file_;
168
+ bool finished_;
169
+ bool interpolate_;
170
+ bool normalizing_;
171
+ bool chunking_;
172
+ StkFloat time_;
173
+ StkFloat rate_;
174
+ unsigned long chunkThreshold_;
175
+ unsigned long chunkSize_;
176
+ long chunkPointer_;
177
+
178
+ };
179
+
180
+ inline StkFloat FileWvIn :: lastOut( unsigned int channel )
181
+ {
182
+ #if defined(_STK_DEBUG_)
183
+ if ( channel >= data_.channels() ) {
184
+ oStream_ << "FileWvIn::lastOut(): channel argument and soundfile data are incompatible!";
185
+ handleError( StkError::FUNCTION_ARGUMENT );
186
+ }
187
+ #endif
188
+
189
+ if ( finished_ ) return 0.0;
190
+ return lastFrame_[channel];
191
+ }
192
+
193
+ } // stk namespace
194
+
195
+ #endif