beeps 0.3 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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