beeps 0.1.31 → 0.1.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/beeps/adsr.cpp +139 -0
  3. data/.doc/ext/beeps/analyser.cpp +128 -0
  4. data/.doc/ext/beeps/beeps.cpp +9 -1
  5. data/.doc/ext/beeps/file_in.cpp +55 -9
  6. data/.doc/ext/beeps/gain.cpp +64 -0
  7. data/.doc/ext/beeps/mic_in.cpp +83 -0
  8. data/.doc/ext/beeps/native.cpp +20 -8
  9. data/.doc/ext/beeps/oscillator.cpp +88 -0
  10. data/.doc/ext/beeps/pitch_shift.cpp +64 -0
  11. data/.doc/ext/beeps/processor.cpp +31 -2
  12. data/.doc/ext/beeps/sound.cpp +90 -7
  13. data/.doc/ext/beeps/sound_player.cpp +156 -0
  14. data/.doc/ext/beeps/time_stretch.cpp +64 -0
  15. data/.github/workflows/release-gem.yml +62 -0
  16. data/.github/workflows/test.yml +0 -6
  17. data/.github/workflows/utils.rb +13 -5
  18. data/ChangeLog.md +13 -0
  19. data/Rakefile +27 -6
  20. data/VERSION +1 -1
  21. data/beeps.gemspec +2 -2
  22. data/ext/beeps/adsr.cpp +150 -0
  23. data/ext/beeps/analyser.cpp +134 -0
  24. data/ext/beeps/beeps.cpp +10 -1
  25. data/ext/beeps/extconf.rb +1 -2
  26. data/ext/beeps/file_in.cpp +60 -9
  27. data/ext/beeps/gain.cpp +67 -0
  28. data/ext/beeps/mic_in.cpp +88 -0
  29. data/ext/beeps/native.cpp +20 -8
  30. data/ext/beeps/oscillator.cpp +93 -0
  31. data/ext/beeps/pitch_shift.cpp +67 -0
  32. data/ext/beeps/processor.cpp +34 -2
  33. data/ext/beeps/sound.cpp +99 -7
  34. data/ext/beeps/sound_player.cpp +169 -0
  35. data/ext/beeps/time_stretch.cpp +67 -0
  36. data/include/beeps/beeps.h +2 -1
  37. data/include/beeps/filter.h +179 -0
  38. data/include/beeps/generator.h +120 -0
  39. data/include/beeps/processor.h +37 -68
  40. data/include/beeps/ruby/filter.h +78 -0
  41. data/include/beeps/ruby/generator.h +60 -0
  42. data/include/beeps/ruby/processor.h +5 -45
  43. data/include/beeps/ruby/sound.h +14 -3
  44. data/include/beeps/signals.h +10 -4
  45. data/include/beeps/sound.h +67 -2
  46. data/lib/beeps/beeps.rb +6 -1
  47. data/lib/beeps/processor.rb +95 -15
  48. data/lib/beeps/sound.rb +29 -2
  49. data/src/adsr.cpp +245 -0
  50. data/src/analyser.cpp +254 -0
  51. data/src/beeps.cpp +11 -2
  52. data/src/file_in.cpp +94 -0
  53. data/src/gain.cpp +55 -0
  54. data/src/mic_in.cpp +262 -0
  55. data/src/mic_in.h +20 -0
  56. data/src/openal.cpp +2 -1
  57. data/src/oscillator.cpp +145 -0
  58. data/src/osx/signals.mm +83 -0
  59. data/src/pitch_shift.cpp +82 -0
  60. data/src/processor.cpp +202 -88
  61. data/src/processor.h +98 -0
  62. data/src/signals.cpp +326 -20
  63. data/src/signals.h +192 -2
  64. data/src/sound.cpp +735 -113
  65. data/src/sound.h +6 -1
  66. data/src/time_stretch.cpp +91 -0
  67. data/test/helper.rb +2 -1
  68. data/test/test_beeps.rb +10 -7
  69. data/test/test_beeps_init.rb +18 -0
  70. data/test/test_file_in.rb +15 -0
  71. data/test/test_processor.rb +50 -0
  72. data/test/test_sound.rb +87 -11
  73. data/test/test_sound_player.rb +134 -0
  74. metadata +55 -17
  75. data/.doc/ext/beeps/sawtooth_wave.cpp +0 -61
  76. data/.doc/ext/beeps/sine_wave.cpp +0 -61
  77. data/.doc/ext/beeps/square_wave.cpp +0 -61
  78. data/.github/workflows/release.yml +0 -34
  79. data/ext/beeps/sawtooth_wave.cpp +0 -64
  80. data/ext/beeps/sine_wave.cpp +0 -64
  81. data/ext/beeps/square_wave.cpp +0 -64
@@ -2,6 +2,7 @@
2
2
 
3
3
 
4
4
  require 'xot/setter'
5
+ require 'xot/const_symbol_accessor'
5
6
  require 'xot/universal_accessor'
6
7
  require 'xot/block_util'
7
8
  require 'beeps/ext'
@@ -14,43 +15,122 @@ module Beeps
14
15
 
15
16
  include Xot::Setter
16
17
 
17
- def initialize(options = nil, &block)
18
+ def initialize(**options, &block)
18
19
  super()
19
- set options if options
20
+ set options unless options.empty?
20
21
  Xot::BlockUtil.instance_eval_or_block_call self, &block if block
21
22
  end
22
23
 
24
+ def >>(o)
25
+ o.input = self
26
+ o
27
+ end
28
+
29
+ def <<(o)
30
+ self.input = o
31
+ o
32
+ end
33
+
34
+ universal_accessor :input
35
+
23
36
  end# Processor
24
37
 
25
38
 
26
- class SineWave
39
+ class Oscillator
40
+
41
+ const_symbol_accessor :type, **{
42
+ none: NONE,
43
+ sine: SINE,
44
+ triangle: TRIANGLE,
45
+ square: SQUARE,
46
+ sawtooth: SAWTOOTH
47
+ }
48
+
49
+ def initialize(type = :sine, *args, **kwargs, &block)
50
+ super(*args, **kwargs, &block)
51
+ self.type = type
52
+ end
27
53
 
28
54
  alias freq= frequency=
29
55
  alias freq frequency
30
56
 
31
- universal_accessor :frequency, :freq
57
+ universal_accessor :type, :frequency, :freq
32
58
 
33
- end# SineWave
59
+ end# Oscillator
34
60
 
35
61
 
36
- class SquareWave
62
+ class FileIn
37
63
 
38
- alias freq= frequency=
39
- alias freq frequency
64
+ def initialize(path = nil, *args, **kwargs, &block)
65
+ super(*args, **kwargs, &block)
66
+ self.path = path if path
67
+ end
40
68
 
41
- universal_accessor :frequency, :freq
69
+ universal_accessor :path
42
70
 
43
- end# SquareWave
71
+ end# FileIn
44
72
 
45
73
 
46
- class SawtoothWave
74
+ class Gain
47
75
 
48
- alias freq= frequency=
49
- alias freq frequency
76
+ universal_accessor :gain
77
+
78
+ end# Gain
79
+
80
+
81
+ class ADSR
82
+
83
+ def note_on(delay = 0)
84
+ note_on! delay
85
+ end
86
+
87
+ def note_off(delay = 0)
88
+ note_off! delay
89
+ end
90
+
91
+ universal_accessor :attack_time, :decay_time, :sustain_level, :release_time
92
+
93
+ alias attack= attack_time=
94
+ alias attack attack_time
95
+ alias decay= decay_time=
96
+ alias decay decay_time
97
+ alias sustain= sustain_level=
98
+ alias sustain sustain_level
99
+ alias release= release_time=
100
+ alias release release_time
101
+
102
+ end# ADSR
103
+
104
+
105
+ class TimeStretch
106
+
107
+ universal_accessor :scale
108
+
109
+ end# TimeStretch
110
+
111
+
112
+ class PitchShift
113
+
114
+ universal_accessor :shift
115
+
116
+ end# PitchShift
117
+
118
+
119
+ class Analyser
120
+
121
+ def each_signal(nsamples = fft_size, &block)
122
+ return enum_for(:each_signal, nsamples) unless block
123
+ each_signal!(nsamples, &block)
124
+ end
125
+
126
+ def each_spectrum(&block)
127
+ return enum_for(:each_spectrum) unless block
128
+ each_spectrum!(&block)
129
+ end
50
130
 
51
- universal_accessor :frequency, :freq
131
+ universal_accessor :fft_size
52
132
 
53
- end# SawtoothWave
133
+ end# Analyser
54
134
 
55
135
 
56
136
  end# Beeps
data/lib/beeps/sound.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
 
4
+ require 'xot/setter'
5
+ require 'xot/universal_accessor'
6
+ require 'xot/block_util'
4
7
  require 'beeps/ext'
5
8
 
6
9
 
@@ -9,11 +12,35 @@ module Beeps
9
12
 
10
13
  class Sound
11
14
 
12
- def self.load(path)
13
- Sound.new FileIn.new(path), 1
15
+ include Xot::Setter
16
+
17
+ def initialize(
18
+ processor, seconds = 0, nchannels: 1, sample_rate: 0, **options, &block)
19
+
20
+ setup processor, seconds, nchannels, sample_rate
21
+ set(**options) unless options.empty?
22
+ Xot::BlockUtil.instance_eval_or_block_call self, &block if block
14
23
  end
15
24
 
25
+ def play(**options, &block)
26
+ play!.tap do |player|
27
+ player.set(**options) unless options.empty?
28
+ Xot::BlockUtil.instance_eval_or_block_call player, &block if block
29
+ end
30
+ end
31
+
32
+ universal_accessor :gain, :loop
33
+
16
34
  end# Sound
17
35
 
18
36
 
37
+ class SoundPlayer
38
+
39
+ include Xot::Setter
40
+
41
+ universal_accessor :gain, :loop
42
+
43
+ end# SoundPlayer
44
+
45
+
19
46
  end# Beeps
data/src/adsr.cpp ADDED
@@ -0,0 +1,245 @@
1
+ #include "beeps/filter.h"
2
+
3
+
4
+ #include <ADSR.h>
5
+ #include "signals.h"
6
+
7
+
8
+ namespace Beeps
9
+ {
10
+
11
+
12
+ struct ADSR::Data
13
+ {
14
+
15
+ stk::ADSR adsr;
16
+
17
+ Signals adsr_signals;
18
+
19
+ float attack_time = 0, decay_time = 0, sustain_level = 1, release_time = 0;
20
+
21
+ float time = 0, note_on_time = -1, note_off_time = -1;
22
+
23
+ void update_envelope ()
24
+ {
25
+ adsr.setAttackTime( attack_time == 0 ? 0.01 : attack_time);
26
+ adsr.setSustainLevel(sustain_level);
27
+ adsr.setDecayTime( decay_time == 0 ? 0.01 : decay_time);
28
+ adsr.setReleaseTime( release_time == 0 ? 0.01 : release_time);
29
+ }
30
+
31
+ };// ADSR::Data
32
+
33
+
34
+ ADSR::ADSR (Processor* input)
35
+ : Super(input)
36
+ {
37
+ self->update_envelope();
38
+ }
39
+
40
+ ADSR::~ADSR ()
41
+ {
42
+ }
43
+
44
+ void
45
+ ADSR::note_on (float delay)
46
+ {
47
+ if (delay < 0)
48
+ argument_error(__FILE__, __LINE__);
49
+
50
+ float on = self->time + delay, off = self->note_off_time;
51
+ if (0 <= off && off < on)
52
+ self->note_off_time = -1;
53
+
54
+ self->note_on_time = on;
55
+
56
+ set_updated();
57
+ }
58
+
59
+ void
60
+ ADSR::note_off (float delay)
61
+ {
62
+ if (delay < 0)
63
+ argument_error(__FILE__, __LINE__);
64
+
65
+ float off = self->time + delay, on = self->note_on_time;
66
+ if (0 <= on && off < on)
67
+ argument_error(__FILE__, __LINE__);
68
+
69
+ self->note_off_time = off;
70
+
71
+ set_updated();
72
+ }
73
+
74
+ void
75
+ ADSR::set_attack_time (float time)
76
+ {
77
+ if (time < 0)
78
+ argument_error(__FILE__, __LINE__);
79
+
80
+ self->attack_time = time;
81
+ self->update_envelope();
82
+
83
+ set_updated();
84
+ }
85
+
86
+ float
87
+ ADSR::attack_time () const
88
+ {
89
+ return self->attack_time;
90
+ }
91
+
92
+ void
93
+ ADSR::set_decay_time (float time)
94
+ {
95
+ if (time < 0)
96
+ argument_error(__FILE__, __LINE__);
97
+
98
+ self->decay_time = time;
99
+ self->update_envelope();
100
+
101
+ set_updated();
102
+ }
103
+
104
+ float
105
+ ADSR::decay_time () const
106
+ {
107
+ return self->decay_time;
108
+ }
109
+
110
+ void
111
+ ADSR::set_sustain_level (float level)
112
+ {
113
+ if (level < 0)
114
+ argument_error(__FILE__, __LINE__);
115
+
116
+ self->sustain_level = level;
117
+ self->update_envelope();
118
+
119
+ set_updated();
120
+ }
121
+
122
+ float
123
+ ADSR::sustain_level () const
124
+ {
125
+ return self->sustain_level;
126
+ }
127
+
128
+ void
129
+ ADSR::set_release_time (float time)
130
+ {
131
+ if (time < 0)
132
+ argument_error(__FILE__, __LINE__);
133
+
134
+ self->release_time = time;
135
+ self->update_envelope();
136
+
137
+ set_updated();
138
+ }
139
+
140
+ float
141
+ ADSR::release_time () const
142
+ {
143
+ return self->release_time;
144
+ }
145
+
146
+ static size_t
147
+ slice (Frames* frames, size_t start, float length_sec = -1)
148
+ {
149
+ Float sample_rate = frames->dataRate();
150
+ size_t len = length_sec >= 0
151
+ ? length_sec * sample_rate
152
+ : frames->nframes() - start;
153
+ assert(0 < len && (start + len) < frames->nsamples());
154
+
155
+ return frames->slice(start, len);
156
+ }
157
+
158
+ static void
159
+ process_envelope_signals (ADSR* adsr, Signals* signals)
160
+ {
161
+ assert(adsr && signals && signals->nchannels() == 1);
162
+
163
+ ADSR::Data* self = adsr->self.get();
164
+
165
+ Frames* frames = Signals_get_frames(signals);
166
+ assert(frames);
167
+
168
+ float start = self->time;
169
+ float end = start + Signals_get_seconds(*signals);
170
+ self->time = end;
171
+
172
+ float on = self->note_on_time;
173
+ float off = self->note_off_time;
174
+ assert(on <= off);
175
+
176
+ bool has_on = 0 <= on && start <= on && on < end;
177
+ bool has_off = 0 <= off && start <= off && off < end;
178
+
179
+ if (!has_on && !has_off)
180
+ {
181
+ self->adsr.tick(*frames);
182
+ return;
183
+ }
184
+
185
+ size_t last = 0;
186
+ if (has_on)
187
+ {
188
+ if (start < on)
189
+ {
190
+ last = slice(frames, 0, on - start);
191
+ self->adsr.tick(*frames);
192
+ frames->unslice();
193
+ }
194
+ self->adsr.keyOn();
195
+ }
196
+ if (has_on || has_off)
197
+ {
198
+ float len = has_off ? off - (has_on ? on : start) : -1;
199
+ last = slice(frames, last, len);
200
+ self->adsr.tick(*frames);
201
+ frames->unslice();
202
+ }
203
+ if (has_off)
204
+ {
205
+ self->adsr.keyOff();
206
+ if (off < end)
207
+ {
208
+ slice(frames, last, -1);
209
+ self->adsr.tick(*frames);
210
+ frames->unslice();
211
+ }
212
+ }
213
+ }
214
+
215
+ void
216
+ ADSR::filter (Context* context, Signals* signals, uint* offset)
217
+ {
218
+ Super::filter(context, signals, offset);
219
+
220
+ if (!self->adsr_signals)
221
+ {
222
+ self->adsr_signals =
223
+ Signals_create(signals->nsamples(), 1, signals->sample_rate());
224
+ }
225
+
226
+ if (self->adsr_signals.nsamples() != signals->nsamples())
227
+ Signals_resize(&self->adsr_signals, signals->nsamples(), 0);
228
+
229
+ process_envelope_signals(this, &self->adsr_signals);
230
+ Signals_apply(signals, self->adsr_signals);
231
+ }
232
+
233
+ ADSR::operator bool () const
234
+ {
235
+ if (!Super::operator bool()) return false;
236
+ return
237
+ self->attack_time >= 0 &&
238
+ self->decay_time >= 0 &&
239
+ self->sustain_level >= 0 &&
240
+ self->release_time >= 0 &&
241
+ self->time >= 0;
242
+ }
243
+
244
+
245
+ }// Beeps
data/src/analyser.cpp ADDED
@@ -0,0 +1,254 @@
1
+ #include "beeps/filter.h"
2
+
3
+
4
+ #include <math.h>
5
+ #include <algorithm>
6
+ #include "pffft.h"
7
+ #include "beeps/beeps.h"
8
+ #include "beeps/exception.h"
9
+ #include "signals.h"
10
+
11
+
12
+ namespace Beeps
13
+ {
14
+
15
+
16
+ struct PFFFTDestroySetup
17
+ {
18
+ void operator () (PFFFT_Setup* ptr)
19
+ {
20
+ pffft_destroy_setup(ptr);
21
+ }
22
+ };
23
+
24
+ struct PFFFTAlignedFree
25
+ {
26
+ void operator () (float* ptr)
27
+ {
28
+ pffft_aligned_free(ptr);
29
+ }
30
+ };
31
+
32
+
33
+ struct Analyser::Data
34
+ {
35
+
36
+ Signals signals;
37
+
38
+ Spectrum spectrum;
39
+
40
+ std::unique_ptr<PFFFT_Setup, PFFFTDestroySetup> pffft;
41
+
42
+ std::unique_ptr<float[], PFFFTAlignedFree> fft_buffer;
43
+
44
+ uint fft_size = 0;
45
+
46
+ ~Data ()
47
+ {
48
+ clear();
49
+ }
50
+
51
+ void setup (uint size)
52
+ {
53
+ if (size == fft_size) return;
54
+
55
+ clear();
56
+
57
+ signals = Signals_create(std::min(size, (uint) Beeps::sample_rate()));
58
+ pffft .reset(pffft_new_setup(size, PFFFT_REAL));
59
+ fft_buffer.reset((float*) pffft_aligned_malloc(sizeof(float) * size));
60
+ fft_size = size;
61
+ }
62
+
63
+ void clear ()
64
+ {
65
+ if (!pffft) return;
66
+
67
+ signals = Signals();
68
+ spectrum .clear();
69
+ pffft .reset();
70
+ fft_buffer.reset();
71
+ fft_size = 0;
72
+ }
73
+
74
+ bool is_valid () const
75
+ {
76
+ return signals && pffft && fft_buffer && fft_size > 0;
77
+ }
78
+
79
+ };// Analyser::Data
80
+
81
+
82
+ Analyser::Analyser (uint fft_size, Processor* input)
83
+ : Super(input)
84
+ {
85
+ set_fft_size(fft_size);
86
+ }
87
+
88
+ Analyser::~Analyser ()
89
+ {
90
+ }
91
+
92
+ static bool
93
+ is_valid_fft_size (uint size)
94
+ {
95
+ if (size < 32) return false;
96
+
97
+ while (size > 1)
98
+ {
99
+ if (size % 2 == 0) size /= 2;
100
+ else if (size % 3 == 0) size /= 3;
101
+ else if (size % 5 == 0) size /= 5;
102
+ else break;
103
+ }
104
+ return size == 1;
105
+ }
106
+
107
+ void
108
+ Analyser::set_fft_size (uint size)
109
+ {
110
+ if (!is_valid_fft_size(size))
111
+ beeps_error(__FILE__, __LINE__, "fft_size must be divisible by 2, 3, or 5");
112
+
113
+ self->setup(size);
114
+ }
115
+
116
+ uint
117
+ Analyser::fft_size () const
118
+ {
119
+ return self->fft_size;
120
+ }
121
+
122
+ float
123
+ Analyser::resolution () const
124
+ {
125
+ if (self->fft_size == 0) return 0;
126
+ return self->signals.sample_rate() / self->fft_size;
127
+ }
128
+
129
+ const Signals&
130
+ Analyser::signals () const
131
+ {
132
+ return self->signals;
133
+ }
134
+
135
+ static void
136
+ copy_signals_to_fft_buffer (float* buffer, uint size, const Signals& signals)
137
+ {
138
+ const double* samples = signals.samples();
139
+ uint nsamples = size > signals.nsamples() ? signals.nsamples() : size;
140
+
141
+ switch (signals.nchannels())
142
+ {
143
+ case 1:
144
+ for (uint i = 0; i < nsamples; ++i)
145
+ buffer[i] = samples[i];
146
+ break;
147
+
148
+ case 2:
149
+ for (uint i = 0; i < nsamples; ++i, samples += 2)
150
+ buffer[i] = (samples[0] + samples[1]) * 0.5;
151
+ break;
152
+
153
+ default:
154
+ beeps_error(__FILE__, __LINE__);
155
+ }
156
+
157
+ for (uint i = nsamples; i < size; ++i)
158
+ buffer[i] = 0;
159
+ }
160
+
161
+ static void
162
+ update_spectrum (Analyser::Spectrum* spectrum, float* buffer, uint buffer_size)
163
+ {
164
+ assert(spectrum && spectrum->empty() && buffer && (buffer_size % 2) == 0);
165
+
166
+ uint size = buffer_size / 2;
167
+ float div = 1.0 / size;
168
+ float* p = buffer;
169
+
170
+ spectrum->reserve(size);
171
+ for (uint i = 0; i < size; ++i, p += 2)
172
+ spectrum->push_back(sqrt(p[0] * p[0] + p[1] * p[1]) * div);
173
+ }
174
+
175
+ const Analyser::Spectrum&
176
+ Analyser::spectrum () const
177
+ {
178
+ if (self->spectrum.empty() && *this)
179
+ {
180
+ float* p = &self->fft_buffer[0];
181
+ copy_signals_to_fft_buffer(p, self->fft_size, self->signals);
182
+ pffft_transform_ordered(self->pffft.get(), p, p, NULL, PFFFT_FORWARD);
183
+ update_spectrum(&self->spectrum, p, self->fft_size);
184
+ }
185
+ return self->spectrum;
186
+ }
187
+
188
+ static void
189
+ shift (Signals* signals, uint nsamples)
190
+ {
191
+ if (nsamples > signals->nsamples())
192
+ return Signals_clear(signals);
193
+
194
+ Frames* frames = Signals_get_frames(signals);
195
+ assert(frames);
196
+
197
+ Float* from = &(*frames)(nsamples, 0);
198
+ Float* to = &(*frames)(0, 0);
199
+ uint size = (signals->nsamples() - nsamples) * signals->nchannels();
200
+ for (uint i = 0; i < size; ++i)
201
+ *to++ = *from++;
202
+
203
+ Signals_set_nsamples(signals, signals->nsamples() - nsamples);
204
+ }
205
+
206
+ static void
207
+ append (Signals* to, const Signals& from)
208
+ {
209
+ assert(to);
210
+
211
+ Frames* tof = Signals_get_frames(to);
212
+ const Frames* fromf = Signals_get_frames(&from);
213
+ assert(fromf && tof);
214
+
215
+ uint to_cap = to->capacity();
216
+ uint to_nsamples = to->nsamples();
217
+ uint from_nsamples = from.nsamples();
218
+ uint from_start = from_nsamples > to_cap ? from_nsamples - to_cap : 0;
219
+ uint nsamples = from_nsamples - from_start;
220
+ assert(to_nsamples + nsamples <= to_capacity);
221
+
222
+ for (uint ch = 0; ch < tof->nchannels(); ++ch)
223
+ {
224
+ uint from_ch = ch < fromf->nchannels() ? ch : 0;
225
+ for (uint i = 0; i < nsamples; ++i)
226
+ (*tof)(to_nsamples + i, ch) = (*fromf)(from_start + i, from_ch);
227
+ }
228
+
229
+ Signals_set_nsamples(to, to_nsamples + nsamples);
230
+ }
231
+
232
+ void
233
+ Analyser::filter (Context* context, Signals* signals, uint* offset)
234
+ {
235
+ Super::filter(context, signals, offset);
236
+
237
+ Signals& sig = self->signals;
238
+ uint nsamples = sig.nsamples() + signals->nsamples();
239
+ if (nsamples > sig.capacity())
240
+ shift(&sig, nsamples - sig.capacity());
241
+
242
+ append(&sig, *signals);
243
+
244
+ self->spectrum.clear();
245
+ }
246
+
247
+ Analyser::operator bool () const
248
+ {
249
+ if (!Super::operator bool()) return false;
250
+ return self->is_valid();
251
+ }
252
+
253
+
254
+ }// Beeps
data/src/beeps.cpp CHANGED
@@ -5,6 +5,8 @@
5
5
  #include "Stk.h"
6
6
  #include "beeps/exception.h"
7
7
  #include "openal.h"
8
+ #include "sound.h"
9
+ #include "mic_in.h"
8
10
 
9
11
 
10
12
  namespace Beeps
@@ -25,8 +27,15 @@ namespace Beeps
25
27
  OpenAL_fin();
26
28
  }
27
29
 
28
- uint
29
- sampling_rate ()
30
+ void
31
+ process_streams ()
32
+ {
33
+ MicIn_process_streams();
34
+ SoundPlayer_process_streams();
35
+ }
36
+
37
+ double
38
+ sample_rate ()
30
39
  {
31
40
  return stk::Stk::sampleRate();
32
41
  }