beeps 0.3.8 → 0.3.9
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/native.cpp +2 -0
- data/.doc/ext/beeps/sound.cpp +1 -1
- data/.doc/ext/beeps/text_in.cpp +63 -0
- data/ChangeLog.md +9 -0
- data/README.md +1 -0
- data/VERSION +1 -1
- data/beeps.gemspec +2 -2
- data/ext/beeps/native.cpp +2 -0
- data/ext/beeps/sound.cpp +1 -1
- data/ext/beeps/text_in.cpp +66 -0
- data/include/beeps/generator.h +29 -0
- data/include/beeps/ruby/generator.h +11 -0
- data/include/beeps/signals.h +2 -0
- data/lib/beeps/processor.rb +10 -0
- data/src/osx/signals.h +23 -0
- data/src/osx/signals.mm +66 -15
- data/src/osx/text_in.mm +133 -0
- data/src/signals.cpp +104 -30
- data/src/signals.h +10 -4
- data/src/win32/text_in.cpp +62 -0
- metadata +16 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8f411f90d8d0ed9b8672d08b5039799ac6f9178835dac7dc24acccd8c93cc0e
|
4
|
+
data.tar.gz: e7ba8574e7962d3b9de62238f4f42cb897dd0edbecce3d298928acc07f2fe161
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4874e8fba3a4e1962853b9ce05454c703065b89c77fa89a286aebbf76bc775c43fb9f6e47c326b9725d005d8f2c680a13ee6981d686836a50e19900ab4c9436e
|
7
|
+
data.tar.gz: f84446b0b666cc6852fc95845e303668c844012208210b647bc71611539972d0d24339113ade1b1903d0df5f2cbc9264ff2d339dfdcf4bccb9ee6e501f6eb163
|
data/.doc/ext/beeps/native.cpp
CHANGED
@@ -13,6 +13,7 @@ void Init_beeps_oscillator ();
|
|
13
13
|
void Init_beeps_sequencer ();
|
14
14
|
void Init_beeps_file_in ();
|
15
15
|
void Init_beeps_mic_in ();
|
16
|
+
void Init_beeps_text_in ();
|
16
17
|
|
17
18
|
void Init_beeps_gain ();
|
18
19
|
void Init_beeps_mixer ();
|
@@ -48,6 +49,7 @@ extern "C" void
|
|
48
49
|
Init_beeps_sequencer();
|
49
50
|
Init_beeps_file_in();
|
50
51
|
Init_beeps_mic_in();
|
52
|
+
Init_beeps_text_in();
|
51
53
|
|
52
54
|
Init_beeps_gain();
|
53
55
|
Init_beeps_mixer();
|
data/.doc/ext/beeps/sound.cpp
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
#include "beeps/ruby/generator.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include "beeps/ruby/processor.h"
|
5
|
+
#include "defs.h"
|
6
|
+
|
7
|
+
|
8
|
+
RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::TextIn)
|
9
|
+
|
10
|
+
#define THIS to<Beeps::TextIn*>(self)
|
11
|
+
|
12
|
+
#define CHECK RUCY_CHECK_OBJ(Beeps::TextIn, self)
|
13
|
+
|
14
|
+
|
15
|
+
static
|
16
|
+
VALUE alloc(VALUE klass)
|
17
|
+
{
|
18
|
+
return value(new Beeps::RubyProcessor<Beeps::TextIn>, klass);
|
19
|
+
}
|
20
|
+
|
21
|
+
static
|
22
|
+
VALUE synthesize(VALUE self, VALUE text)
|
23
|
+
{
|
24
|
+
CHECK;
|
25
|
+
|
26
|
+
THIS->synthesize(text.c_str());
|
27
|
+
}
|
28
|
+
|
29
|
+
static
|
30
|
+
VALUE get_sample_rate(VALUE self)
|
31
|
+
{
|
32
|
+
CHECK;
|
33
|
+
|
34
|
+
return value(THIS->sample_rate());
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
static Class cTextIn;
|
39
|
+
|
40
|
+
void
|
41
|
+
Init_beeps_text_in ()
|
42
|
+
{
|
43
|
+
Module mBeeps = rb_define_module("Beeps");
|
44
|
+
|
45
|
+
cTextIn = mBeeps.define_class("TextIn", Beeps::processor_class());
|
46
|
+
rb_define_alloc_func(cTextIn, alloc);
|
47
|
+
rb_define_method(cTextIn, "synthesize", RUBY_METHOD_FUNC(synthesize), 1);
|
48
|
+
rb_define_method(cTextIn, "sample_rate", RUBY_METHOD_FUNC(get_sample_rate), 0);
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
namespace Beeps
|
53
|
+
{
|
54
|
+
|
55
|
+
|
56
|
+
Class
|
57
|
+
text_in_class ()
|
58
|
+
{
|
59
|
+
return cTextIn;
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
}// Beeps
|
data/ChangeLog.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# beeps ChangeLog
|
2
2
|
|
3
3
|
|
4
|
+
## [v0.3.9] - 2025-07-06
|
5
|
+
|
6
|
+
- Add TextIn class
|
7
|
+
- Add Signals::full()
|
8
|
+
- Add Siangls_shift() and Signals_set_capacity()
|
9
|
+
- Add Signals_create() and Signals_append() for AVAudioPCMBuffer
|
10
|
+
- Add deepwiki badge
|
11
|
+
|
12
|
+
|
4
13
|
## [v0.3.8] - 2025-05-22
|
5
14
|
|
6
15
|
- The oscillator resets the frequency to 0.001 if it is set to 0
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Beeps - Plays beep sound
|
2
2
|
|
3
|
+
[](https://deepwiki.com/xord/beeps)
|
3
4
|

|
4
5
|

|
5
6
|

|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.9
|
data/beeps.gemspec
CHANGED
@@ -25,8 +25,8 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.platform = Gem::Platform::RUBY
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
27
27
|
|
28
|
-
s.add_dependency 'xot', '~> 0.3.
|
29
|
-
s.add_dependency 'rucy', '~> 0.3.
|
28
|
+
s.add_dependency 'xot', '~> 0.3.9', '>= 0.3.9'
|
29
|
+
s.add_dependency 'rucy', '~> 0.3.9', '>= 0.3.9'
|
30
30
|
|
31
31
|
s.files = `git ls-files`.split $/
|
32
32
|
s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
|
data/ext/beeps/native.cpp
CHANGED
@@ -13,6 +13,7 @@ void Init_beeps_oscillator ();
|
|
13
13
|
void Init_beeps_sequencer ();
|
14
14
|
void Init_beeps_file_in ();
|
15
15
|
void Init_beeps_mic_in ();
|
16
|
+
void Init_beeps_text_in ();
|
16
17
|
|
17
18
|
void Init_beeps_gain ();
|
18
19
|
void Init_beeps_mixer ();
|
@@ -48,6 +49,7 @@ extern "C" void
|
|
48
49
|
Init_beeps_sequencer();
|
49
50
|
Init_beeps_file_in();
|
50
51
|
Init_beeps_mic_in();
|
52
|
+
Init_beeps_text_in();
|
51
53
|
|
52
54
|
Init_beeps_gain();
|
53
55
|
Init_beeps_mixer();
|
data/ext/beeps/sound.cpp
CHANGED
@@ -0,0 +1,66 @@
|
|
1
|
+
#include "beeps/ruby/generator.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include "beeps/ruby/processor.h"
|
5
|
+
#include "defs.h"
|
6
|
+
|
7
|
+
|
8
|
+
RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::TextIn)
|
9
|
+
|
10
|
+
#define THIS to<Beeps::TextIn*>(self)
|
11
|
+
|
12
|
+
#define CHECK RUCY_CHECK_OBJ(Beeps::TextIn, self)
|
13
|
+
|
14
|
+
|
15
|
+
static
|
16
|
+
RUCY_DEF_ALLOC(alloc, klass)
|
17
|
+
{
|
18
|
+
return value(new Beeps::RubyProcessor<Beeps::TextIn>, klass);
|
19
|
+
}
|
20
|
+
RUCY_END
|
21
|
+
|
22
|
+
static
|
23
|
+
RUCY_DEF1(synthesize, text)
|
24
|
+
{
|
25
|
+
CHECK;
|
26
|
+
|
27
|
+
THIS->synthesize(text.c_str());
|
28
|
+
}
|
29
|
+
RUCY_END
|
30
|
+
|
31
|
+
static
|
32
|
+
RUCY_DEF0(get_sample_rate)
|
33
|
+
{
|
34
|
+
CHECK;
|
35
|
+
|
36
|
+
return value(THIS->sample_rate());
|
37
|
+
}
|
38
|
+
RUCY_END
|
39
|
+
|
40
|
+
|
41
|
+
static Class cTextIn;
|
42
|
+
|
43
|
+
void
|
44
|
+
Init_beeps_text_in ()
|
45
|
+
{
|
46
|
+
Module mBeeps = define_module("Beeps");
|
47
|
+
|
48
|
+
cTextIn = mBeeps.define_class("TextIn", Beeps::processor_class());
|
49
|
+
cTextIn.define_alloc_func(alloc);
|
50
|
+
cTextIn.define_method("synthesize", synthesize);
|
51
|
+
cTextIn.define_method("sample_rate", get_sample_rate);
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
namespace Beeps
|
56
|
+
{
|
57
|
+
|
58
|
+
|
59
|
+
Class
|
60
|
+
text_in_class ()
|
61
|
+
{
|
62
|
+
return cTextIn;
|
63
|
+
}
|
64
|
+
|
65
|
+
|
66
|
+
}// Beeps
|
data/include/beeps/generator.h
CHANGED
@@ -193,6 +193,35 @@ namespace Beeps
|
|
193
193
|
};// MicIn
|
194
194
|
|
195
195
|
|
196
|
+
class TextIn : public Generator
|
197
|
+
{
|
198
|
+
|
199
|
+
typedef Generator Super;
|
200
|
+
|
201
|
+
public:
|
202
|
+
|
203
|
+
TextIn (const char* text = NULL, double sample_rate = 0);
|
204
|
+
|
205
|
+
virtual ~TextIn ();
|
206
|
+
|
207
|
+
virtual void synthesize (const char* text);
|
208
|
+
|
209
|
+
virtual double sample_rate () const;
|
210
|
+
|
211
|
+
virtual operator bool () const override;
|
212
|
+
|
213
|
+
struct Data;
|
214
|
+
|
215
|
+
Xot::PImpl<Data> self;
|
216
|
+
|
217
|
+
protected:
|
218
|
+
|
219
|
+
virtual void generate (
|
220
|
+
Context* context, Signals* signals, uint* offset) override;
|
221
|
+
|
222
|
+
};// TextIn
|
223
|
+
|
224
|
+
|
196
225
|
}// Beeps
|
197
226
|
|
198
227
|
|
@@ -17,6 +17,8 @@ RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::FileIn)
|
|
17
17
|
|
18
18
|
RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::MicIn)
|
19
19
|
|
20
|
+
RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::TextIn)
|
21
|
+
|
20
22
|
|
21
23
|
namespace Beeps
|
22
24
|
{
|
@@ -34,6 +36,9 @@ namespace Beeps
|
|
34
36
|
BEEPS_EXPORT Rucy::Class mic_in_class ();
|
35
37
|
// class Beeps::MicIn
|
36
38
|
|
39
|
+
BEEPS_EXPORT Rucy::Class text_in_class ();
|
40
|
+
// class Beeps::TextIn
|
41
|
+
|
37
42
|
|
38
43
|
}// Beeps
|
39
44
|
|
@@ -66,6 +71,12 @@ namespace Rucy
|
|
66
71
|
return Beeps::mic_in_class();
|
67
72
|
}
|
68
73
|
|
74
|
+
template <> inline Class
|
75
|
+
get_ruby_class<Beeps::TextIn> ()
|
76
|
+
{
|
77
|
+
return Beeps::text_in_class();
|
78
|
+
}
|
79
|
+
|
69
80
|
|
70
81
|
}// Rucy
|
71
82
|
|
data/include/beeps/signals.h
CHANGED
data/lib/beeps/processor.rb
CHANGED
@@ -94,6 +94,16 @@ module Beeps
|
|
94
94
|
end# FileIn
|
95
95
|
|
96
96
|
|
97
|
+
class TextIn
|
98
|
+
|
99
|
+
def initialize(text = nil, **kwargs, &block)
|
100
|
+
super(**kwargs, &block)
|
101
|
+
synthesize text if text
|
102
|
+
end
|
103
|
+
|
104
|
+
end# TextIn
|
105
|
+
|
106
|
+
|
97
107
|
class Gain
|
98
108
|
|
99
109
|
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/signals.cpp
CHANGED
@@ -116,13 +116,13 @@ namespace Beeps
|
|
116
116
|
Signals
|
117
117
|
Signals_create (
|
118
118
|
const float* const* channels,
|
119
|
-
uint nsamples, uint nchannels, double sample_rate)
|
119
|
+
uint nsamples, uint nchannels, double sample_rate, uint capacity)
|
120
120
|
{
|
121
121
|
if (!channels)
|
122
122
|
argument_error(__FILE__, __LINE__);
|
123
123
|
|
124
|
-
Signals s
|
125
|
-
|
124
|
+
Signals s = Signals_create(
|
125
|
+
capacity > nsamples ? capacity : nsamples, nchannels, sample_rate);
|
126
126
|
|
127
127
|
for (uint channel = 0; channel < nchannels; ++channel)
|
128
128
|
{
|
@@ -131,32 +131,10 @@ namespace Beeps
|
|
131
131
|
*p = channels[channel][i];
|
132
132
|
}
|
133
133
|
|
134
|
+
s.self->nsamples = nsamples;
|
134
135
|
return s;
|
135
136
|
}
|
136
137
|
|
137
|
-
void
|
138
|
-
Signals_clear (Signals* signals)
|
139
|
-
{
|
140
|
-
if (!signals)
|
141
|
-
argument_error(__FILE__, __LINE__);
|
142
|
-
|
143
|
-
signals->self->nsamples = 0;
|
144
|
-
}
|
145
|
-
|
146
|
-
void
|
147
|
-
Signals_clear (Signals* signals, uint capacity)
|
148
|
-
{
|
149
|
-
if (!signals)
|
150
|
-
argument_error(__FILE__, __LINE__);
|
151
|
-
if (!*signals)
|
152
|
-
argument_error(__FILE__, __LINE__);
|
153
|
-
if (capacity <= 0)
|
154
|
-
argument_error(__FILE__, __LINE__);
|
155
|
-
|
156
|
-
Signals_clear(signals);
|
157
|
-
signals->self->frames->resize(capacity, signals->nchannels());
|
158
|
-
}
|
159
|
-
|
160
138
|
uint
|
161
139
|
Signals_tick (Signals* signals, std::function<void(stk::StkFrames*)> fun)
|
162
140
|
{
|
@@ -212,20 +190,70 @@ namespace Beeps
|
|
212
190
|
}
|
213
191
|
|
214
192
|
void
|
215
|
-
|
193
|
+
Signals_clear (Signals* signals)
|
194
|
+
{
|
195
|
+
if (!signals)
|
196
|
+
argument_error(__FILE__, __LINE__);
|
197
|
+
|
198
|
+
signals->self->nsamples = 0;
|
199
|
+
}
|
200
|
+
|
201
|
+
void
|
202
|
+
Signals_clear (Signals* signals, uint capacity)
|
216
203
|
{
|
217
204
|
if (!signals)
|
218
205
|
argument_error(__FILE__, __LINE__);
|
219
206
|
if (!*signals)
|
220
207
|
argument_error(__FILE__, __LINE__);
|
208
|
+
if (capacity <= 0)
|
209
|
+
argument_error(__FILE__, __LINE__);
|
221
210
|
|
222
211
|
Signals_clear(signals);
|
223
|
-
|
212
|
+
signals->self->frames->resize(capacity, signals->nchannels());
|
213
|
+
}
|
224
214
|
|
225
|
-
|
215
|
+
void
|
216
|
+
Signals_fill (Signals* signals, uint nsamples, Sample value, uint offset)
|
217
|
+
{
|
218
|
+
if (!signals)
|
219
|
+
argument_error(__FILE__, __LINE__);
|
220
|
+
if (!*signals)
|
221
|
+
argument_error(__FILE__, __LINE__);
|
222
|
+
|
223
|
+
uint new_nsamples = offset + nsamples;
|
224
|
+
if (new_nsamples > signals->capacity())
|
225
|
+
beeps_error(__FILE__, __LINE__);
|
226
|
+
|
227
|
+
Sample* p = Signals_at(signals, offset);
|
226
228
|
size_t size = nsamples * signals->nchannels();
|
227
229
|
for (size_t i = 0; i < size; ++i)
|
228
230
|
*p++ = value;
|
231
|
+
|
232
|
+
Signals_set_nsamples(signals, new_nsamples);
|
233
|
+
}
|
234
|
+
|
235
|
+
void
|
236
|
+
Signals_shift (Signals* signals, uint nsamples)
|
237
|
+
{
|
238
|
+
if (!signals)
|
239
|
+
argument_error(__FILE__, __LINE__);
|
240
|
+
if (!*signals)
|
241
|
+
argument_error(__FILE__, __LINE__);
|
242
|
+
|
243
|
+
if (nsamples == 0)
|
244
|
+
return;
|
245
|
+
|
246
|
+
int new_nsamples = signals->nsamples() - nsamples;
|
247
|
+
if (new_nsamples < 0)
|
248
|
+
new_nsamples = 0;
|
249
|
+
|
250
|
+
Sample* from = Signals_at(signals, nsamples);
|
251
|
+
Sample* to = Signals_at(signals, 0);
|
252
|
+
int size = new_nsamples * signals->nchannels();
|
253
|
+
for (int i = 0; i < size; ++i)
|
254
|
+
*to++ = *from++;
|
255
|
+
|
256
|
+
Signals_set_nsamples(signals, new_nsamples);
|
229
257
|
}
|
230
258
|
|
231
259
|
static uint
|
@@ -450,6 +478,43 @@ namespace Beeps
|
|
450
478
|
write_samples(signals, samples, nsamples);
|
451
479
|
}
|
452
480
|
|
481
|
+
void
|
482
|
+
Signals_set_capacity (Signals* signals, uint capacity)
|
483
|
+
{
|
484
|
+
if (!signals)
|
485
|
+
argument_error(__FILE__, __LINE__);
|
486
|
+
if (!*signals)
|
487
|
+
argument_error(__FILE__, __LINE__);
|
488
|
+
if (capacity == 0)
|
489
|
+
argument_error(__FILE__, __LINE__);
|
490
|
+
|
491
|
+
if (capacity == signals->capacity())
|
492
|
+
return;
|
493
|
+
|
494
|
+
uint nsamples = signals->nsamples();
|
495
|
+
uint nchannels = signals->nchannels();
|
496
|
+
|
497
|
+
if (capacity < signals->capacity())
|
498
|
+
{
|
499
|
+
signals->self->frames->resize(capacity, nchannels);
|
500
|
+
if (capacity < nsamples) Signals_set_nsamples(signals, capacity);
|
501
|
+
}
|
502
|
+
else
|
503
|
+
{
|
504
|
+
double sample_rate = signals->sample_rate();
|
505
|
+
const Sample* from = Signals_at(signals, 0);
|
506
|
+
|
507
|
+
std::unique_ptr<Frames> old = std::move(signals->self->frames);
|
508
|
+
signals->self->frames.reset(
|
509
|
+
new Frames(capacity * nchannels, nchannels, sample_rate));
|
510
|
+
|
511
|
+
Sample* to = Signals_at(signals, 0);
|
512
|
+
uint size = nsamples * nchannels;
|
513
|
+
for (uint i = 0; i < size; ++i)
|
514
|
+
*to++ = *from++;
|
515
|
+
}
|
516
|
+
}
|
517
|
+
|
453
518
|
void
|
454
519
|
Signals_set_nsamples (Signals* signals, uint nsamples)
|
455
520
|
{
|
@@ -568,7 +633,16 @@ namespace Beeps
|
|
568
633
|
bool
|
569
634
|
Signals::empty () const
|
570
635
|
{
|
571
|
-
return
|
636
|
+
return nsamples() == 0;
|
637
|
+
}
|
638
|
+
|
639
|
+
bool
|
640
|
+
Signals::full () const
|
641
|
+
{
|
642
|
+
uint n = nsamples();
|
643
|
+
if (n == 0) return false;
|
644
|
+
|
645
|
+
return n == capacity();
|
572
646
|
}
|
573
647
|
|
574
648
|
const Sample*
|
data/src/signals.h
CHANGED
@@ -26,7 +26,7 @@ namespace Beeps
|
|
26
26
|
|
27
27
|
Signals Signals_create (
|
28
28
|
const float* const* channels,
|
29
|
-
uint nsamples, uint nchannels, double sample_rate = 0);
|
29
|
+
uint nsamples, uint nchannels, double sample_rate = 0, uint capacity = 0);
|
30
30
|
|
31
31
|
uint Signals_tick (
|
32
32
|
Signals* signals,
|
@@ -44,9 +44,13 @@ namespace Beeps
|
|
44
44
|
|
45
45
|
void Signals_clear (Signals* signals, uint capacity);
|
46
46
|
|
47
|
-
void Signals_fill (
|
47
|
+
void Signals_fill (
|
48
|
+
Signals* signals, uint nsamples, Sample value,
|
49
|
+
uint offset = 0);
|
48
50
|
|
49
|
-
|
51
|
+
void Signals_shift (Signals* signals, uint nsamples);
|
52
|
+
|
53
|
+
uint Signals_copy (Signals* to, const Signals& from, uint from_offset = 0);
|
50
54
|
|
51
55
|
void Signals_add ( Signals* signals, const Signals& add);
|
52
56
|
|
@@ -60,7 +64,9 @@ namespace Beeps
|
|
60
64
|
void Signals_write_samples (
|
61
65
|
Signals* signals, const SignalSamples<T>& samples, long nsamples = -1);
|
62
66
|
|
63
|
-
void
|
67
|
+
void Signals_set_capacity (Signals* signals, uint capacity);
|
68
|
+
|
69
|
+
void Signals_set_nsamples (Signals* signals, uint nsamples);
|
64
70
|
|
65
71
|
Sample* Signals_at ( Signals* signals, uint index, uint channel = 0);
|
66
72
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
// -*- c++ -*-
|
2
|
+
#include "beeps/generator.h"
|
3
|
+
|
4
|
+
|
5
|
+
#include "beeps/exception.h"
|
6
|
+
#include "../signals.h"
|
7
|
+
|
8
|
+
|
9
|
+
namespace Beeps
|
10
|
+
{
|
11
|
+
|
12
|
+
|
13
|
+
struct TextIn::Data
|
14
|
+
{
|
15
|
+
|
16
|
+
double sample_rate = 0;
|
17
|
+
|
18
|
+
};// TextIn::Data
|
19
|
+
|
20
|
+
|
21
|
+
TextIn::TextIn (const char* text, double sample_rate)
|
22
|
+
{
|
23
|
+
if (sample_rate == 0)
|
24
|
+
sample_rate = Beeps::sample_rate();
|
25
|
+
if (sample_rate <= 0)
|
26
|
+
argument_error(__FILE__, __LINE__);
|
27
|
+
|
28
|
+
self->sample_rate = sample_rate;
|
29
|
+
|
30
|
+
if (text) synthesize(text);
|
31
|
+
}
|
32
|
+
|
33
|
+
TextIn::~TextIn ()
|
34
|
+
{
|
35
|
+
}
|
36
|
+
|
37
|
+
void
|
38
|
+
TextIn::synthesize (const char* text)
|
39
|
+
{
|
40
|
+
not_implemented_error(__FILE__, __LINE__);
|
41
|
+
}
|
42
|
+
|
43
|
+
double
|
44
|
+
TextIn::sample_rate () const
|
45
|
+
{
|
46
|
+
return self->sample_rate;
|
47
|
+
}
|
48
|
+
|
49
|
+
TextIn::operator bool () const
|
50
|
+
{
|
51
|
+
if (!Super::operator bool()) return false;
|
52
|
+
return self->sample_rate > 0;
|
53
|
+
}
|
54
|
+
|
55
|
+
void
|
56
|
+
TextIn::generate (Context* context, Signals* signals, uint* offset)
|
57
|
+
{
|
58
|
+
Super::generate(context, signals, offset);
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
}// Beeps
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beeps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- xordog
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05
|
11
|
+
date: 2025-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xot
|
@@ -16,40 +16,40 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.3.
|
19
|
+
version: 0.3.9
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.3.
|
22
|
+
version: 0.3.9
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.3.
|
29
|
+
version: 0.3.9
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.3.
|
32
|
+
version: 0.3.9
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rucy
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 0.3.
|
39
|
+
version: 0.3.9
|
40
40
|
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 0.3.
|
42
|
+
version: 0.3.9
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 0.3.
|
49
|
+
version: 0.3.9
|
50
50
|
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: 0.3.
|
52
|
+
version: 0.3.9
|
53
53
|
description: Synthesize and play beep sounds.
|
54
54
|
email: xordog@gmail.com
|
55
55
|
executables: []
|
@@ -75,6 +75,7 @@ extra_rdoc_files:
|
|
75
75
|
- ".doc/ext/beeps/signals.cpp"
|
76
76
|
- ".doc/ext/beeps/sound.cpp"
|
77
77
|
- ".doc/ext/beeps/sound_player.cpp"
|
78
|
+
- ".doc/ext/beeps/text_in.cpp"
|
78
79
|
- ".doc/ext/beeps/time_stretch.cpp"
|
79
80
|
files:
|
80
81
|
- ".doc/ext/beeps/analyser.cpp"
|
@@ -96,6 +97,7 @@ files:
|
|
96
97
|
- ".doc/ext/beeps/signals.cpp"
|
97
98
|
- ".doc/ext/beeps/sound.cpp"
|
98
99
|
- ".doc/ext/beeps/sound_player.cpp"
|
100
|
+
- ".doc/ext/beeps/text_in.cpp"
|
99
101
|
- ".doc/ext/beeps/time_stretch.cpp"
|
100
102
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
101
103
|
- ".github/workflows/release-gem.yml"
|
@@ -132,6 +134,7 @@ files:
|
|
132
134
|
- ext/beeps/signals.cpp
|
133
135
|
- ext/beeps/sound.cpp
|
134
136
|
- ext/beeps/sound_player.cpp
|
137
|
+
- ext/beeps/text_in.cpp
|
135
138
|
- ext/beeps/time_stretch.cpp
|
136
139
|
- include/beeps.h
|
137
140
|
- include/beeps/beeps.h
|
@@ -176,7 +179,9 @@ files:
|
|
176
179
|
- src/openal.h
|
177
180
|
- src/oscillator.cpp
|
178
181
|
- src/osx/beeps.mm
|
182
|
+
- src/osx/signals.h
|
179
183
|
- src/osx/signals.mm
|
184
|
+
- src/osx/text_in.mm
|
180
185
|
- src/pitch_shift.cpp
|
181
186
|
- src/processor.cpp
|
182
187
|
- src/processor.h
|
@@ -191,6 +196,7 @@ files:
|
|
191
196
|
- src/win32/exception.cpp
|
192
197
|
- src/win32/exception.h
|
193
198
|
- src/win32/signals.cpp
|
199
|
+
- src/win32/text_in.cpp
|
194
200
|
- src/x_pass.h
|
195
201
|
- test/helper.rb
|
196
202
|
- test/test_analyser.rb
|