beeps 0.3.3 → 0.3.5

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.
@@ -11,6 +11,8 @@
11
11
 
12
12
  RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Gain)
13
13
 
14
+ RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Mixer)
15
+
14
16
  RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Envelope)
15
17
 
16
18
  RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::TimeStretch)
@@ -27,6 +29,9 @@ namespace Beeps
27
29
  BEEPS_EXPORT Rucy::Class gain_class ();
28
30
  // class Beeps::Gain
29
31
 
32
+ BEEPS_EXPORT Rucy::Class mixer_class ();
33
+ // class Beeps::Mixer
34
+
30
35
  BEEPS_EXPORT Rucy::Class envelope_class ();
31
36
  // class Beeps::Envelope
32
37
 
@@ -53,6 +58,12 @@ namespace Rucy
53
58
  return Beeps::gain_class();
54
59
  }
55
60
 
61
+ template <> inline Class
62
+ get_ruby_class<Beeps::Mixer> ()
63
+ {
64
+ return Beeps::mixer_class();
65
+ }
66
+
56
67
  template <> inline Class
57
68
  get_ruby_class<Beeps::Envelope> ()
58
69
  {
@@ -21,7 +21,23 @@ namespace Beeps
21
21
 
22
22
 
23
23
  template <typename T>
24
- class RubyProcessor : public Rucy::ClassWrapper<T> {};
24
+ class RubyProcessor : public Rucy::ClassWrapper<T>
25
+ {
26
+
27
+ typedef Rucy::ClassWrapper<T> Super;
28
+
29
+ public:
30
+
31
+ virtual void on_start ()
32
+ {
33
+ RUCY_SYM(on_start);
34
+ if (this->is_overridable())
35
+ this->value.call(on_start);
36
+ else
37
+ Super::on_start();
38
+ }
39
+
40
+ };// RubyProcessor
25
41
 
26
42
 
27
43
  }// Beeps
@@ -1,6 +1,7 @@
1
1
  require 'xot/setter'
2
2
  require 'xot/const_symbol_accessor'
3
3
  require 'xot/universal_accessor'
4
+ require 'xot/hookable'
4
5
  require 'xot/block_util'
5
6
  require 'beeps/ext'
6
7
 
@@ -11,55 +12,76 @@ module Beeps
11
12
  class Processor
12
13
 
13
14
  include Xot::Setter
15
+ include Xot::Hookable
14
16
 
15
- def initialize(**options, &block)
17
+ def initialize(*inputs, **options, &block)
16
18
  super()
19
+ add_input(*inputs)
17
20
  set options unless options.empty?
18
21
  Xot::BlockUtil.instance_eval_or_block_call self, &block if block
19
22
  end
20
23
 
21
- def >>(o)
22
- o.input = self
23
- o
24
+ universal_accessor :input
25
+
26
+ def add_input(*inputs)
27
+ last = inputs.flatten.compact.last
28
+ self.input = last if last
24
29
  end
25
30
 
26
- def <<(o)
27
- self.input = o
28
- o
31
+ def >>(processor)
32
+ processor.add_input self
33
+ processor
29
34
  end
30
35
 
31
- universal_accessor :input
36
+ #def <<(processors)
37
+ # self.add_input(*processors)
38
+ # self
39
+ #end
32
40
 
33
41
  end# Processor
34
42
 
35
43
 
36
44
  class Oscillator
37
45
 
46
+ include Enumerable
47
+
38
48
  const_symbol_accessor :type, **{
39
49
  none: TYPE_NONE,
40
50
  sine: SINE,
41
51
  triangle: TRIANGLE,
42
52
  square: SQUARE,
43
- sawtooth: SAWTOOTH
53
+ sawtooth: SAWTOOTH,
54
+ noise: NOISE,
55
+ samples: SAMPLES
44
56
  }
45
57
 
46
- def initialize(type = :sine, *args, **kwargs, &block)
47
- super(*args, **kwargs, &block)
48
- self.type = type
58
+ def initialize(type = :sine, samples: nil, **kwargs, &block)
59
+ super(**kwargs, &block)
60
+ if samples
61
+ self.samples = samples
62
+ else
63
+ self.type = type
64
+ end
49
65
  end
50
66
 
67
+ universal_accessor :type, :frequency, :phase
68
+
51
69
  alias freq= frequency=
52
70
  alias freq frequency
53
71
 
54
- universal_accessor :type, :frequency, :freq
72
+ def each_sample(&block)
73
+ block ? each_sample!(&block) : enum_for(:each_sample!)
74
+ end
75
+
76
+ alias each each_sample
55
77
 
56
78
  end# Oscillator
57
79
 
58
80
 
59
81
  class FileIn
60
82
 
61
- def initialize(path = nil, *args, **kwargs, &block)
62
- super(*args, **kwargs, &block)
83
+ def initialize(path = nil, **kwargs, &block)
84
+ super(**kwargs, &block)
63
85
  self.path = path if path
64
86
  end
65
87
 
@@ -70,13 +92,50 @@ module Beeps
70
92
 
71
93
  class Gain
72
94
 
95
+ def initialize(gain = 1, **kwargs, &block)
96
+ super(gain: gain, **kwargs, &block)
97
+ end
98
+
73
99
  universal_accessor :gain
74
100
 
75
101
  end# Gain
76
102
 
77
103
 
104
+ class Mixer
105
+
106
+ include Enumerable
107
+
108
+ def add_input(*inputs)
109
+ add_input! inputs.flatten.compact
110
+ end
111
+
112
+ def remove_input(*inputs)
113
+ remove_input! inputs.flatten.compact
114
+ end
115
+
116
+ def each_input(&block)
117
+ block ? each_input!(&block) : enum_for(:each_input!)
118
+ end
119
+
120
+ alias each each_input
121
+
122
+ end# Mixer
123
+
124
+
78
125
  class Envelope
79
126
 
127
+ def initialize(
128
+ attack = nil, decay = nil, sustain = nil, release = nil,
129
+ *args, **kwargs, &block)
130
+
131
+ attack_time attack if attack
132
+ decay_time decay if decay
133
+ sustain_level sustain if sustain
134
+ release_time release if release
135
+
136
+ super(*args, **kwargs, &block)
137
+ end
138
+
80
139
  def note_on(delay = 0)
81
140
  note_on! delay
82
141
  end
@@ -115,6 +174,8 @@ module Beeps
115
174
 
116
175
  class Analyser
117
176
 
177
+ universal_accessor :fft_size
178
+
118
179
  def each_signal(nsamples = fft_size, &block)
119
180
  return enum_for(:each_signal, nsamples) unless block
120
181
  each_signal!(nsamples, &block)
@@ -125,8 +186,6 @@ module Beeps
125
186
  each_spectrum!(&block)
126
187
  end
127
188
 
128
- universal_accessor :fft_size
129
-
130
189
  end# Analyser
131
190
 
132
191
 
data/src/envelope.cpp CHANGED
@@ -11,6 +11,9 @@ namespace Beeps
11
11
  {
12
12
 
13
13
 
14
+ static const float TIME_ZERO = 0.0000001;
15
+
16
+
14
17
  struct Envelope::Data
15
18
  {
16
19
 
@@ -18,16 +21,19 @@ namespace Beeps
18
21
 
19
22
  Signals adsr_signals;
20
23
 
21
- float attack_time = 0, decay_time = 0, sustain_level = 1, release_time = 0;
24
+ float attack_time = 0.005;
25
+ float decay_time = 0.005;
26
+ float sustain_level = 1;
27
+ float release_time = 0.005;
22
28
 
23
29
  float time = 0, note_on_time = -1, note_off_time = -1;
24
30
 
25
31
  void update_envelope ()
26
32
  {
27
- adsr.setAttackTime( attack_time == 0 ? 0.01 : attack_time);
28
33
  adsr.setSustainLevel(sustain_level);
29
- adsr.setDecayTime( decay_time == 0 ? 0.01 : decay_time);
30
- adsr.setReleaseTime( release_time == 0 ? 0.01 : release_time);
34
+ adsr.setAttackTime( attack_time == 0 ? TIME_ZERO : attack_time);
35
+ adsr.setDecayTime( decay_time == 0 ? TIME_ZERO : decay_time);
36
+ adsr.setReleaseTime(release_time == 0 ? TIME_ZERO : release_time);
31
37
  }
32
38
 
33
39
  };// Envelope::Data
@@ -148,11 +154,10 @@ namespace Beeps
148
154
  static size_t
149
155
  slice (Frames* frames, size_t start, float length_sec = -1)
150
156
  {
151
- Float sample_rate = frames->dataRate();
152
- size_t len = length_sec >= 0
153
- ? length_sec * sample_rate
154
- : frames->nframes() - start;
155
- assert(0 < len && (start + len) < frames->nframes());
157
+ size_t max = frames->nframes() - start;
158
+ size_t len = length_sec >= 0 ? length_sec * frames->sample_rate() : max;
159
+ if (len > max) len = max;
160
+ assert(0 < len && (start + len) <= frames->nframes());
156
161
 
157
162
  return frames->slice(start, len);
158
163
  }
@@ -167,6 +172,9 @@ namespace Beeps
167
172
  Frames* frames = Signals_get_frames(signals);
168
173
  assert(frames);
169
174
 
175
+ if (self->time == 0 && self->attack_time == 0)
176
+ self->adsr.setValue(self->sustain_level);// skip attack phase
177
+
170
178
  float start = self->time;
171
179
  float end = start + Signals_get_seconds(*signals);
172
180
  self->time = end;
@@ -175,7 +183,7 @@ namespace Beeps
175
183
  float off = self->note_off_time;
176
184
  assert(on <= off);
177
185
 
178
- bool has_on = 0 <= on && start <= on && on < end;
186
+ bool has_on = 0 <= on && start <= on && on < end;
179
187
  bool has_off = 0 <= off && start <= off && off < end;
180
188
 
181
189
  if (!has_on && !has_off)
data/src/mixer.cpp ADDED
@@ -0,0 +1,112 @@
1
+ #include "beeps/filter.h"
2
+
3
+
4
+ #include <algorithm>
5
+ #include <vector>
6
+ #include "processor.h"
7
+ #include "signals.h"
8
+
9
+
10
+ namespace Beeps
11
+ {
12
+
13
+
14
+ struct Mixer::Data
15
+ {
16
+
17
+ std::vector<Processor::Ref> inputs;
18
+
19
+ };// Mixer::Data
20
+
21
+
22
+ Mixer::Mixer (Processor* input)
23
+ {
24
+ if (input) add_input(input);
25
+ }
26
+
27
+ Mixer::~Mixer ()
28
+ {
29
+ }
30
+
31
+ void
32
+ Mixer::add_input (Processor* input)
33
+ {
34
+ auto it = std::find(self->inputs.begin(), self->inputs.end(), input);
35
+ if (it != self->inputs.end()) return;
36
+
37
+ self->inputs.emplace_back(input);
38
+
39
+ set_updated();
40
+ }
41
+
42
+ void
43
+ Mixer::remove_input (Processor* input)
44
+ {
45
+ auto it = std::find(self->inputs.begin(), self->inputs.end(), input);
46
+ if (it == self->inputs.end()) return;
47
+
48
+ self->inputs.erase(it);
49
+
50
+ set_updated();
51
+ }
52
+
53
+ Mixer::iterator
54
+ Mixer::begin ()
55
+ {
56
+ return self->inputs.begin();
57
+ }
58
+
59
+ Mixer::const_iterator
60
+ Mixer::begin () const
61
+ {
62
+ return self->inputs.begin();
63
+ }
64
+
65
+ Mixer::iterator
66
+ Mixer::end ()
67
+ {
68
+ return self->inputs.end();
69
+ }
70
+
71
+ Mixer::const_iterator
72
+ Mixer::end () const
73
+ {
74
+ return self->inputs.end();
75
+ }
76
+
77
+ void
78
+ Mixer::filter (Context* context, Signals* signals, uint* offset)
79
+ {
80
+ Super::filter(context, signals, offset);
81
+
82
+ Signals_resize(signals, signals->capacity(), 0);
83
+
84
+ Signals sig = Signals_create(signals->capacity(), signals->nchannels());
85
+ uint min_size = signals->capacity();
86
+ for (auto& input : self->inputs)
87
+ {
88
+ Signals_clear(&sig);
89
+
90
+ uint sig_offset = *offset;
91
+ Processor_get_context(context)->process(input, &sig, &sig_offset);
92
+
93
+ uint size = sig_offset - *offset;
94
+ if (size < min_size) min_size = size;
95
+
96
+ Signals_add(signals, sig);
97
+ }
98
+
99
+ *offset += min_size;
100
+ }
101
+
102
+ Mixer::operator bool () const
103
+ {
104
+ if (self->inputs.empty()) return false;
105
+
106
+ for (auto& input : self->inputs)
107
+ if (!*input) return false;
108
+ return true;
109
+ }
110
+
111
+
112
+ }// Beeps