beeps 0.3.11 → 0.3.12
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/sound_player.cpp +57 -0
- data/.github/workflows/release-gem.yml +3 -0
- data/.github/workflows/utils.rb +88 -17
- data/ChangeLog.md +14 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/beeps.gemspec +3 -4
- data/ext/beeps/extconf.rb +1 -1
- data/ext/beeps/sound_player.cpp +64 -1
- data/include/beeps/defs.h +2 -0
- data/include/beeps/filter.h +6 -0
- data/include/beeps/generator.h +8 -2
- data/include/beeps/processor.h +10 -8
- data/include/beeps/ruby.h +2 -2
- data/include/beeps/signals.h +14 -0
- data/include/beeps/sound.h +12 -0
- data/include/beeps.h +2 -2
- data/lib/beeps/extension.rb +8 -2
- data/lib/beeps/sound.rb +1 -1
- data/src/analyser.cpp +10 -3
- data/src/envelope.cpp +2 -5
- data/src/file_in.cpp +7 -1
- data/src/gain.cpp +7 -0
- data/src/mixer.cpp +16 -3
- data/src/oscillator.cpp +7 -1
- data/src/osx/signals.mm +4 -4
- data/src/osx/text_in.mm +1 -1
- data/src/processor.cpp +51 -38
- data/src/processor.h +1 -5
- data/src/reverb.cpp +2 -3
- data/src/sequencer.cpp +4 -4
- data/src/signals.cpp +178 -161
- data/src/signals.h +2 -15
- data/src/sound.cpp +154 -5
- data/src/time_stretch.cpp +2 -2
- data/src/value.cpp +8 -2
- data/src/win32/signals.cpp +9 -9
- data/src/x_pass.h +2 -3
- data/test/test_sound_player.rb +70 -0
- metadata +6 -6
data/src/file_in.cpp
CHANGED
|
@@ -82,12 +82,18 @@ namespace Beeps
|
|
|
82
82
|
return self->signals;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
bool
|
|
86
|
+
FileIn::seekable () const
|
|
87
|
+
{
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
85
91
|
void
|
|
86
92
|
FileIn::generate (Context* context, Signals* signals, uint* offset)
|
|
87
93
|
{
|
|
88
94
|
Super::generate(context, signals, offset);
|
|
89
95
|
|
|
90
|
-
*offset +=
|
|
96
|
+
*offset += signals->append(self->signals, *offset);
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
|
data/src/gain.cpp
CHANGED
data/src/mixer.cpp
CHANGED
|
@@ -91,6 +91,19 @@ namespace Beeps
|
|
|
91
91
|
return true;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
bool
|
|
95
|
+
Mixer::seekable () const
|
|
96
|
+
{
|
|
97
|
+
const auto* in = input();
|
|
98
|
+
if (in && !in->seekable())
|
|
99
|
+
return false;
|
|
100
|
+
|
|
101
|
+
for (auto& i : self->inputs)
|
|
102
|
+
if (!i->seekable()) return false;
|
|
103
|
+
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
|
|
94
107
|
static void
|
|
95
108
|
mix (
|
|
96
109
|
Mixer* mixer, Processor* input,
|
|
@@ -100,9 +113,9 @@ namespace Beeps
|
|
|
100
113
|
|
|
101
114
|
auto& insig = self->input_signals;
|
|
102
115
|
if (!insig)
|
|
103
|
-
insig =
|
|
116
|
+
insig = Signals(signals->capacity(), signals->nchannels());
|
|
104
117
|
else
|
|
105
|
-
|
|
118
|
+
insig.clear(signals->capacity());
|
|
106
119
|
|
|
107
120
|
Processor_get_context(context)->process(input, &insig, &offset);
|
|
108
121
|
|
|
@@ -116,7 +129,7 @@ namespace Beeps
|
|
|
116
129
|
Mixer::filter (Context* context, Signals* signals, uint* offset)
|
|
117
130
|
{
|
|
118
131
|
Signals_fill(signals, signals->capacity(), 0);
|
|
119
|
-
|
|
132
|
+
signals->clear();
|
|
120
133
|
|
|
121
134
|
Super::filter(context, signals, offset);
|
|
122
135
|
|
data/src/oscillator.cpp
CHANGED
|
@@ -493,6 +493,12 @@ namespace Beeps
|
|
|
493
493
|
return self->type != TYPE_NONE && self->osc;
|
|
494
494
|
}
|
|
495
495
|
|
|
496
|
+
bool
|
|
497
|
+
Oscillator::seekable () const
|
|
498
|
+
{
|
|
499
|
+
return true;
|
|
500
|
+
}
|
|
501
|
+
|
|
496
502
|
void
|
|
497
503
|
Oscillator::generate (Context* context, Signals* signals, uint* offset)
|
|
498
504
|
{
|
|
@@ -530,7 +536,7 @@ namespace Beeps
|
|
|
530
536
|
}
|
|
531
537
|
|
|
532
538
|
int
|
|
533
|
-
Oscillator::
|
|
539
|
+
Oscillator::get_max_segment_size_for_process (
|
|
534
540
|
double sample_rate, uint nsamples) const
|
|
535
541
|
{
|
|
536
542
|
return std::clamp(
|
data/src/osx/signals.mm
CHANGED
|
@@ -41,7 +41,7 @@ namespace Beeps
|
|
|
41
41
|
if (!channels)
|
|
42
42
|
beeps_error(__FILE__, __LINE__, "failed to get channel data");
|
|
43
43
|
|
|
44
|
-
return
|
|
44
|
+
return Signals(
|
|
45
45
|
channels, nsamples, nchannels, (uint) buffer.format.sampleRate, capacity);
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -77,11 +77,11 @@ namespace Beeps
|
|
|
77
77
|
if (new_nsamples > to->capacity())
|
|
78
78
|
Signals_set_capacity(to, get_next_capacity(*to, new_nsamples));
|
|
79
79
|
|
|
80
|
-
for (uint
|
|
80
|
+
for (uint ch = 0; ch < nchannels; ++ch)
|
|
81
81
|
{
|
|
82
|
-
Sample* p = Signals_at(to, to->nsamples(),
|
|
82
|
+
Sample* p = Signals_at(to, to->nsamples(), ch);
|
|
83
83
|
for (uint i = 0; i < nsamples; ++i, p += nchannels)
|
|
84
|
-
*p = channels[
|
|
84
|
+
*p = channels[ch][i];
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
Signals_set_nsamples(to, new_nsamples);
|
data/src/osx/text_in.mm
CHANGED
|
@@ -116,7 +116,7 @@ namespace Beeps
|
|
|
116
116
|
self->signals.sample_rate());
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
uint copied_size =
|
|
119
|
+
uint copied_size = signals->append(self->signals);
|
|
120
120
|
Signals_shift(&self->signals, copied_size);
|
|
121
121
|
*offset += copied_size;
|
|
122
122
|
}
|
data/src/processor.cpp
CHANGED
|
@@ -111,6 +111,12 @@ namespace Beeps
|
|
|
111
111
|
return const_cast<Processor*>(this)->input();
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
bool
|
|
115
|
+
Processor::seekable () const
|
|
116
|
+
{
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
114
120
|
void
|
|
115
121
|
Processor::on_start ()
|
|
116
122
|
{
|
|
@@ -185,28 +191,6 @@ namespace Beeps
|
|
|
185
191
|
Processor_get_context(context)->process(self->input, signals, offset);
|
|
186
192
|
}
|
|
187
193
|
|
|
188
|
-
int
|
|
189
|
-
Processor::max_segment_size_for_process (
|
|
190
|
-
double sample_rate, uint nsamples) const
|
|
191
|
-
{
|
|
192
|
-
return -1;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
uint
|
|
196
|
-
Processor::get_segment_size (double sample_rate, uint nsamples) const
|
|
197
|
-
{
|
|
198
|
-
uint size = nsamples;
|
|
199
|
-
for (const auto& kv : self->sub_inputs)
|
|
200
|
-
{
|
|
201
|
-
const auto& processor = kv.second;
|
|
202
|
-
|
|
203
|
-
int max = processor->max_segment_size_for_process(sample_rate, nsamples);
|
|
204
|
-
if (max > 0 && (uint) max < size)
|
|
205
|
-
size = (uint) max;
|
|
206
|
-
}
|
|
207
|
-
return size;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
194
|
void
|
|
211
195
|
Processor::set_sub_input (uint index, Processor* input)
|
|
212
196
|
{
|
|
@@ -235,6 +219,36 @@ namespace Beeps
|
|
|
235
219
|
set_sub_input(index, NULL);
|
|
236
220
|
}
|
|
237
221
|
|
|
222
|
+
uint
|
|
223
|
+
Processor::get_segment_size (double sample_rate, uint nsamples) const
|
|
224
|
+
{
|
|
225
|
+
uint size = nsamples;
|
|
226
|
+
for (const auto& kv : self->sub_inputs)
|
|
227
|
+
{
|
|
228
|
+
const auto& processor = kv.second;
|
|
229
|
+
|
|
230
|
+
int max = processor->get_max_segment_size_for_process(sample_rate, nsamples);
|
|
231
|
+
if (max > 0 && (uint) max < size)
|
|
232
|
+
size = (uint) max;
|
|
233
|
+
}
|
|
234
|
+
return size;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
int
|
|
238
|
+
Processor::get_max_segment_size_for_process (
|
|
239
|
+
double sample_rate, uint nsamples) const
|
|
240
|
+
{
|
|
241
|
+
return -1;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
void
|
|
245
|
+
Processor::set_buffering_seconds (float seconds)
|
|
246
|
+
{
|
|
247
|
+
self->buffering_seconds = seconds;
|
|
248
|
+
|
|
249
|
+
set_updated();
|
|
250
|
+
}
|
|
251
|
+
|
|
238
252
|
void
|
|
239
253
|
Processor::set_updated ()
|
|
240
254
|
{
|
|
@@ -260,14 +274,6 @@ namespace Beeps
|
|
|
260
274
|
if (input) set_input(input);
|
|
261
275
|
}
|
|
262
276
|
|
|
263
|
-
void
|
|
264
|
-
Filter::set_buffering_seconds (float seconds)
|
|
265
|
-
{
|
|
266
|
-
Super::self->buffering_seconds = seconds;
|
|
267
|
-
|
|
268
|
-
set_updated();
|
|
269
|
-
}
|
|
270
|
-
|
|
271
277
|
void
|
|
272
278
|
Filter::generate (Context* context, Signals* signals, uint* offset)
|
|
273
279
|
{
|
|
@@ -278,7 +284,7 @@ namespace Beeps
|
|
|
278
284
|
SignalsBuffer::SignalsBuffer (
|
|
279
285
|
uint nsamples_per_block, uint nchannels, double sample_rate)
|
|
280
286
|
{
|
|
281
|
-
buffer =
|
|
287
|
+
buffer = Signals(nsamples_per_block, nchannels, sample_rate);
|
|
282
288
|
assert(*this);
|
|
283
289
|
}
|
|
284
290
|
|
|
@@ -301,7 +307,7 @@ namespace Beeps
|
|
|
301
307
|
|
|
302
308
|
while (true)
|
|
303
309
|
{
|
|
304
|
-
*offset +=
|
|
310
|
+
*offset += signals->append(buffer, *offset - buffer_offset);
|
|
305
311
|
|
|
306
312
|
bool signals_full = signals->nsamples() == signals->capacity();
|
|
307
313
|
bool buffer_full = buffer.nsamples() == buffer.capacity();
|
|
@@ -327,7 +333,7 @@ namespace Beeps
|
|
|
327
333
|
SignalsBuffer::buffer_next (
|
|
328
334
|
ProcessorContext* context, Processor* processor, uint offset)
|
|
329
335
|
{
|
|
330
|
-
|
|
336
|
+
buffer.clear();
|
|
331
337
|
buffer_offset = offset;
|
|
332
338
|
context->process(processor, &buffer, &offset, true);
|
|
333
339
|
|
|
@@ -337,7 +343,7 @@ namespace Beeps
|
|
|
337
343
|
void
|
|
338
344
|
SignalsBuffer::clear ()
|
|
339
345
|
{
|
|
340
|
-
|
|
346
|
+
buffer.clear();
|
|
341
347
|
buffer_offset = 0;
|
|
342
348
|
}
|
|
343
349
|
|
|
@@ -353,8 +359,8 @@ namespace Beeps
|
|
|
353
359
|
{
|
|
354
360
|
assert(processor);
|
|
355
361
|
|
|
356
|
-
if (!signal) signal =
|
|
357
|
-
|
|
362
|
+
if (!signal) signal = Signals(nsamples, 1, sample_rate);
|
|
363
|
+
signal.clear(nsamples);
|
|
358
364
|
|
|
359
365
|
SignalsBuffer* buffer = NULL;
|
|
360
366
|
uint offset_ = offset;
|
|
@@ -411,7 +417,7 @@ namespace Beeps
|
|
|
411
417
|
StreamContext::StreamContext (
|
|
412
418
|
uint nsamples_per_process, uint nchannels, double sample_rate)
|
|
413
419
|
: context(nchannels, sample_rate),
|
|
414
|
-
signals(
|
|
420
|
+
signals(nsamples_per_process, nchannels, sample_rate),
|
|
415
421
|
nsamples_per_process(nsamples_per_process)
|
|
416
422
|
{
|
|
417
423
|
}
|
|
@@ -421,7 +427,7 @@ namespace Beeps
|
|
|
421
427
|
{
|
|
422
428
|
assert(processor);
|
|
423
429
|
|
|
424
|
-
|
|
430
|
+
signals.clear(nsamples_per_process);
|
|
425
431
|
context.process(processor, &signals, &offset);
|
|
426
432
|
|
|
427
433
|
if (signals.nsamples() < nsamples_per_process)
|
|
@@ -430,6 +436,13 @@ namespace Beeps
|
|
|
430
436
|
return signals;
|
|
431
437
|
}
|
|
432
438
|
|
|
439
|
+
void
|
|
440
|
+
StreamContext::seek (uint offset)
|
|
441
|
+
{
|
|
442
|
+
this->offset = offset;
|
|
443
|
+
this->finished = false;
|
|
444
|
+
}
|
|
445
|
+
|
|
433
446
|
bool
|
|
434
447
|
StreamContext::is_finished () const
|
|
435
448
|
{
|
data/src/processor.h
CHANGED
|
@@ -93,9 +93,7 @@ namespace Beeps
|
|
|
93
93
|
|
|
94
94
|
Signals process_next (Processor* processor);
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
//uint pop_offset ();
|
|
96
|
+
void seek (uint offset);
|
|
99
97
|
|
|
100
98
|
bool is_finished () const;
|
|
101
99
|
|
|
@@ -111,8 +109,6 @@ namespace Beeps
|
|
|
111
109
|
|
|
112
110
|
bool finished = false;
|
|
113
111
|
|
|
114
|
-
//std::vector<uint> offset_stack;
|
|
115
|
-
|
|
116
112
|
};// StreamContext
|
|
117
113
|
|
|
118
114
|
|
data/src/reverb.cpp
CHANGED
|
@@ -105,9 +105,8 @@ namespace Beeps
|
|
|
105
105
|
self->freeverb.setRoomSize( self->room_size);
|
|
106
106
|
self->freeverb.setDamping( self->damping);
|
|
107
107
|
|
|
108
|
-
uint nchannels
|
|
109
|
-
Signals filtered
|
|
110
|
-
signals->nsamples(), nchannels, signals->sample_rate());
|
|
108
|
+
uint nchannels = signals->nchannels();
|
|
109
|
+
Signals filtered(signals->nsamples(), nchannels, signals->sample_rate());
|
|
111
110
|
|
|
112
111
|
Signals_tick(
|
|
113
112
|
&filtered, *signals,
|
data/src/sequencer.cpp
CHANGED
|
@@ -139,9 +139,9 @@ namespace Beeps
|
|
|
139
139
|
auto& signals = *psignals;
|
|
140
140
|
Signals_fill(&signals, signals.capacity(), 0);
|
|
141
141
|
|
|
142
|
-
uint generate_begin
|
|
143
|
-
uint generate_end
|
|
144
|
-
Signals note_signals
|
|
142
|
+
uint generate_begin = *offset;
|
|
143
|
+
uint generate_end = *offset + signals.capacity();
|
|
144
|
+
Signals note_signals(
|
|
145
145
|
signals.capacity(), signals.nchannels(), signals.sample_rate());
|
|
146
146
|
|
|
147
147
|
uint nsamples = 0;
|
|
@@ -161,7 +161,7 @@ namespace Beeps
|
|
|
161
161
|
assert(begin != end);
|
|
162
162
|
|
|
163
163
|
uint note_offset = begin - note_begin;
|
|
164
|
-
|
|
164
|
+
note_signals.clear(end - begin);
|
|
165
165
|
context.process(note.processor.get(), ¬e_signals, ¬e_offset);
|
|
166
166
|
|
|
167
167
|
uint mix_offset = begin - generate_begin;
|