beeps 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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