beeps 0.3 → 0.3.1

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.
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include <assert.h>
5
5
  #include <ADSR.h>
6
+ #include "beeps/debug.h"
6
7
  #include "signals.h"
7
8
 
8
9
 
@@ -10,7 +11,7 @@ namespace Beeps
10
11
  {
11
12
 
12
13
 
13
- struct ADSR::Data
14
+ struct Envelope::Data
14
15
  {
15
16
 
16
17
  stk::ADSR adsr;
@@ -29,21 +30,21 @@ namespace Beeps
29
30
  adsr.setReleaseTime( release_time == 0 ? 0.01 : release_time);
30
31
  }
31
32
 
32
- };// ADSR::Data
33
+ };// Envelope::Data
33
34
 
34
35
 
35
- ADSR::ADSR (Processor* input)
36
+ Envelope::Envelope (Processor* input)
36
37
  : Super(input)
37
38
  {
38
39
  self->update_envelope();
39
40
  }
40
41
 
41
- ADSR::~ADSR ()
42
+ Envelope::~Envelope ()
42
43
  {
43
44
  }
44
45
 
45
46
  void
46
- ADSR::note_on (float delay)
47
+ Envelope::note_on (float delay)
47
48
  {
48
49
  if (delay < 0)
49
50
  argument_error(__FILE__, __LINE__);
@@ -58,7 +59,7 @@ namespace Beeps
58
59
  }
59
60
 
60
61
  void
61
- ADSR::note_off (float delay)
62
+ Envelope::note_off (float delay)
62
63
  {
63
64
  if (delay < 0)
64
65
  argument_error(__FILE__, __LINE__);
@@ -73,7 +74,7 @@ namespace Beeps
73
74
  }
74
75
 
75
76
  void
76
- ADSR::set_attack_time (float time)
77
+ Envelope::set_attack_time (float time)
77
78
  {
78
79
  if (time < 0)
79
80
  argument_error(__FILE__, __LINE__);
@@ -85,13 +86,13 @@ namespace Beeps
85
86
  }
86
87
 
87
88
  float
88
- ADSR::attack_time () const
89
+ Envelope::attack_time () const
89
90
  {
90
91
  return self->attack_time;
91
92
  }
92
93
 
93
94
  void
94
- ADSR::set_decay_time (float time)
95
+ Envelope::set_decay_time (float time)
95
96
  {
96
97
  if (time < 0)
97
98
  argument_error(__FILE__, __LINE__);
@@ -103,13 +104,13 @@ namespace Beeps
103
104
  }
104
105
 
105
106
  float
106
- ADSR::decay_time () const
107
+ Envelope::decay_time () const
107
108
  {
108
109
  return self->decay_time;
109
110
  }
110
111
 
111
112
  void
112
- ADSR::set_sustain_level (float level)
113
+ Envelope::set_sustain_level (float level)
113
114
  {
114
115
  if (level < 0)
115
116
  argument_error(__FILE__, __LINE__);
@@ -121,13 +122,13 @@ namespace Beeps
121
122
  }
122
123
 
123
124
  float
124
- ADSR::sustain_level () const
125
+ Envelope::sustain_level () const
125
126
  {
126
127
  return self->sustain_level;
127
128
  }
128
129
 
129
130
  void
130
- ADSR::set_release_time (float time)
131
+ Envelope::set_release_time (float time)
131
132
  {
132
133
  if (time < 0)
133
134
  argument_error(__FILE__, __LINE__);
@@ -139,7 +140,7 @@ namespace Beeps
139
140
  }
140
141
 
141
142
  float
142
- ADSR::release_time () const
143
+ Envelope::release_time () const
143
144
  {
144
145
  return self->release_time;
145
146
  }
@@ -157,11 +158,11 @@ namespace Beeps
157
158
  }
158
159
 
159
160
  static void
160
- process_envelope_signals (ADSR* adsr, Signals* signals)
161
+ process_envelope_signals (Envelope* envelope, Signals* signals)
161
162
  {
162
- assert(adsr && signals && signals->nchannels() == 1);
163
+ assert(envelope && signals && signals->nchannels() == 1);
163
164
 
164
- ADSR::Data* self = adsr->self.get();
165
+ Envelope::Data* self = envelope->self.get();
165
166
 
166
167
  Frames* frames = Signals_get_frames(signals);
167
168
  assert(frames);
@@ -214,7 +215,7 @@ namespace Beeps
214
215
  }
215
216
 
216
217
  void
217
- ADSR::filter (Context* context, Signals* signals, uint* offset)
218
+ Envelope::filter (Context* context, Signals* signals, uint* offset)
218
219
  {
219
220
  Super::filter(context, signals, offset);
220
221
 
@@ -228,10 +229,10 @@ namespace Beeps
228
229
  Signals_resize(&self->adsr_signals, signals->nsamples(), 0);
229
230
 
230
231
  process_envelope_signals(this, &self->adsr_signals);
231
- Signals_apply(signals, self->adsr_signals);
232
+ Signals_multiply(signals, self->adsr_signals);
232
233
  }
233
234
 
234
- ADSR::operator bool () const
235
+ Envelope::operator bool () const
235
236
  {
236
237
  if (!Super::operator bool()) return false;
237
238
  return
data/src/openal.cpp CHANGED
@@ -42,7 +42,9 @@ namespace Beeps
42
42
  void
43
43
  OpenAL_init ()
44
44
  {
45
- if (global::device || global::context)
45
+ if (global::device)
46
+ beeps_error(__FILE__, __LINE__, "already initialized.");
47
+ if (global::context)
46
48
  beeps_error(__FILE__, __LINE__, "already initialized.");
47
49
 
48
50
  global::device = alcOpenDevice(NULL);
data/src/oscillator.cpp CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include <assert.h>
5
5
  #include "SineWave.h"
6
+ #include "Blit.h"
6
7
  #include "BlitSquare.h"
7
8
  #include "BlitSaw.h"
8
9
  #include "beeps/exception.h"
@@ -13,6 +14,70 @@ namespace Beeps
13
14
  {
14
15
 
15
16
 
17
+ class Osc
18
+ {
19
+
20
+ public:
21
+
22
+ virtual ~Osc () {}
23
+
24
+ virtual void reset () = 0;
25
+
26
+ virtual void tick (Frames* frames) = 0;
27
+
28
+ virtual void set_frequency (float freq) = 0;
29
+
30
+ };// Osc
31
+
32
+
33
+ template <typename OSC>
34
+ class StkOsc : public Osc
35
+ {
36
+
37
+ public:
38
+
39
+ void reset () override
40
+ {
41
+ osc.reset();
42
+ }
43
+
44
+ void tick (Frames* frames) override
45
+ {
46
+ osc.tick(*frames);
47
+ }
48
+
49
+ void set_frequency (float freq) override
50
+ {
51
+ osc.setFrequency(freq);
52
+ }
53
+
54
+ protected:
55
+
56
+ OSC osc;
57
+
58
+ };// StkOsc
59
+
60
+
61
+ typedef StkOsc<stk::SineWave> SineOsc;
62
+
63
+ typedef StkOsc<stk::BlitSquare> SquareOsc;
64
+
65
+ typedef StkOsc<stk::BlitSaw> SawtoothOsc;
66
+
67
+
68
+ class TriangleOsc : public StkOsc<stk::Blit>
69
+ {
70
+
71
+ public:
72
+
73
+ TriangleOsc ()
74
+ {
75
+ osc.setHarmonics(10);
76
+ }
77
+
78
+ };// TriangleOsc
79
+
80
+
16
81
  struct Oscillator::Data
17
82
  {
18
83
 
@@ -20,11 +85,7 @@ namespace Beeps
20
85
 
21
86
  float frequency = 440;
22
87
 
23
- std::unique_ptr<stk::SineWave> sine;
24
-
25
- std::unique_ptr<stk::BlitSquare> square;
26
-
27
- std::unique_ptr<stk::BlitSaw> saw;
88
+ std::unique_ptr<Osc> osc;
28
89
 
29
90
  };// Oscillator::Data
30
91
 
@@ -42,10 +103,7 @@ namespace Beeps
42
103
  Oscillator::reset ()
43
104
  {
44
105
  Super::reset();
45
-
46
- if (self->sine) self->sine->reset();
47
- if (self->square) self->square->reset();
48
- if (self->saw) self->saw->reset();
106
+ self->osc->reset();
49
107
  }
50
108
 
51
109
  void
@@ -54,16 +112,14 @@ namespace Beeps
54
112
  if (type == self->type) return;
55
113
 
56
114
  self->type = type;
57
-
58
- self->sine .reset();
59
- self->square.reset();
60
- self->saw .reset();
115
+ self->osc.reset();
61
116
 
62
117
  switch (self->type)
63
118
  {
64
- case SINE: self->sine .reset(new stk::SineWave()); break;
65
- case SQUARE: self->square.reset(new stk::BlitSquare()); break;
66
- case SAWTOOTH: self->saw .reset(new stk::BlitSaw()); break;
119
+ case SINE: self->osc.reset(new SineOsc()); break;
120
+ case TRIANGLE: self->osc.reset(new TriangleOsc()); break;
121
+ case SQUARE: self->osc.reset(new SquareOsc()); break;
122
+ case SAWTOOTH: self->osc.reset(new SawtoothOsc()); break;
67
123
  default:
68
124
  argument_error(
69
125
  __FILE__, __LINE__, "unknown oscilator type '%d'", self->type);
@@ -105,31 +161,8 @@ namespace Beeps
105
161
  if (!frames)
106
162
  argument_error(__FILE__, __LINE__);
107
163
 
108
- switch (self->type)
109
- {
110
- case SINE:
111
- assert(self->sine);
112
- self->sine->setFrequency(self->frequency);
113
- self->sine->tick(*frames);
114
- break;
115
-
116
- case SQUARE:
117
- assert(self->square);
118
- self->square->setFrequency(self->frequency);
119
- self->square->tick(*frames);
120
- break;
121
-
122
- case SAWTOOTH:
123
- assert(self->saw);
124
- self->saw->setFrequency(self->frequency);
125
- self->saw->tick(*frames);
126
- break;
127
-
128
- default:
129
- invalid_state_error(
130
- __FILE__, __LINE__, "unknown oscilator type '%d'", self->type);
131
- break;
132
- }
164
+ self->osc->set_frequency(self->frequency);
165
+ self->osc->tick(frames);
133
166
 
134
167
  Signals_set_nsamples(signals, frames->nframes());
135
168
  }
@@ -137,9 +170,7 @@ namespace Beeps
137
170
  Oscillator::operator bool () const
138
171
  {
139
172
  if (!Super::operator bool()) return false;
140
- return
141
- self->type != TYPE_NONE && self->frequency > 0 &&
142
- (self->sine || self->square || self->saw);
173
+ return self->type != TYPE_NONE && self->frequency > 0 && self->osc;
143
174
  }
144
175
 
145
176
 
data/src/processor.cpp CHANGED
@@ -4,19 +4,13 @@
4
4
  #include <assert.h>
5
5
  #include <xot/time.h>
6
6
  #include "beeps/exception.h"
7
+ #include "beeps/debug.h"
7
8
 
8
9
 
9
10
  namespace Beeps
10
11
  {
11
12
 
12
13
 
13
- static ProcessorContext*
14
- get_context(Processor::Context* context)
15
- {
16
- return (ProcessorContext*) context;
17
- }
18
-
19
-
20
14
  struct Processor::Data
21
15
  {
22
16
 
@@ -36,6 +30,12 @@ namespace Beeps
36
30
  };// Processor::Data
37
31
 
38
32
 
33
+ ProcessorContext*
34
+ Processor_get_context(Processor::Context* context)
35
+ {
36
+ return (ProcessorContext*) context;
37
+ }
38
+
39
39
  float
40
40
  Processor_get_buffering_seconds (Processor* processor)
41
41
  {
@@ -108,24 +108,40 @@ namespace Beeps
108
108
  void
109
109
  Processor::generate (Context* context, Signals* signals, uint* offset)
110
110
  {
111
- if (!context || !signals || !*signals || signals->nsamples() > 0 || !offset)
111
+ if (!context)
112
+ argument_error(__FILE__, __LINE__);
113
+ if (!signals)
114
+ argument_error(__FILE__, __LINE__);
115
+ if (!*signals)
116
+ argument_error(__FILE__, __LINE__);
117
+ if (signals->nsamples() > 0)
118
+ argument_error(__FILE__, __LINE__);
119
+ if (!offset)
112
120
  argument_error(__FILE__, __LINE__);
113
121
 
114
- if (!*this || self->input)
122
+ if (!*this)
123
+ invalid_state_error(__FILE__, __LINE__);
124
+ if (self->input)
115
125
  invalid_state_error(__FILE__, __LINE__);
116
126
  }
117
127
 
118
128
  void
119
129
  Processor::filter (Context* context, Signals* signals, uint* offset)
120
130
  {
121
- if (!context || !signals || !*signals || !offset)
131
+ if (!context)
132
+ argument_error(__FILE__, __LINE__);
133
+ if (!signals)
134
+ argument_error(__FILE__, __LINE__);
135
+ if (!*signals)
136
+ argument_error(__FILE__, __LINE__);
137
+ if (!offset)
122
138
  argument_error(__FILE__, __LINE__);
123
139
 
124
140
  if (!*this)
125
141
  invalid_state_error(__FILE__, __LINE__);
126
142
 
127
143
  if (self->input)
128
- get_context(context)->process(self->input, signals, offset);
144
+ Processor_get_context(context)->process(self->input, signals, offset);
129
145
  }
130
146
 
131
147
  void
@@ -235,25 +251,9 @@ namespace Beeps
235
251
  }
236
252
 
237
253
 
238
- ProcessorContext::ProcessorContext (
239
- uint nsamples_per_process, uint nchannels, double sample_rate)
240
- : signals(Signals_create(nsamples_per_process, nchannels, sample_rate))
241
- {
242
- assert(*this);
243
- }
244
-
245
- Signals
246
- ProcessorContext::process_signals (Processor* processor)
254
+ ProcessorContext::ProcessorContext (uint nchannels, double sample_rate)
255
+ : sample_rate(sample_rate), nchannels(nchannels)
247
256
  {
248
- assert(processor);
249
-
250
- Signals_clear(&signals);
251
- process(processor, &signals, &offset);
252
-
253
- if (signals.nsamples() < signals.capacity())
254
- finished = true;
255
-
256
- return signals.nsamples() > 0 ? signals : Signals();
257
257
  }
258
258
 
259
259
  void
@@ -269,23 +269,6 @@ namespace Beeps
269
269
  processor->process(this, signals, offset);
270
270
  }
271
271
 
272
- bool
273
- ProcessorContext::is_finished () const
274
- {
275
- return finished;
276
- }
277
-
278
- ProcessorContext::operator bool () const
279
- {
280
- return signals && !finished;
281
- }
282
-
283
- bool
284
- ProcessorContext::operator ! () const
285
- {
286
- return !operator bool();
287
- }
288
-
289
272
  static uintptr_t
290
273
  get_buffer_key (Processor* processor)
291
274
  {
@@ -304,13 +287,40 @@ namespace Beeps
304
287
  auto it = buffers.find(key);
305
288
  if (it != buffers.end()) return it->second.get();
306
289
 
307
- SignalsBuffer* buffer = new SignalsBuffer(
308
- buffering_sec * signals.sample_rate(),
309
- signals.nchannels(), signals.sample_rate());
290
+ SignalsBuffer* buffer =
291
+ new SignalsBuffer(buffering_sec * sample_rate, nchannels, sample_rate);
310
292
 
311
293
  buffers.emplace(key, buffer);
312
294
  return buffer;
313
295
  }
314
296
 
315
297
 
298
+ StreamContext::StreamContext (
299
+ uint nsamples_per_process, uint nchannels, double sample_rate)
300
+ : context(nchannels, sample_rate),
301
+ signals(Signals_create(nsamples_per_process, nchannels, sample_rate))
302
+ {
303
+ }
304
+
305
+ Signals
306
+ StreamContext::process_next (Processor* processor)
307
+ {
308
+ assert(processor);
309
+
310
+ Signals_clear(&signals);
311
+ context.process(processor, &signals, &offset);
312
+
313
+ if (signals.nsamples() < signals.capacity())
314
+ finished = true;
315
+
316
+ return signals;
317
+ }
318
+
319
+ bool
320
+ StreamContext::is_finished () const
321
+ {
322
+ return finished;
323
+ }
324
+
325
+
316
326
  }// Beeps
data/src/processor.h CHANGED
@@ -16,6 +16,8 @@ namespace Beeps
16
16
  class ProcessorContext;
17
17
 
18
18
 
19
+ ProcessorContext* Processor_get_context (Processor::Context* context);
20
+
19
21
  float Processor_get_buffering_seconds (Processor* processor);
20
22
 
21
23
 
@@ -56,40 +58,54 @@ namespace Beeps
56
58
 
57
59
  public:
58
60
 
59
- ProcessorContext (
60
- uint nsamples_per_process, uint nchannels, double sample_rate);
61
-
62
- Signals process_signals (Processor* processor);
61
+ ProcessorContext (uint nchannels, double sample_rate);
63
62
 
64
63
  void process (
65
64
  Processor* processor, Signals* signals, uint* offset,
66
65
  bool ignore_buffer = false);
67
66
 
67
+ private:
68
+
69
+ double sample_rate;
70
+
71
+ uint nchannels;
72
+
73
+ std::map<uintptr_t, std::unique_ptr<SignalsBuffer>> buffers;
74
+
75
+ SignalsBuffer* get_buffer (Processor* processor);
76
+
77
+ };// ProcessorContext
78
+
79
+
80
+ class StreamContext
81
+ {
82
+
83
+ public:
84
+
85
+ StreamContext (
86
+ uint nsamples_per_process, uint nchannels, double sample_rate);
87
+
88
+ Signals process_next (Processor* processor);
89
+
68
90
  //void push_offset (uint offset);
69
91
 
70
92
  //uint pop_offset ();
71
93
 
72
94
  bool is_finished () const;
73
95
 
74
- operator bool () const;
75
-
76
- bool operator ! () const;
77
-
78
96
  private:
79
97
 
98
+ ProcessorContext context;
99
+
80
100
  Signals signals;
81
101
 
82
- uint offset = 0;
102
+ uint offset = 0;
83
103
 
84
104
  bool finished = false;
85
105
 
86
106
  //std::vector<uint> offset_stack;
87
107
 
88
- std::map<uintptr_t, std::unique_ptr<SignalsBuffer>> buffers;
89
-
90
- SignalsBuffer* get_buffer (Processor* processor);
91
-
92
- };// ProcessorContext
108
+ };// StreamContext
93
109
 
94
110
 
95
111
  }// Beeps