beeps 0.3.6 → 0.3.8
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.
- checksums.yaml +4 -4
- data/.doc/ext/beeps/beeps.cpp +7 -0
- data/.doc/ext/beeps/high_pass.cpp +63 -0
- data/.doc/ext/beeps/low_pass.cpp +63 -0
- data/.doc/ext/beeps/native.cpp +8 -0
- data/.doc/ext/beeps/oscillator.cpp +87 -10
- data/.doc/ext/beeps/processor.cpp +14 -1
- data/.doc/ext/beeps/reverb.cpp +99 -0
- data/.doc/ext/beeps/signals.cpp +128 -0
- data/ChangeLog.md +30 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/beeps.gemspec +2 -2
- data/ext/beeps/beeps.cpp +8 -0
- data/ext/beeps/high_pass.cpp +66 -0
- data/ext/beeps/low_pass.cpp +66 -0
- data/ext/beeps/native.cpp +8 -0
- data/ext/beeps/oscillator.cpp +95 -12
- data/ext/beeps/processor.cpp +15 -1
- data/ext/beeps/reverb.cpp +106 -0
- data/ext/beeps/signals.cpp +136 -0
- data/include/beeps/beeps.h +2 -2
- data/include/beeps/defs.h +3 -0
- data/include/beeps/filter.h +118 -17
- data/include/beeps/generator.h +50 -17
- data/include/beeps/processor.h +23 -6
- data/include/beeps/ruby/filter.h +33 -0
- data/include/beeps/ruby/signals.h +40 -0
- data/include/beeps/signals.h +1 -1
- data/lib/beeps/processor.rb +46 -1
- data/lib/beeps/signals.rb +19 -0
- data/lib/beeps.rb +1 -0
- data/src/analyser.cpp +34 -37
- data/src/beeps.cpp +7 -6
- data/src/envelope.cpp +70 -46
- data/src/file_in.cpp +6 -6
- data/src/gain.cpp +5 -5
- data/src/high_pass.cpp +57 -0
- data/src/low_pass.cpp +57 -0
- data/src/mic_in.cpp +16 -14
- data/src/mixer.cpp +38 -20
- data/src/oscillator.cpp +261 -169
- data/src/pitch_shift.cpp +6 -6
- data/src/processor.cpp +118 -11
- data/src/processor.h +8 -0
- data/src/reverb.cpp +124 -0
- data/src/sequencer.cpp +18 -14
- data/src/signals.cpp +264 -106
- data/src/signals.h +28 -89
- data/src/sound.cpp +28 -20
- data/src/time_stretch.cpp +6 -6
- data/src/win32/signals.cpp +8 -7
- data/src/x_pass.h +51 -0
- data/test/helper.rb +14 -0
- data/test/test_analyser.rb +26 -0
- data/test/test_envelope.rb +55 -0
- data/test/test_file_in.rb +22 -1
- data/test/test_gain.rb +28 -0
- data/test/test_high_pass.rb +41 -0
- data/test/test_low_pass.rb +41 -0
- data/test/test_mixer.rb +63 -0
- data/test/test_oscillator.rb +58 -0
- data/test/test_pitch_shift.rb +32 -0
- data/test/test_processor.rb +7 -0
- data/test/test_signals.rb +60 -0
- data/test/test_time_stretch.rb +36 -0
- metadata +48 -10
data/src/analyser.cpp
CHANGED
@@ -186,48 +186,46 @@ namespace Beeps
|
|
186
186
|
return self->spectrum;
|
187
187
|
}
|
188
188
|
|
189
|
+
Analyser::operator bool () const
|
190
|
+
{
|
191
|
+
if (!Super::operator bool()) return false;
|
192
|
+
return self->is_valid();
|
193
|
+
}
|
194
|
+
|
189
195
|
static void
|
190
196
|
shift (Signals* signals, uint nsamples)
|
191
197
|
{
|
198
|
+
if (nsamples == 0)
|
199
|
+
return;
|
200
|
+
|
192
201
|
if (nsamples > signals->nsamples())
|
193
202
|
return Signals_clear(signals);
|
194
203
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
Float* to = &(*frames)(0, 0);
|
200
|
-
uint size = (signals->nsamples() - nsamples) * signals->nchannels();
|
204
|
+
Sample* from = Signals_at(signals, nsamples);
|
205
|
+
Sample* to = Signals_at(signals, 0);
|
206
|
+
uint nsamples_remain = signals->nsamples() - nsamples;
|
207
|
+
uint size = nsamples_remain * signals->nchannels();
|
201
208
|
for (uint i = 0; i < size; ++i)
|
202
209
|
*to++ = *from++;
|
203
210
|
|
204
|
-
Signals_set_nsamples(signals,
|
211
|
+
Signals_set_nsamples(signals, nsamples_remain);
|
205
212
|
}
|
206
213
|
|
207
214
|
static void
|
208
215
|
append (Signals* to, const Signals& from)
|
209
216
|
{
|
210
|
-
assert(to);
|
211
|
-
|
212
|
-
Frames* tof = Signals_get_frames(to);
|
213
|
-
const Frames* fromf = Signals_get_frames(&from);
|
214
|
-
assert(fromf && tof);
|
217
|
+
assert(to->nchannels() == from.nchannels());
|
218
|
+
assert(to->nsamples() + from.nsamples() <= to->capacity());
|
215
219
|
|
216
|
-
uint
|
217
|
-
uint
|
218
|
-
uint
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
for (uint ch = 0; ch < tof->nchannels(); ++ch)
|
224
|
-
{
|
225
|
-
uint from_ch = ch < fromf->nchannels() ? ch : 0;
|
226
|
-
for (uint i = 0; i < nsamples; ++i)
|
227
|
-
(*tof)(to_nsamples + i, ch) = (*fromf)(from_start + i, from_ch);
|
228
|
-
}
|
220
|
+
uint nchannels = to->nchannels();
|
221
|
+
uint nsamples = std::min(from.nsamples(), to->capacity() - to->nsamples());
|
222
|
+
uint size = nsamples * nchannels;
|
223
|
+
Sample* to_p = Signals_at(to, to->nsamples());
|
224
|
+
const Sample* from_p = Signals_at(from, 0);
|
225
|
+
for (uint i = 0; i < size; ++i)
|
226
|
+
*to_p++ = *from_p++;
|
229
227
|
|
230
|
-
Signals_set_nsamples(to,
|
228
|
+
Signals_set_nsamples(to, to->nsamples() + nsamples);
|
231
229
|
}
|
232
230
|
|
233
231
|
void
|
@@ -235,20 +233,19 @@ namespace Beeps
|
|
235
233
|
{
|
236
234
|
Super::filter(context, signals, offset);
|
237
235
|
|
238
|
-
|
239
|
-
|
240
|
-
if (nsamples > sig.capacity())
|
241
|
-
shift(&sig, nsamples - sig.capacity());
|
236
|
+
auto& in = *signals;
|
237
|
+
auto& my = self->signals;
|
242
238
|
|
243
|
-
|
239
|
+
if (my.nchannels() != in.nchannels() || my.sample_rate() != in.sample_rate())
|
240
|
+
my = Signals_create(my.capacity(), in.nchannels(), in.sample_rate());
|
244
241
|
|
245
|
-
|
246
|
-
|
242
|
+
uint total_nsamples = my.nsamples() + in.nsamples();
|
243
|
+
if (total_nsamples > my.capacity())
|
244
|
+
shift(&my, total_nsamples - my.capacity());
|
247
245
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
return self->is_valid();
|
246
|
+
append(&my, in);
|
247
|
+
|
248
|
+
self->spectrum.clear();
|
252
249
|
}
|
253
250
|
|
254
251
|
|
data/src/beeps.cpp
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
#include "Stk.h"
|
6
6
|
#include "beeps/exception.h"
|
7
|
+
#include "beeps/debug.h"
|
7
8
|
#include "openal.h"
|
8
9
|
#include "sound.h"
|
9
10
|
#include "mic_in.h"
|
@@ -32,6 +33,12 @@ namespace Beeps
|
|
32
33
|
Beeps_fin();
|
33
34
|
}
|
34
35
|
|
36
|
+
double
|
37
|
+
sample_rate ()
|
38
|
+
{
|
39
|
+
return stk::Stk::sampleRate();
|
40
|
+
}
|
41
|
+
|
35
42
|
void
|
36
43
|
process_streams ()
|
37
44
|
{
|
@@ -39,11 +46,5 @@ namespace Beeps
|
|
39
46
|
SoundPlayer_process_streams();
|
40
47
|
}
|
41
48
|
|
42
|
-
double
|
43
|
-
sample_rate ()
|
44
|
-
{
|
45
|
-
return stk::Stk::sampleRate();
|
46
|
-
}
|
47
|
-
|
48
49
|
|
49
50
|
}// Beeps
|
data/src/envelope.cpp
CHANGED
@@ -14,10 +14,25 @@ namespace Beeps
|
|
14
14
|
static const float TIME_ZERO = 0.0000001;
|
15
15
|
|
16
16
|
|
17
|
+
class ADSR : public stk::ADSR
|
18
|
+
{
|
19
|
+
|
20
|
+
public:
|
21
|
+
|
22
|
+
void skipAttackPhase()
|
23
|
+
{
|
24
|
+
value_ = 1;
|
25
|
+
target_ = 1;
|
26
|
+
state_ = DECAY;
|
27
|
+
}
|
28
|
+
|
29
|
+
};// ADSR
|
30
|
+
|
31
|
+
|
17
32
|
struct Envelope::Data
|
18
33
|
{
|
19
34
|
|
20
|
-
|
35
|
+
ADSR adsr;
|
21
36
|
|
22
37
|
Signals adsr_signals;
|
23
38
|
|
@@ -151,15 +166,28 @@ namespace Beeps
|
|
151
166
|
return self->release_time;
|
152
167
|
}
|
153
168
|
|
154
|
-
|
155
|
-
|
169
|
+
Envelope::operator bool () const
|
170
|
+
{
|
171
|
+
if (!Super::operator bool()) return false;
|
172
|
+
return
|
173
|
+
self->attack_time >= 0 &&
|
174
|
+
self->decay_time >= 0 &&
|
175
|
+
self->sustain_level >= 0 &&
|
176
|
+
self->release_time >= 0 &&
|
177
|
+
self->time >= 0;
|
178
|
+
}
|
179
|
+
|
180
|
+
static uint
|
181
|
+
tick (Envelope* envelope, Signals* signals, uint start, float length_sec = -1)
|
156
182
|
{
|
157
|
-
|
158
|
-
|
183
|
+
uint max = signals->capacity() - start;
|
184
|
+
uint len = length_sec >= 0 ? length_sec * signals->sample_rate() : max;
|
159
185
|
if (len > max) len = max;
|
160
|
-
assert(0 < len && (start + len) <=
|
186
|
+
assert(0 < len && (start + len) <= signals->nsamples());
|
161
187
|
|
162
|
-
return
|
188
|
+
return Signals_tick(
|
189
|
+
signals, start, start + len,
|
190
|
+
[&](stk::StkFrames* frames) {envelope->self->adsr.tick(*frames);});
|
163
191
|
}
|
164
192
|
|
165
193
|
static void
|
@@ -169,57 +197,62 @@ namespace Beeps
|
|
169
197
|
|
170
198
|
Envelope::Data* self = envelope->self.get();
|
171
199
|
|
172
|
-
Frames* frames = Signals_get_frames(signals);
|
173
|
-
assert(frames);
|
174
|
-
|
175
200
|
if (self->time == 0 && self->attack_time == 0)
|
176
|
-
self->adsr.
|
201
|
+
self->adsr.skipAttackPhase();
|
177
202
|
|
178
|
-
|
179
|
-
|
180
|
-
|
203
|
+
if (
|
204
|
+
self->note_on_time >= 0 &&
|
205
|
+
self->note_off_time < 0 &&
|
206
|
+
self->sustain_level == 0)
|
207
|
+
{
|
208
|
+
envelope->note_off(
|
209
|
+
self->note_on_time + self->attack_time + self->decay_time
|
210
|
+
- self->time);
|
211
|
+
}
|
212
|
+
|
213
|
+
float on = self->note_on_time;
|
214
|
+
float off = self->note_off_time;
|
215
|
+
float start = self->time;
|
216
|
+
float end = start + signals->capacity() / signals->sample_rate();
|
217
|
+
float release_end = off >= 0 ? off + self->release_time : -1;
|
218
|
+
bool has_on = 0 <= on && start <= on && on < end;
|
219
|
+
bool has_off = 0 <= off && start <= off && off < end;
|
181
220
|
|
182
|
-
|
183
|
-
|
184
|
-
assert(on <= off);
|
221
|
+
if (release_end >= 0 && release_end < end)
|
222
|
+
end = release_end;
|
185
223
|
|
186
|
-
|
187
|
-
bool has_off = 0 <= off && start <= off && off < end;
|
224
|
+
self->time = end;
|
188
225
|
|
189
226
|
if (!has_on && !has_off)
|
190
227
|
{
|
191
|
-
|
228
|
+
float len = end == release_end ? end - start : -1;
|
229
|
+
tick(envelope, signals, 0, len);
|
192
230
|
return;
|
193
231
|
}
|
194
232
|
|
195
|
-
|
233
|
+
uint pos = 0;
|
196
234
|
if (has_on)
|
197
235
|
{
|
198
236
|
if (start < on)
|
199
|
-
|
200
|
-
last = slice(frames, 0, on - start);
|
201
|
-
self->adsr.tick(*frames);
|
202
|
-
frames->unslice();
|
203
|
-
}
|
237
|
+
pos = tick(envelope, signals, pos, on - start);
|
204
238
|
self->adsr.keyOn();
|
205
239
|
}
|
206
240
|
if (has_on || has_off)
|
207
241
|
{
|
208
242
|
float len = has_off ? off - (has_on ? on : start) : -1;
|
209
|
-
|
210
|
-
self->adsr.tick(*frames);
|
211
|
-
frames->unslice();
|
243
|
+
pos = tick(envelope, signals, pos, len);
|
212
244
|
}
|
213
245
|
if (has_off)
|
214
246
|
{
|
215
247
|
self->adsr.keyOff();
|
216
248
|
if (off < end)
|
217
249
|
{
|
218
|
-
|
219
|
-
|
220
|
-
frames->unslice();
|
250
|
+
float len = end == release_end ? end - off : -1;
|
251
|
+
pos = tick(envelope, signals, pos, len);
|
221
252
|
}
|
222
253
|
}
|
254
|
+
|
255
|
+
Signals_set_nsamples(signals, pos);
|
223
256
|
}
|
224
257
|
|
225
258
|
void
|
@@ -232,23 +265,14 @@ namespace Beeps
|
|
232
265
|
self->adsr_signals =
|
233
266
|
Signals_create(signals->nsamples(), 1, signals->sample_rate());
|
234
267
|
}
|
235
|
-
|
236
|
-
|
237
|
-
Signals_resize(&self->adsr_signals, signals->nsamples(), 0);
|
268
|
+
else
|
269
|
+
Signals_clear(&self->adsr_signals, signals->nsamples());
|
238
270
|
|
239
271
|
process_envelope_signals(this, &self->adsr_signals);
|
240
|
-
|
241
|
-
|
272
|
+
if (self->adsr_signals.nsamples() < signals->nsamples())
|
273
|
+
Signals_set_nsamples(signals, self->adsr_signals.nsamples());
|
242
274
|
|
243
|
-
|
244
|
-
{
|
245
|
-
if (!Super::operator bool()) return false;
|
246
|
-
return
|
247
|
-
self->attack_time >= 0 &&
|
248
|
-
self->decay_time >= 0 &&
|
249
|
-
self->sustain_level >= 0 &&
|
250
|
-
self->release_time >= 0 &&
|
251
|
-
self->time >= 0;
|
275
|
+
Signals_multiply(signals, self->adsr_signals);
|
252
276
|
}
|
253
277
|
|
254
278
|
|
data/src/file_in.cpp
CHANGED
@@ -76,6 +76,12 @@ namespace Beeps
|
|
76
76
|
return Signals_get_seconds(self->signals);
|
77
77
|
}
|
78
78
|
|
79
|
+
FileIn::operator bool () const
|
80
|
+
{
|
81
|
+
if (!Super::operator bool()) return false;
|
82
|
+
return self->signals;
|
83
|
+
}
|
84
|
+
|
79
85
|
void
|
80
86
|
FileIn::generate (Context* context, Signals* signals, uint* offset)
|
81
87
|
{
|
@@ -84,11 +90,5 @@ namespace Beeps
|
|
84
90
|
*offset += Signals_copy(signals, self->signals, *offset);
|
85
91
|
}
|
86
92
|
|
87
|
-
FileIn::operator bool () const
|
88
|
-
{
|
89
|
-
if (!Super::operator bool()) return false;
|
90
|
-
return self->signals;
|
91
|
-
}
|
92
|
-
|
93
93
|
|
94
94
|
}// Beeps
|
data/src/gain.cpp
CHANGED
@@ -44,11 +44,11 @@ namespace Beeps
|
|
44
44
|
{
|
45
45
|
Super::filter(context, signals, offset);
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
float gain = self->gain;
|
48
|
+
uint size = signals->nsamples() * signals->nchannels();
|
49
|
+
Sample* p = Signals_at(signals, 0);
|
50
|
+
for (uint i = 0; i < size; ++i)
|
51
|
+
*p++ *= gain;
|
52
52
|
}
|
53
53
|
|
54
54
|
|
data/src/high_pass.cpp
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#include "x_pass.h"
|
2
|
+
|
3
|
+
|
4
|
+
namespace Beeps
|
5
|
+
{
|
6
|
+
|
7
|
+
|
8
|
+
struct HighPass::Data : public xPassFilterData
|
9
|
+
{
|
10
|
+
|
11
|
+
Data ()
|
12
|
+
: xPassFilterData(100)
|
13
|
+
{
|
14
|
+
}
|
15
|
+
|
16
|
+
};// HighPass::Data
|
17
|
+
|
18
|
+
|
19
|
+
HighPass::HighPass (Processor* input)
|
20
|
+
: Super(input)
|
21
|
+
{
|
22
|
+
}
|
23
|
+
|
24
|
+
HighPass::~HighPass ()
|
25
|
+
{
|
26
|
+
}
|
27
|
+
|
28
|
+
void
|
29
|
+
HighPass::set_cutoff_frequency (float frequency)
|
30
|
+
{
|
31
|
+
if (frequency <= 0)
|
32
|
+
argument_error(__FILE__, __LINE__);
|
33
|
+
|
34
|
+
if (frequency == self->cutoff_freq)
|
35
|
+
return;
|
36
|
+
|
37
|
+
self->cutoff_freq = frequency;
|
38
|
+
set_updated();
|
39
|
+
}
|
40
|
+
|
41
|
+
float
|
42
|
+
HighPass::cutoff_frequency () const
|
43
|
+
{
|
44
|
+
return self->cutoff_freq;
|
45
|
+
}
|
46
|
+
|
47
|
+
void
|
48
|
+
HighPass::filter (Context* context, Signals* signals, uint* offset)
|
49
|
+
{
|
50
|
+
Super::filter(context, signals, offset);
|
51
|
+
|
52
|
+
self->biquad.setHighPass(self->cutoff_freq);
|
53
|
+
self->tick(signals);
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
}// Beeps
|
data/src/low_pass.cpp
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#include "x_pass.h"
|
2
|
+
|
3
|
+
|
4
|
+
namespace Beeps
|
5
|
+
{
|
6
|
+
|
7
|
+
|
8
|
+
struct LowPass::Data : public xPassFilterData
|
9
|
+
{
|
10
|
+
|
11
|
+
Data ()
|
12
|
+
: xPassFilterData(1000)
|
13
|
+
{
|
14
|
+
}
|
15
|
+
|
16
|
+
};// LowPass::Data
|
17
|
+
|
18
|
+
|
19
|
+
LowPass::LowPass (Processor* input)
|
20
|
+
: Super(input)
|
21
|
+
{
|
22
|
+
}
|
23
|
+
|
24
|
+
LowPass::~LowPass ()
|
25
|
+
{
|
26
|
+
}
|
27
|
+
|
28
|
+
void
|
29
|
+
LowPass::set_cutoff_frequency (float frequency)
|
30
|
+
{
|
31
|
+
if (frequency <= 0)
|
32
|
+
argument_error(__FILE__, __LINE__);
|
33
|
+
|
34
|
+
if (frequency == self->cutoff_freq)
|
35
|
+
return;
|
36
|
+
|
37
|
+
self->cutoff_freq = frequency;
|
38
|
+
set_updated();
|
39
|
+
}
|
40
|
+
|
41
|
+
float
|
42
|
+
LowPass::cutoff_frequency () const
|
43
|
+
{
|
44
|
+
return self->cutoff_freq;
|
45
|
+
}
|
46
|
+
|
47
|
+
void
|
48
|
+
LowPass::filter (Context* context, Signals* signals, uint* offset)
|
49
|
+
{
|
50
|
+
Super::filter(context, signals, offset);
|
51
|
+
|
52
|
+
self->biquad.setLowPass(self->cutoff_freq);
|
53
|
+
self->tick(signals);
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
}// Beeps
|
data/src/mic_in.cpp
CHANGED
@@ -86,22 +86,19 @@ namespace Beeps
|
|
86
86
|
|
87
87
|
if (!is_valid()) return;
|
88
88
|
|
89
|
-
Frames* frames = Signals_get_frames(signals);
|
90
|
-
assert(frames);
|
91
|
-
|
92
89
|
auto& samples = self->samples;
|
93
90
|
uint nchannels = self->nchannels;
|
94
91
|
uint nsamples = (uint) (samples.size() / nchannels);
|
95
92
|
uint offset = *gen_offset < self->offset ? 0 : *gen_offset - self->offset;
|
96
93
|
if (offset >= nsamples) return;
|
97
94
|
|
98
|
-
nsamples = std::min(
|
99
|
-
for (uint ch = 0; ch <
|
95
|
+
nsamples = std::min(signals->capacity(), nsamples - offset);
|
96
|
+
for (uint ch = 0; ch < signals->nchannels(); ++ch)
|
100
97
|
{
|
101
98
|
uint samples_ch = ch < nchannels ? ch : 0;
|
102
99
|
float div = 1.0f / SHRT_MAX;
|
103
100
|
for (uint i = 0; i < nsamples; ++i)
|
104
|
-
|
101
|
+
*Signals_at(signals, i, ch) = samples[(offset + i) * nchannels + samples_ch] * div;
|
105
102
|
}
|
106
103
|
Signals_set_nsamples(signals, nsamples);
|
107
104
|
|
@@ -207,10 +204,15 @@ namespace Beeps
|
|
207
204
|
|
208
205
|
MicIn::MicIn (uint nchannels, double sample_rate)
|
209
206
|
{
|
207
|
+
if (sample_rate == 0)
|
208
|
+
sample_rate = Beeps::sample_rate();
|
209
|
+
|
210
|
+
if (nchannels <= 0)
|
211
|
+
argument_error(__FILE__, __LINE__);
|
210
212
|
if (nchannels > 2)
|
211
213
|
argument_error(__FILE__, __LINE__);
|
212
|
-
|
213
|
-
|
214
|
+
if (sample_rate <= 0)
|
215
|
+
argument_error(__FILE__, __LINE__);
|
214
216
|
|
215
217
|
self->mic.self->sample_rate = sample_rate;
|
216
218
|
self->mic.self->nchannels = nchannels;
|
@@ -254,6 +256,12 @@ namespace Beeps
|
|
254
256
|
return self->mic.self->nchannels;
|
255
257
|
}
|
256
258
|
|
259
|
+
MicIn::operator bool () const
|
260
|
+
{
|
261
|
+
if (!Super::operator bool()) return false;
|
262
|
+
return self->mic.is_valid();
|
263
|
+
}
|
264
|
+
|
257
265
|
void
|
258
266
|
MicIn::generate (Context* context, Signals* signals, uint* offset)
|
259
267
|
{
|
@@ -262,11 +270,5 @@ namespace Beeps
|
|
262
270
|
self->mic.get_signals(signals, offset);
|
263
271
|
}
|
264
272
|
|
265
|
-
MicIn::operator bool () const
|
266
|
-
{
|
267
|
-
if (!Super::operator bool()) return false;
|
268
|
-
return self->mic.is_valid();
|
269
|
-
}
|
270
|
-
|
271
273
|
|
272
274
|
}// Beeps
|
data/src/mixer.cpp
CHANGED
@@ -16,6 +16,8 @@ namespace Beeps
|
|
16
16
|
|
17
17
|
std::vector<Processor::Ref> inputs;
|
18
18
|
|
19
|
+
Signals input_signals;
|
20
|
+
|
19
21
|
};// Mixer::Data
|
20
22
|
|
21
23
|
|
@@ -74,38 +76,54 @@ namespace Beeps
|
|
74
76
|
return self->inputs.end();
|
75
77
|
}
|
76
78
|
|
77
|
-
|
78
|
-
Mixer::filter (Context* context, Signals* signals, uint* offset)
|
79
|
+
Mixer::operator bool () const
|
79
80
|
{
|
80
|
-
|
81
|
+
const auto* input = this->input();
|
82
|
+
if (input && !*input)
|
83
|
+
return false;
|
81
84
|
|
82
|
-
|
85
|
+
if (!input && self->inputs.empty())
|
86
|
+
return false;
|
83
87
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
88
|
+
for (auto& i : self->inputs)
|
89
|
+
if (!*i) return false;
|
90
|
+
|
91
|
+
return true;
|
92
|
+
}
|
89
93
|
|
90
|
-
|
91
|
-
|
94
|
+
static void
|
95
|
+
mix (
|
96
|
+
Mixer* mixer, Processor* input,
|
97
|
+
Processor::Context* context, Signals* signals, uint offset)
|
98
|
+
{
|
99
|
+
Mixer::Data* self = mixer->self.get();
|
100
|
+
|
101
|
+
auto& insig = self->input_signals;
|
102
|
+
if (!insig)
|
103
|
+
insig = Signals_create(signals->capacity(), signals->nchannels());
|
104
|
+
else
|
105
|
+
Signals_clear(&insig, signals->capacity());
|
92
106
|
|
93
|
-
|
94
|
-
if (size < min_size) min_size = size;
|
107
|
+
Processor_get_context(context)->process(input, &insig, &offset);
|
95
108
|
|
96
|
-
|
97
|
-
|
109
|
+
if (insig.nsamples() > signals->nsamples())
|
110
|
+
Signals_set_nsamples(signals, insig.nsamples());
|
98
111
|
|
99
|
-
|
112
|
+
Signals_add(signals, insig);
|
100
113
|
}
|
101
114
|
|
102
|
-
|
115
|
+
void
|
116
|
+
Mixer::filter (Context* context, Signals* signals, uint* offset)
|
103
117
|
{
|
104
|
-
|
118
|
+
Signals_fill(signals, signals->capacity(), 0);
|
119
|
+
Signals_clear(signals);
|
120
|
+
|
121
|
+
Super::filter(context, signals, offset);
|
105
122
|
|
106
123
|
for (auto& input : self->inputs)
|
107
|
-
|
108
|
-
|
124
|
+
mix(this, input.get(), context, signals, *offset);
|
125
|
+
|
126
|
+
*offset += signals->nsamples();
|
109
127
|
}
|
110
128
|
|
111
129
|
|