beeps 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.doc/ext/beeps/beeps.cpp +46 -0
- data/.doc/ext/beeps/file_in.cpp +59 -0
- data/.doc/ext/beeps/native.cpp +41 -0
- data/.doc/ext/beeps/processor.cpp +49 -0
- data/.doc/ext/beeps/sawtooth_wave.cpp +66 -0
- data/.doc/ext/beeps/sine_wave.cpp +66 -0
- data/.doc/ext/beeps/sound.cpp +69 -0
- data/.doc/ext/beeps/square_wave.cpp +66 -0
- data/README.md +4 -0
- data/Rakefile +27 -0
- data/VERSION +1 -0
- data/beeps.gemspec +43 -0
- data/ext/beeps/beeps.cpp +48 -0
- data/ext/beeps/defs.h +13 -0
- data/ext/beeps/extconf.rb +25 -0
- data/ext/beeps/file_in.cpp +61 -0
- data/ext/beeps/native.cpp +41 -0
- data/ext/beeps/processor.cpp +50 -0
- data/ext/beeps/sawtooth_wave.cpp +69 -0
- data/ext/beeps/sine_wave.cpp +69 -0
- data/ext/beeps/sound.cpp +72 -0
- data/ext/beeps/square_wave.cpp +69 -0
- data/include/beeps.h +12 -0
- data/include/beeps/beeps.h +25 -0
- data/include/beeps/defs.h +23 -0
- data/include/beeps/exception.h +47 -0
- data/include/beeps/openal.h +34 -0
- data/include/beeps/processor.h +132 -0
- data/include/beeps/ruby.h +10 -0
- data/include/beeps/ruby/beeps.h +21 -0
- data/include/beeps/ruby/processor.h +86 -0
- data/include/beeps/ruby/sound.h +42 -0
- data/include/beeps/signals.h +53 -0
- data/include/beeps/sound.h +44 -0
- data/lib/beeps.rb +9 -0
- data/lib/beeps/autoinit.rb +10 -0
- data/lib/beeps/beeps.rb +49 -0
- data/lib/beeps/ext.rb +4 -0
- data/lib/beeps/module.rb +49 -0
- data/lib/beeps/processor.rb +60 -0
- data/lib/beeps/sound.rb +19 -0
- data/src/beeps.cpp +93 -0
- data/src/exception.cpp +43 -0
- data/src/openal.cpp +216 -0
- data/src/openal.h +25 -0
- data/src/processor.cpp +201 -0
- data/src/signals.cpp +90 -0
- data/src/sound.cpp +125 -0
- data/src/stk/include/Blit.h +151 -0
- data/src/stk/include/BlitSaw.h +148 -0
- data/src/stk/include/BlitSquare.h +170 -0
- data/src/stk/include/FileRead.h +141 -0
- data/src/stk/include/FileWvIn.h +195 -0
- data/src/stk/include/Generator.h +50 -0
- data/src/stk/include/SineWave.h +159 -0
- data/src/stk/include/Stk.h +589 -0
- data/src/stk/include/WvIn.h +46 -0
- data/src/stk/src/Blit.cpp +78 -0
- data/src/stk/src/BlitSaw.cpp +91 -0
- data/src/stk/src/BlitSquare.cpp +95 -0
- data/src/stk/src/FileRead.cpp +903 -0
- data/src/stk/src/FileWvIn.cpp +260 -0
- data/src/stk/src/SineWave.cpp +78 -0
- data/src/stk/src/Stk.cpp +395 -0
- data/test/helper.rb +17 -0
- data/test/test_beeps.rb +18 -0
- data/test/test_sound.rb +26 -0
- metadata +177 -0
data/src/exception.cpp
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#include "beeps/exception.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include <xot/string.h>
|
5
|
+
|
6
|
+
|
7
|
+
namespace Beeps
|
8
|
+
{
|
9
|
+
|
10
|
+
|
11
|
+
BeepsError::BeepsError (const char* str)
|
12
|
+
: Super(str)
|
13
|
+
{
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
OpenALError::OpenALError (const char* str)
|
18
|
+
: Super(str)
|
19
|
+
{
|
20
|
+
}
|
21
|
+
|
22
|
+
|
23
|
+
namespace ErrorFunctions
|
24
|
+
{
|
25
|
+
|
26
|
+
void
|
27
|
+
beeps_error (const char* file, int line, const char* format, ...)
|
28
|
+
{
|
29
|
+
XOT_STRINGF(format, s);
|
30
|
+
throw BeepsError(Xot::error_text(file, line, s));
|
31
|
+
}
|
32
|
+
|
33
|
+
void
|
34
|
+
openal_error (const char* file, int line, const char* format, ...)
|
35
|
+
{
|
36
|
+
XOT_STRINGF(format, s);
|
37
|
+
throw OpenALError(Xot::error_text(file, line, s));
|
38
|
+
}
|
39
|
+
|
40
|
+
}// ErrorFunctions
|
41
|
+
|
42
|
+
|
43
|
+
}// Beeps
|
data/src/openal.cpp
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
#include "beeps/openal.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include <vector>
|
5
|
+
#include <xot/debug.h>
|
6
|
+
#include "beeps/defs.h"
|
7
|
+
#include "beeps/sound.h"
|
8
|
+
#include "beeps/exception.h"
|
9
|
+
#include "openal.h"
|
10
|
+
|
11
|
+
|
12
|
+
#if 0
|
13
|
+
#define LOG(...) doutln(__VA_ARGS__)
|
14
|
+
#else
|
15
|
+
#define LOG(...)
|
16
|
+
#endif
|
17
|
+
|
18
|
+
|
19
|
+
namespace Beeps
|
20
|
+
{
|
21
|
+
|
22
|
+
|
23
|
+
ALCdevice* get_device ();
|
24
|
+
|
25
|
+
|
26
|
+
ALCenum
|
27
|
+
get_error ()
|
28
|
+
{
|
29
|
+
return alcGetError(get_device());
|
30
|
+
}
|
31
|
+
|
32
|
+
bool
|
33
|
+
no_error ()
|
34
|
+
{
|
35
|
+
return get_error() == ALC_NO_ERROR;
|
36
|
+
}
|
37
|
+
|
38
|
+
bool
|
39
|
+
is_error (ALCenum err)
|
40
|
+
{
|
41
|
+
return get_error() == err;
|
42
|
+
}
|
43
|
+
|
44
|
+
static String
|
45
|
+
get_error_name (ALenum error)
|
46
|
+
{
|
47
|
+
switch (error)
|
48
|
+
{
|
49
|
+
case ALC_NO_ERROR: return "ALC_NO_ERROR";
|
50
|
+
case ALC_INVALID_DEVICE: return "ALC_INVALID_DEVICE";
|
51
|
+
case ALC_INVALID_CONTEXT: return "ALC_INVALID_CONTEXT";
|
52
|
+
case ALC_INVALID_ENUM: return "ALC_INVALID_ENUM";
|
53
|
+
case ALC_OUT_OF_MEMORY: return "ALC_OUT_OF_MEMORY";
|
54
|
+
}
|
55
|
+
return "UNKNOWN ERROR";
|
56
|
+
}
|
57
|
+
|
58
|
+
void
|
59
|
+
check_error (const char* file, int line)
|
60
|
+
{
|
61
|
+
ALCenum e = get_error();
|
62
|
+
if (e != ALC_NO_ERROR)
|
63
|
+
openal_error(file, line, "OpenAL error %s", get_error_name(e).c_str());
|
64
|
+
}
|
65
|
+
|
66
|
+
void
|
67
|
+
clear_error ()
|
68
|
+
{
|
69
|
+
get_error();
|
70
|
+
}
|
71
|
+
|
72
|
+
|
73
|
+
struct SoundSource
|
74
|
+
{
|
75
|
+
|
76
|
+
typedef SoundSource This;
|
77
|
+
|
78
|
+
typedef boost::shared_ptr<This> Ptr;
|
79
|
+
|
80
|
+
ALint id;
|
81
|
+
|
82
|
+
static Ptr create ()
|
83
|
+
{
|
84
|
+
ALuint id_;
|
85
|
+
alGenSources(1, &id_);
|
86
|
+
if (!no_error()) return Ptr();
|
87
|
+
|
88
|
+
This* p = new This;
|
89
|
+
p->id = id_;
|
90
|
+
return Ptr(p);
|
91
|
+
}
|
92
|
+
|
93
|
+
SoundSource ()
|
94
|
+
: id(-1)
|
95
|
+
{
|
96
|
+
}
|
97
|
+
|
98
|
+
~SoundSource ()
|
99
|
+
{
|
100
|
+
if (!*this) return;
|
101
|
+
|
102
|
+
ALuint id_ = id;
|
103
|
+
alDeleteSources(1, &id_);
|
104
|
+
check_error(__FILE__, __LINE__);
|
105
|
+
}
|
106
|
+
|
107
|
+
void play (const Sound& sound)
|
108
|
+
{
|
109
|
+
if (!sound)
|
110
|
+
argument_error(__FILE__, __LINE__);
|
111
|
+
|
112
|
+
if (!*this)
|
113
|
+
invalid_state_error(__FILE__, __LINE__);
|
114
|
+
|
115
|
+
alSourcei(id, AL_BUFFER, get_sound_buffer_id(sound));
|
116
|
+
alSourcePlay(id);
|
117
|
+
check_error(__FILE__, __LINE__);
|
118
|
+
}
|
119
|
+
|
120
|
+
void stop ()
|
121
|
+
{
|
122
|
+
if (!*this)
|
123
|
+
invalid_state_error(__FILE__, __LINE__);
|
124
|
+
|
125
|
+
alSourceStop(id);
|
126
|
+
check_error(__FILE__, __LINE__);
|
127
|
+
}
|
128
|
+
|
129
|
+
bool is_playing () const
|
130
|
+
{
|
131
|
+
if (!*this) return false;
|
132
|
+
|
133
|
+
ALint state = 0;
|
134
|
+
alGetSourcei(id, AL_SOURCE_STATE, &state);
|
135
|
+
check_error(__FILE__, __LINE__);
|
136
|
+
|
137
|
+
return state == AL_PLAYING;
|
138
|
+
}
|
139
|
+
|
140
|
+
operator bool () const
|
141
|
+
{
|
142
|
+
return id >= 0;
|
143
|
+
}
|
144
|
+
|
145
|
+
bool operator ! () const
|
146
|
+
{
|
147
|
+
return !operator bool();
|
148
|
+
}
|
149
|
+
|
150
|
+
};// SoundSource
|
151
|
+
|
152
|
+
|
153
|
+
typedef std::vector<SoundSource::Ptr> SoundSourceList;
|
154
|
+
|
155
|
+
static SoundSourceList sources;
|
156
|
+
|
157
|
+
|
158
|
+
static SoundSource*
|
159
|
+
next_source ()
|
160
|
+
{
|
161
|
+
SoundSource::Ptr source;
|
162
|
+
for (SoundSourceList::iterator it = sources.begin(); it != sources.end(); ++it)
|
163
|
+
{
|
164
|
+
const SoundSource::Ptr& p = *it;
|
165
|
+
if (p && *p && !p->is_playing())
|
166
|
+
{
|
167
|
+
source = p;
|
168
|
+
sources.erase(it);
|
169
|
+
LOG("reuse source");
|
170
|
+
break;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
if (!source)
|
175
|
+
{
|
176
|
+
source = SoundSource::create();
|
177
|
+
LOG("new source");
|
178
|
+
}
|
179
|
+
|
180
|
+
if (!source)
|
181
|
+
{
|
182
|
+
source = *sources.begin();
|
183
|
+
if (source) source->stop();
|
184
|
+
sources.erase(sources.begin());
|
185
|
+
LOG("stop and reuse oldest source");
|
186
|
+
}
|
187
|
+
|
188
|
+
if (!source)
|
189
|
+
return NULL;
|
190
|
+
|
191
|
+
sources.push_back(source);
|
192
|
+
return source.get();
|
193
|
+
}
|
194
|
+
|
195
|
+
void
|
196
|
+
play_sound (const Sound& sound)
|
197
|
+
{
|
198
|
+
if (!sound)
|
199
|
+
argument_error(__FILE__, __LINE__);
|
200
|
+
|
201
|
+
SoundSource* source = next_source();
|
202
|
+
if (!source || !*source)
|
203
|
+
invalid_state_error(__FILE__, __LINE__);
|
204
|
+
|
205
|
+
source->play(sound);
|
206
|
+
|
207
|
+
#if 0
|
208
|
+
std::string ox = "";
|
209
|
+
for (size_t i = 0; i < sources.size(); ++i)
|
210
|
+
ox += sources[i]->is_playing() ? 'o' : 'x';
|
211
|
+
LOG("playing with %d sources. (%s)", sources.size(), ox.c_str());
|
212
|
+
#endif
|
213
|
+
}
|
214
|
+
|
215
|
+
|
216
|
+
}// Beeps
|
data/src/openal.h
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
// -*- c++ -*-
|
2
|
+
#pragma once
|
3
|
+
#ifndef __BEEPS_SRC_OPENAL_H__
|
4
|
+
#define __BEEPS_SRC_OPENAL_H__
|
5
|
+
|
6
|
+
|
7
|
+
#include <beeps/openal.h>
|
8
|
+
|
9
|
+
|
10
|
+
namespace Beeps
|
11
|
+
{
|
12
|
+
|
13
|
+
|
14
|
+
class Sound;
|
15
|
+
|
16
|
+
|
17
|
+
void play_sound (const Sound& sound);
|
18
|
+
|
19
|
+
ALuint get_sound_buffer_id (const Sound& sound);
|
20
|
+
|
21
|
+
|
22
|
+
}// Beeps
|
23
|
+
|
24
|
+
|
25
|
+
#endif//EOH
|
data/src/processor.cpp
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
#include "beeps/processor.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include "SineWave.h"
|
5
|
+
#include "BlitSaw.h"
|
6
|
+
#include "BlitSquare.h"
|
7
|
+
#include "FileWvIn.h"
|
8
|
+
#include "beeps/signals.h"
|
9
|
+
#include "beeps/exception.h"
|
10
|
+
|
11
|
+
|
12
|
+
namespace Beeps
|
13
|
+
{
|
14
|
+
|
15
|
+
|
16
|
+
Processor::Processor ()
|
17
|
+
{
|
18
|
+
}
|
19
|
+
|
20
|
+
Processor::~Processor ()
|
21
|
+
{
|
22
|
+
}
|
23
|
+
|
24
|
+
void
|
25
|
+
Processor::process (Signals* signals)
|
26
|
+
{
|
27
|
+
if (!signals || !*signals)
|
28
|
+
argument_error(__FILE__, __LINE__);
|
29
|
+
|
30
|
+
if (!*this)
|
31
|
+
invalid_state_error(__FILE__, __LINE__);
|
32
|
+
}
|
33
|
+
|
34
|
+
Processor::operator bool () const
|
35
|
+
{
|
36
|
+
return true;
|
37
|
+
}
|
38
|
+
|
39
|
+
bool
|
40
|
+
Processor::operator ! () const
|
41
|
+
{
|
42
|
+
return !operator bool();
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
struct SineWave::Data
|
47
|
+
{
|
48
|
+
|
49
|
+
stk::SineWave oscillator;
|
50
|
+
|
51
|
+
float frequency;
|
52
|
+
|
53
|
+
};// SineWave::Data
|
54
|
+
|
55
|
+
|
56
|
+
SineWave::SineWave ()
|
57
|
+
{
|
58
|
+
set_frequency(440);
|
59
|
+
}
|
60
|
+
|
61
|
+
SineWave::~SineWave ()
|
62
|
+
{
|
63
|
+
}
|
64
|
+
|
65
|
+
void
|
66
|
+
SineWave::set_frequency (float frequency)
|
67
|
+
{
|
68
|
+
self->frequency = frequency;
|
69
|
+
self->oscillator.setFrequency(frequency);
|
70
|
+
}
|
71
|
+
|
72
|
+
float
|
73
|
+
SineWave::frequency () const
|
74
|
+
{
|
75
|
+
return self->frequency;
|
76
|
+
}
|
77
|
+
|
78
|
+
void
|
79
|
+
SineWave::process (Signals* signals)
|
80
|
+
{
|
81
|
+
Super::process(signals);
|
82
|
+
|
83
|
+
self->oscillator.tick(*signals->frames());
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
struct SquareWave::Data
|
88
|
+
{
|
89
|
+
|
90
|
+
stk::BlitSquare oscillator;
|
91
|
+
|
92
|
+
float frequency;
|
93
|
+
|
94
|
+
};// SquareWave::Data
|
95
|
+
|
96
|
+
|
97
|
+
SquareWave::SquareWave ()
|
98
|
+
{
|
99
|
+
set_frequency(440);
|
100
|
+
}
|
101
|
+
|
102
|
+
SquareWave::~SquareWave ()
|
103
|
+
{
|
104
|
+
}
|
105
|
+
|
106
|
+
void
|
107
|
+
SquareWave::set_frequency (float frequency)
|
108
|
+
{
|
109
|
+
self->frequency = frequency;
|
110
|
+
self->oscillator.setFrequency(frequency);
|
111
|
+
}
|
112
|
+
|
113
|
+
float
|
114
|
+
SquareWave::frequency () const
|
115
|
+
{
|
116
|
+
return self->frequency;
|
117
|
+
}
|
118
|
+
|
119
|
+
void
|
120
|
+
SquareWave::process (Signals* signals)
|
121
|
+
{
|
122
|
+
Super::process(signals);
|
123
|
+
|
124
|
+
self->oscillator.tick(*signals->frames());
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
struct SawtoothWave::Data
|
129
|
+
{
|
130
|
+
|
131
|
+
stk::BlitSaw oscillator;
|
132
|
+
|
133
|
+
float frequency;
|
134
|
+
|
135
|
+
};// SawtoothWave::Data
|
136
|
+
|
137
|
+
|
138
|
+
SawtoothWave::SawtoothWave ()
|
139
|
+
{
|
140
|
+
set_frequency(440);
|
141
|
+
}
|
142
|
+
|
143
|
+
SawtoothWave::~SawtoothWave ()
|
144
|
+
{
|
145
|
+
}
|
146
|
+
|
147
|
+
void
|
148
|
+
SawtoothWave::set_frequency (float frequency)
|
149
|
+
{
|
150
|
+
self->frequency = frequency;
|
151
|
+
self->oscillator.setFrequency(frequency);
|
152
|
+
}
|
153
|
+
|
154
|
+
float
|
155
|
+
SawtoothWave::frequency () const
|
156
|
+
{
|
157
|
+
return self->frequency;
|
158
|
+
}
|
159
|
+
|
160
|
+
void
|
161
|
+
SawtoothWave::process (Signals* signals)
|
162
|
+
{
|
163
|
+
Super::process(signals);
|
164
|
+
|
165
|
+
self->oscillator.tick(*signals->frames());
|
166
|
+
}
|
167
|
+
|
168
|
+
|
169
|
+
struct FileIn::Data
|
170
|
+
{
|
171
|
+
|
172
|
+
stk::FileWvIn input;
|
173
|
+
|
174
|
+
};// FileIn::Data
|
175
|
+
|
176
|
+
|
177
|
+
FileIn::FileIn (const char* path)
|
178
|
+
{
|
179
|
+
if (path)
|
180
|
+
self->input.openFile(path);
|
181
|
+
}
|
182
|
+
|
183
|
+
FileIn::~FileIn ()
|
184
|
+
{
|
185
|
+
}
|
186
|
+
|
187
|
+
void
|
188
|
+
FileIn::process (Signals* signals)
|
189
|
+
{
|
190
|
+
Super::process(signals);
|
191
|
+
|
192
|
+
self->input.tick(*signals->frames());
|
193
|
+
}
|
194
|
+
|
195
|
+
FileIn::operator bool () const
|
196
|
+
{
|
197
|
+
return self->input.isOpen();
|
198
|
+
}
|
199
|
+
|
200
|
+
|
201
|
+
}// Beeps
|