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.
- checksums.yaml +4 -4
- data/.doc/ext/beeps/analyser.cpp +2 -2
- data/.doc/ext/beeps/native.cpp +5 -5
- data/.doc/ext/beeps/oscillator.cpp +2 -2
- data/.doc/ext/beeps/sequencer.cpp +17 -0
- data/.doc/ext/beeps/sound.cpp +1 -1
- data/.doc/ext/beeps/text_in.cpp +63 -0
- data/.doc/ext/beeps/value.cpp +107 -0
- data/CLAUDE.md +24 -0
- data/ChangeLog.md +18 -0
- data/README.md +1 -0
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/beeps.gemspec +2 -2
- data/ext/beeps/analyser.cpp +2 -2
- data/ext/beeps/extconf.rb +10 -6
- data/ext/beeps/native.cpp +5 -5
- data/ext/beeps/oscillator.cpp +2 -2
- data/ext/beeps/sequencer.cpp +18 -0
- data/ext/beeps/sound.cpp +1 -1
- data/ext/beeps/text_in.cpp +66 -0
- data/ext/beeps/value.cpp +114 -0
- data/include/beeps/generator.h +121 -0
- data/include/beeps/ruby/generator.h +22 -0
- data/include/beeps/signals.h +2 -0
- data/lib/beeps/ext.rb +1 -1
- data/lib/beeps/processor.rb +56 -1
- data/src/osx/signals.h +23 -0
- data/src/osx/signals.mm +66 -15
- data/src/osx/text_in.mm +133 -0
- data/src/sdl/beeps.cpp +19 -0
- data/src/sdl/signals.cpp +18 -0
- data/src/sdl/text_in.cpp +61 -0
- data/src/sequencer.cpp +31 -16
- data/src/signals.cpp +104 -30
- data/src/signals.h +10 -4
- data/src/value.cpp +181 -0
- data/src/win32/text_in.cpp +62 -0
- data/test/test_oscillator.rb +2 -2
- data/test/test_sequencer.rb +25 -0
- data/test/test_value.rb +47 -0
- metadata +24 -18
data/include/beeps/generator.h
CHANGED
|
@@ -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
|
|
data/include/beeps/signals.h
CHANGED
data/lib/beeps/ext.rb
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'beeps_ext'
|
data/lib/beeps/processor.rb
CHANGED
|
@@ -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
|
-
|
|
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 "
|
|
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
|
-
|
|
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
|
|
data/src/osx/text_in.mm
ADDED
|
@@ -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
data/src/sdl/signals.cpp
ADDED
data/src/sdl/text_in.cpp
ADDED
|
@@ -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
|