beeps 0.3.8 → 0.3.10

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.
@@ -4,6 +4,7 @@
4
4
  #define __BEEPS_GENERATOR_H__
5
5
 
6
6
 
7
+ #include <list>
7
8
  #include <beeps/processor.h>
8
9
 
9
10
 
@@ -11,6 +12,72 @@ namespace Beeps
11
12
  {
12
13
 
13
14
 
15
+ class Value : public Generator
16
+ {
17
+
18
+ typedef Generator Super;
19
+
20
+ public:
21
+
22
+ enum Type
23
+ {
24
+ TYPE_NONE = 0, LINEAR
25
+ };
26
+
27
+ struct Point
28
+ {
29
+
30
+ float value;
31
+
32
+ float time;
33
+
34
+ Point (float value, float time);
35
+
36
+ };// Point
37
+
38
+ typedef std::vector<Point> PointList;
39
+
40
+ typedef PointList:: iterator iterator;
41
+
42
+ typedef PointList::const_iterator const_iterator;
43
+
44
+ Value (float value = 0, Type type = LINEAR);
45
+
46
+ virtual ~Value ();
47
+
48
+ virtual void set_type (Type type);
49
+
50
+ virtual Type type () const;
51
+
52
+ virtual void set_value (float value);
53
+
54
+ virtual void insert (float value, float time);
55
+
56
+ virtual void clear ();
57
+
58
+ virtual iterator begin ();
59
+
60
+ virtual const_iterator begin () const;
61
+
62
+ virtual iterator end ();
63
+
64
+ virtual const_iterator end () const;
65
+
66
+ struct Data;
67
+
68
+ Xot::PImpl<Data> self;
69
+
70
+ private:
71
+
72
+ virtual void generate (
73
+ Context* context, Signals* signals, uint* offset) override;
74
+
75
+ virtual int max_segment_size_for_process (
76
+ double sample_rate, uint nsamples) const override;
77
+
78
+ };// Value
79
+
80
+
14
81
  class Oscillator : public Generator
15
82
  {
16
83
 
@@ -95,6 +162,23 @@ namespace Beeps
95
162
 
96
163
  public:
97
164
 
165
+ struct Note
166
+ {
167
+
168
+ Processor::Ref processor;
169
+
170
+ float offset, duration;
171
+
172
+ Note (Processor* processor, float offset, float duration);
173
+
174
+ };// Note
175
+
176
+ typedef std::list<Note> NoteList;
177
+
178
+ typedef NoteList:: iterator iterator;
179
+
180
+ typedef NoteList::const_iterator const_iterator;
181
+
98
182
  Sequencer ();
99
183
 
100
184
  virtual ~Sequencer ();
@@ -107,6 +191,14 @@ namespace Beeps
107
191
 
108
192
  virtual float time_scale () const;
109
193
 
194
+ virtual iterator begin ();
195
+
196
+ virtual const_iterator begin () const;
197
+
198
+ virtual iterator end ();
199
+
200
+ virtual const_iterator end () const;
201
+
110
202
  virtual operator bool () const override;
111
203
 
112
204
  struct Data;
@@ -193,6 +285,35 @@ namespace Beeps
193
285
  };// MicIn
194
286
 
195
287
 
288
+ class TextIn : public Generator
289
+ {
290
+
291
+ typedef Generator Super;
292
+
293
+ public:
294
+
295
+ TextIn (const char* text = NULL, double sample_rate = 0);
296
+
297
+ virtual ~TextIn ();
298
+
299
+ virtual void synthesize (const char* text);
300
+
301
+ virtual double sample_rate () const;
302
+
303
+ virtual operator bool () const override;
304
+
305
+ struct Data;
306
+
307
+ Xot::PImpl<Data> self;
308
+
309
+ protected:
310
+
311
+ virtual void generate (
312
+ Context* context, Signals* signals, uint* offset) override;
313
+
314
+ };// TextIn
315
+
316
+
196
317
  }// Beeps
197
318
 
198
319
 
@@ -9,6 +9,8 @@
9
9
  #include <beeps/generator.h>
10
10
 
11
11
 
12
+ RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Value)
13
+
12
14
  RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Oscillator)
13
15
 
14
16
  RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Sequencer)
@@ -17,11 +19,16 @@ RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::FileIn)
17
19
 
18
20
  RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::MicIn)
19
21
 
22
+ RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::TextIn)
23
+
20
24
 
21
25
  namespace Beeps
22
26
  {
23
27
 
24
28
 
29
+ BEEPS_EXPORT Rucy::Class value_class ();
30
+ // class Beeps::Value
31
+
25
32
  BEEPS_EXPORT Rucy::Class oscillator_class ();
26
33
  // class Beeps::Oscillator
27
34
 
@@ -34,6 +41,9 @@ namespace Beeps
34
41
  BEEPS_EXPORT Rucy::Class mic_in_class ();
35
42
  // class Beeps::MicIn
36
43
 
44
+ BEEPS_EXPORT Rucy::Class text_in_class ();
45
+ // class Beeps::TextIn
46
+
37
47
 
38
48
  }// Beeps
39
49
 
@@ -42,6 +52,12 @@ namespace Rucy
42
52
  {
43
53
 
44
54
 
55
+ template <> inline Class
56
+ get_ruby_class<Beeps::Value> ()
57
+ {
58
+ return Beeps::value_class();
59
+ }
60
+
45
61
  template <> inline Class
46
62
  get_ruby_class<Beeps::Oscillator> ()
47
63
  {
@@ -66,6 +82,12 @@ namespace Rucy
66
82
  return Beeps::mic_in_class();
67
83
  }
68
84
 
85
+ template <> inline Class
86
+ get_ruby_class<Beeps::TextIn> ()
87
+ {
88
+ return Beeps::text_in_class();
89
+ }
90
+
69
91
 
70
92
  }// Rucy
71
93
 
@@ -33,6 +33,8 @@ namespace Beeps
33
33
 
34
34
  bool empty () const;
35
35
 
36
+ bool full() const;
37
+
36
38
  const Sample* samples () const;
37
39
 
38
40
  operator bool () const;
data/lib/beeps/ext.rb CHANGED
@@ -1 +1 @@
1
- require 'beeps/native'
1
+ require 'beeps_ext'
@@ -45,6 +45,32 @@ module Beeps
45
45
  end# Processor
46
46
 
47
47
 
48
+ class Value
49
+
50
+ include Enumerable
51
+
52
+ const_symbol_accessor :type, **{
53
+ none: TYPE_NONE,
54
+ linear: LINEAR
55
+ }
56
+
57
+ def initialize(value, type = :linear, **kwargs, &block)
58
+ super(**kwargs, &block)
59
+ self.value, self.type = value, type
60
+ end
61
+
62
+ universal_accessor :type
63
+
64
+ def each_value(&block)
65
+ return enum_for :each_value unless block
66
+ each_value!(&block)
67
+ end
68
+
69
+ alias each each_value
70
+
71
+ end# Value
72
+
73
+
48
74
  class Oscillator
49
75
 
50
76
  include Enumerable
@@ -74,14 +100,33 @@ module Beeps
74
100
  alias freq frequency
75
101
 
76
102
  def each_sample(&block)
77
- block ? each_sample!(&block) : enum_for(:each_sample!)
103
+ return enum_for :each_sample unless block
104
+ each_sample!(&block)
78
105
  end
79
106
 
80
107
  alias each each_sample
81
108
 
109
+ def samples()
110
+ to_a
111
+ end
112
+
82
113
  end# Oscillator
83
114
 
84
115
 
116
+ class Sequencer
117
+
118
+ include Enumerable
119
+
120
+ def each_note(&block)
121
+ return enum_for :each_note unless block
122
+ each_note!(&block)
123
+ end
124
+
125
+ alias each each_note
126
+
127
+ end# Sequencer
128
+
129
+
85
130
  class FileIn
86
131
 
87
132
  def initialize(path = nil, **kwargs, &block)
@@ -94,6 +139,16 @@ module Beeps
94
139
  end# FileIn
95
140
 
96
141
 
142
+ class TextIn
143
+
144
+ def initialize(text = nil, **kwargs, &block)
145
+ super(**kwargs, &block)
146
+ synthesize text if text
147
+ end
148
+
149
+ end# TextIn
150
+
151
+
97
152
  class Gain
98
153
 
99
154
  def initialize(gain = 1, **kwargs, &block)
data/src/osx/signals.h ADDED
@@ -0,0 +1,23 @@
1
+ // -*- c++ -*-
2
+ #pragma once
3
+ #ifndef __BEEPS_SRC_OSX_SIGNALS_H__
4
+ #define __BEEPS_SRC_OSX_SIGNALS_H__
5
+
6
+
7
+ #import <AVFoundation/AVFoundation.h>
8
+ #include "../signals.h"
9
+
10
+
11
+ namespace Beeps
12
+ {
13
+
14
+
15
+ Signals Signals_create (AVAudioPCMBuffer* buffer, uint capacity = 0);
16
+
17
+ void Signals_append (Signals* to, AVAudioPCMBuffer* buffer);
18
+
19
+
20
+ }// Beeps
21
+
22
+
23
+ #endif//EOH
data/src/osx/signals.mm CHANGED
@@ -1,8 +1,7 @@
1
1
  // -*- c++ -*-
2
- #include "../signals.h"
2
+ #include "signals.h"
3
3
 
4
4
 
5
- #import <AVFoundation/AVFoundation.h>
6
5
  #include "beeps/exception.h"
7
6
 
8
7
 
@@ -24,6 +23,70 @@ namespace Beeps
24
23
  }
25
24
 
26
25
 
26
+ Signals
27
+ Signals_create (AVAudioPCMBuffer* buffer, uint capacity)
28
+ {
29
+ if (!buffer)
30
+ argument_error(__FILE__, __LINE__);
31
+
32
+ uint nchannels = buffer.format.channelCount;
33
+ if (nchannels <= 0)
34
+ beeps_error(__FILE__, __LINE__, "invalid nchannels %d", nchannels);
35
+
36
+ uint nsamples = buffer.frameLength;
37
+ if (nsamples <= 0)
38
+ beeps_error(__FILE__, __LINE__, "invalid buffer length %d", nsamples);
39
+
40
+ const float* const* channels = buffer.floatChannelData;
41
+ if (!channels)
42
+ beeps_error(__FILE__, __LINE__, "failed to get channel data");
43
+
44
+ return Signals_create(
45
+ channels, nsamples, nchannels, (uint) buffer.format.sampleRate, capacity);
46
+ }
47
+
48
+ static uint
49
+ get_next_capacity (const Signals& signals, uint nsamples)
50
+ {
51
+ uint cap = signals.capacity();
52
+ while (cap < nsamples) cap *= 2;
53
+ return cap;
54
+ }
55
+
56
+ void
57
+ Signals_append (Signals* to, AVAudioPCMBuffer* buffer)
58
+ {
59
+ if (!buffer)
60
+ argument_error(__FILE__, __LINE__);
61
+
62
+ uint nchannels = buffer.format.channelCount;
63
+ if (nchannels <= 0)
64
+ beeps_error(__FILE__, __LINE__, "invalid nchannels %d", nchannels);
65
+ if (nchannels != to->nchannels())
66
+ beeps_error(__FILE__, __LINE__, "nchannels does not match", nchannels);
67
+
68
+ uint nsamples = buffer.frameLength;
69
+ if (nsamples <= 0)
70
+ beeps_error(__FILE__, __LINE__, "invalid buffer length %d", nsamples);
71
+
72
+ const float* const* channels = buffer.floatChannelData;
73
+ if (!channels)
74
+ beeps_error(__FILE__, __LINE__, "failed to get channel data");
75
+
76
+ uint new_nsamples = to->nsamples() + nsamples;
77
+ if (new_nsamples > to->capacity())
78
+ Signals_set_capacity(to, get_next_capacity(*to, new_nsamples));
79
+
80
+ for (uint channel = 0; channel < nchannels; ++channel)
81
+ {
82
+ Sample* p = Signals_at(to, to->nsamples(), channel);
83
+ for (uint i = 0; i < nsamples; ++i, p += nchannels)
84
+ *p = channels[channel][i];
85
+ }
86
+
87
+ Signals_set_nsamples(to, new_nsamples);
88
+ }
89
+
27
90
  static AVAudioPCMBuffer*
28
91
  load_buffer (const char* path)
29
92
  {
@@ -64,19 +127,7 @@ namespace Beeps
64
127
  AVAudioPCMBuffer* buffer = load_buffer(path);
65
128
  if (!buffer) return Signals();
66
129
 
67
- uint nchannels = buffer.format.channelCount;
68
- if (nchannels <= 0)
69
- beeps_error(__FILE__, __LINE__, "invalid nchannels %d", nchannels);
70
-
71
- uint len = buffer.frameLength;
72
- if (len <= 0)
73
- beeps_error(__FILE__, __LINE__, "invalid buffer length %d", len);
74
-
75
- const float* const* data = buffer.floatChannelData;
76
- if (!data)
77
- beeps_error(__FILE__, __LINE__, "failed to get channel data");
78
-
79
- return Signals_create(data, len, nchannels, (uint) buffer.format.sampleRate);
130
+ return Signals_create(buffer);
80
131
  }
81
132
 
82
133
 
@@ -0,0 +1,133 @@
1
+ // -*- c++ -*-
2
+ #include "beeps/generator.h"
3
+
4
+
5
+ #include <deque>
6
+ #import <Foundation/Foundation.h>
7
+ #include "beeps/exception.h"
8
+ #include "beeps/debug.h"
9
+ #include "signals.h"
10
+
11
+
12
+ namespace Beeps
13
+ {
14
+
15
+
16
+ typedef Xot::Ref<TextIn> TextInRef;
17
+
18
+
19
+ struct TextIn::Data
20
+ {
21
+
22
+ double sample_rate = 0;
23
+
24
+ bool finished = false;
25
+
26
+ Signals signals;
27
+
28
+ };// TextIn::Data
29
+
30
+
31
+ TextIn::TextIn (const char* text, double sample_rate)
32
+ {
33
+ if (sample_rate == 0)
34
+ sample_rate = Beeps::sample_rate();
35
+ if (sample_rate <= 0)
36
+ argument_error(__FILE__, __LINE__);
37
+
38
+ self->sample_rate = sample_rate;
39
+
40
+ if (text) synthesize(text);
41
+ }
42
+
43
+ TextIn::~TextIn ()
44
+ {
45
+ }
46
+
47
+ void
48
+ TextIn::synthesize (const char* text)
49
+ {
50
+ if (@available(macOS 10.15, *))
51
+ {
52
+ TextInRef pthis = this;
53
+ AVSpeechSynthesizer* synth = [[AVSpeechSynthesizer alloc] init];
54
+
55
+ NSString* str = [NSString stringWithUTF8String: text];
56
+ auto* utt = [[[AVSpeechUtterance alloc] initWithString: str] autorelease];
57
+ utt.voice = [AVSpeechSynthesisVoice voiceWithLanguage: @"ja-JP"];
58
+ utt.rate = 0.5;
59
+
60
+ [synth writeUtterance: utt
61
+ toBufferCallback: ^(AVAudioBuffer* buffer)
62
+ {
63
+ auto finish = [&]()
64
+ {
65
+ pthis->self->finished = true;
66
+ [synth release];
67
+ };
68
+
69
+ if (![buffer isKindOfClass: AVAudioPCMBuffer.class])
70
+ return finish();
71
+
72
+ AVAudioPCMBuffer* pcmbuf = (AVAudioPCMBuffer*) buffer;
73
+ if (pcmbuf.frameLength == 0)
74
+ return finish();
75
+
76
+ [pcmbuf retain];
77
+ dispatch_async(dispatch_get_main_queue(), ^()
78
+ {
79
+ if (!pthis->self->signals)
80
+ pthis->self->signals = Signals_create(pcmbuf, 4096);
81
+ else
82
+ Signals_append(&pthis->self->signals, pcmbuf);
83
+ [pcmbuf release];
84
+ });
85
+ }];
86
+ }
87
+ else
88
+ not_implemented_error(__FILE__, __LINE__);
89
+ }
90
+
91
+ double
92
+ TextIn::sample_rate () const
93
+ {
94
+ return self->sample_rate;
95
+ }
96
+
97
+ TextIn::operator bool () const
98
+ {
99
+ if (!Super::operator bool()) return false;
100
+ return self->sample_rate > 0;
101
+ }
102
+
103
+ void
104
+ TextIn::generate (Context* context, Signals* signals, uint* offset)
105
+ {
106
+ Super::generate(context, signals, offset);
107
+
108
+ if (self->signals)
109
+ {
110
+ if (signals->sample_rate() != self->signals.sample_rate())
111
+ {
112
+ beeps_error(
113
+ __FILE__, __LINE__,
114
+ "sample_rate does not match: %f and %f",
115
+ signals->sample_rate(),
116
+ self->signals.sample_rate());
117
+ }
118
+
119
+ uint copied_size = Signals_copy(signals, self->signals);
120
+ Signals_shift(&self->signals, copied_size);
121
+ *offset += copied_size;
122
+ }
123
+
124
+ if (!self->finished)
125
+ {
126
+ uint fill_size = signals->capacity() - signals->nsamples();
127
+ Signals_fill(signals, fill_size, 0, signals->nsamples());
128
+ *offset += fill_size;
129
+ }
130
+ }
131
+
132
+
133
+ }// Beeps
data/src/sdl/beeps.cpp ADDED
@@ -0,0 +1,19 @@
1
+ #include "../beeps.h"
2
+
3
+
4
+ namespace Beeps
5
+ {
6
+
7
+
8
+ void
9
+ Beeps_init ()
10
+ {
11
+ }
12
+
13
+ void
14
+ Beeps_fin ()
15
+ {
16
+ }
17
+
18
+
19
+ }// Beeps
@@ -0,0 +1,18 @@
1
+ #include "../signals.h"
2
+
3
+
4
+ #include "beeps/exception.h"
5
+
6
+
7
+ namespace Beeps
8
+ {
9
+
10
+
11
+ Signals
12
+ Signals_load (const char* path)
13
+ {
14
+ not_implemented_error(__FILE__, __LINE__);
15
+ }
16
+
17
+
18
+ }// Beeps
@@ -0,0 +1,61 @@
1
+ #include "beeps/generator.h"
2
+
3
+
4
+ #include "beeps/exception.h"
5
+ #include "../signals.h"
6
+
7
+
8
+ namespace Beeps
9
+ {
10
+
11
+
12
+ struct TextIn::Data
13
+ {
14
+
15
+ double sample_rate = 0;
16
+
17
+ };// TextIn::Data
18
+
19
+
20
+ TextIn::TextIn (const char* text, double sample_rate)
21
+ {
22
+ if (sample_rate == 0)
23
+ sample_rate = Beeps::sample_rate();
24
+ if (sample_rate <= 0)
25
+ argument_error(__FILE__, __LINE__);
26
+
27
+ self->sample_rate = sample_rate;
28
+
29
+ if (text) synthesize(text);
30
+ }
31
+
32
+ TextIn::~TextIn ()
33
+ {
34
+ }
35
+
36
+ void
37
+ TextIn::synthesize (const char* text)
38
+ {
39
+ not_implemented_error(__FILE__, __LINE__);
40
+ }
41
+
42
+ double
43
+ TextIn::sample_rate () const
44
+ {
45
+ return self->sample_rate;
46
+ }
47
+
48
+ TextIn::operator bool () const
49
+ {
50
+ if (!Super::operator bool()) return false;
51
+ return self->sample_rate > 0;
52
+ }
53
+
54
+ void
55
+ TextIn::generate (Context* context, Signals* signals, uint* offset)
56
+ {
57
+ Super::generate(context, signals, offset);
58
+ }
59
+
60
+
61
+ }// Beeps