beeps 0.4.0 → 0.5.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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/beeps/analyser.cpp +1 -1
  3. data/.doc/ext/beeps/envelope.cpp +1 -1
  4. data/.doc/ext/beeps/file_in.cpp +1 -1
  5. data/.doc/ext/beeps/gain.cpp +1 -1
  6. data/.doc/ext/beeps/high_pass.cpp +1 -1
  7. data/.doc/ext/beeps/low_pass.cpp +1 -1
  8. data/.doc/ext/beeps/mic_in.cpp +1 -1
  9. data/.doc/ext/beeps/mixer.cpp +1 -1
  10. data/.doc/ext/beeps/oscillator.cpp +2 -2
  11. data/.doc/ext/beeps/pitch_shift.cpp +1 -1
  12. data/.doc/ext/beeps/processor.cpp +1 -1
  13. data/.doc/ext/beeps/reverb.cpp +1 -1
  14. data/.doc/ext/beeps/sequencer.cpp +1 -1
  15. data/.doc/ext/beeps/signals.cpp +1 -1
  16. data/.doc/ext/beeps/sound.cpp +6 -6
  17. data/.doc/ext/beeps/sound_player.cpp +5 -5
  18. data/.doc/ext/beeps/text_in.cpp +1 -1
  19. data/.doc/ext/beeps/time_stretch.cpp +1 -1
  20. data/.doc/ext/beeps/value.cpp +1 -1
  21. data/.github/workflows/release-gem.yml +2 -49
  22. data/.github/workflows/tag.yml +5 -28
  23. data/.github/workflows/test.yml +1 -37
  24. data/ChangeLog.md +21 -0
  25. data/Gemfile.lock +13 -8
  26. data/Rakefile +1 -1
  27. data/VERSION +1 -1
  28. data/beeps.gemspec +3 -3
  29. data/ext/beeps/analyser.cpp +1 -1
  30. data/ext/beeps/envelope.cpp +1 -1
  31. data/ext/beeps/file_in.cpp +1 -1
  32. data/ext/beeps/gain.cpp +1 -1
  33. data/ext/beeps/high_pass.cpp +1 -1
  34. data/ext/beeps/low_pass.cpp +1 -1
  35. data/ext/beeps/mic_in.cpp +1 -1
  36. data/ext/beeps/mixer.cpp +1 -1
  37. data/ext/beeps/oscillator.cpp +2 -2
  38. data/ext/beeps/pitch_shift.cpp +1 -1
  39. data/ext/beeps/processor.cpp +1 -1
  40. data/ext/beeps/reverb.cpp +1 -1
  41. data/ext/beeps/sequencer.cpp +1 -1
  42. data/ext/beeps/signals.cpp +1 -1
  43. data/ext/beeps/sound.cpp +6 -6
  44. data/ext/beeps/sound_player.cpp +5 -5
  45. data/ext/beeps/text_in.cpp +1 -1
  46. data/ext/beeps/time_stretch.cpp +1 -1
  47. data/ext/beeps/value.cpp +1 -1
  48. data/include/beeps/signals.h +2 -2
  49. data/include/beeps/sound.h +3 -3
  50. data/lib/beeps/beeps.rb +4 -4
  51. data/lib/beeps/sound.rb +1 -1
  52. data/src/mic_in.cpp +10 -9
  53. data/src/openal.cpp +66 -8
  54. data/src/openal.h +5 -1
  55. data/src/oscillator.cpp +1 -1
  56. data/src/signals.cpp +6 -6
  57. data/src/sound.cpp +347 -152
  58. data/src/win32/beeps.cpp +25 -2
  59. data/src/win32/signals.cpp +102 -21
  60. data/test/test_file_in.rb +38 -0
  61. data/test/test_sound.rb +6 -6
  62. data/test/test_sound_player.rb +86 -20
  63. metadata +7 -8
  64. data/.github/workflows/utils.rb +0 -127
data/ext/beeps/sound.cpp CHANGED
@@ -8,7 +8,7 @@ RUCY_DEFINE_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Sound)
8
8
 
9
9
  #define THIS to<Beeps::Sound*>(self)
10
10
 
11
- #define CHECK RUCY_CHECK_OBJ(Beeps::Sound, self)
11
+ #define CHECK RUCY_CHECK_PTR(Beeps::Sound, self)
12
12
 
13
13
 
14
14
  static
@@ -48,20 +48,20 @@ RUCY_DEF0(play)
48
48
  RUCY_END
49
49
 
50
50
  static
51
- RUCY_DEF0(get_sample_rate)
51
+ RUCY_DEF0(get_nchannels)
52
52
  {
53
53
  CHECK;
54
54
 
55
- return value(THIS->sample_rate());
55
+ return value(THIS->nchannels());
56
56
  }
57
57
  RUCY_END
58
58
 
59
59
  static
60
- RUCY_DEF0(get_nchannels)
60
+ RUCY_DEF0(get_sample_rate)
61
61
  {
62
62
  CHECK;
63
63
 
64
- return value(THIS->nchannels());
64
+ return value(THIS->sample_rate());
65
65
  }
66
66
  RUCY_END
67
67
 
@@ -142,8 +142,8 @@ Init_beeps_sound ()
142
142
  cSound.define_private_method("initialize!", initialize);
143
143
  cSound.define_private_method("initialize_copy", initialize_copy);
144
144
  cSound.define_private_method("play!", play);
145
- cSound.define_method("sample_rate", get_sample_rate);
146
145
  cSound.define_method("nchannels", get_nchannels);
146
+ cSound.define_method("sample_rate", get_sample_rate);
147
147
  cSound.define_method("seconds", get_seconds);
148
148
  cSound.define_method("gain=", set_gain);
149
149
  cSound.define_method("gain", get_gain);
@@ -9,7 +9,7 @@ RUCY_DEFINE_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::SoundPlayer)
9
9
 
10
10
  #define THIS to<Beeps::SoundPlayer*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::SoundPlayer, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::SoundPlayer, self)
13
13
 
14
14
 
15
15
  static
@@ -205,10 +205,10 @@ Init_beeps_sound_player ()
205
205
  cSoundPlayer.define_method("loop", get_loop);
206
206
  cSoundPlayer.define_singleton_method("stop_all", stop_all);
207
207
 
208
- cSoundPlayer.define_const("STATE_UNKNOWN", Beeps::SoundPlayer::STATE_UNKNOWN);
209
- cSoundPlayer.define_const("PLAYING", Beeps::SoundPlayer::PLAYING);
210
- cSoundPlayer.define_const("PAUSED", Beeps::SoundPlayer::PAUSED);
211
- cSoundPlayer.define_const("STOPPED", Beeps::SoundPlayer::STOPPED);
208
+ cSoundPlayer.define_const("STATE_NONE", Beeps::SoundPlayer::STATE_NONE);
209
+ cSoundPlayer.define_const("PLAYING", Beeps::SoundPlayer::PLAYING);
210
+ cSoundPlayer.define_const("PAUSED", Beeps::SoundPlayer::PAUSED);
211
+ cSoundPlayer.define_const("STOPPED", Beeps::SoundPlayer::STOPPED);
212
212
  }
213
213
 
214
214
 
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::TextIn)
9
9
 
10
10
  #define THIS to<Beeps::TextIn*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::TextIn, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::TextIn, self)
13
13
 
14
14
 
15
15
  static
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::TimeStretch)
9
9
 
10
10
  #define THIS to<Beeps::TimeStretch*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::TimeStretch, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::TimeStretch, self)
13
13
 
14
14
 
15
15
  static
data/ext/beeps/value.cpp CHANGED
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Value)
9
9
 
10
10
  #define THIS to<Beeps::Value*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::Value, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::Value, self)
13
13
 
14
14
 
15
15
  static
@@ -37,10 +37,10 @@ namespace Beeps
37
37
 
38
38
  uint append (const Signals& source, uint source_offset = 0);
39
39
 
40
- double sample_rate () const;
41
-
42
40
  uint nchannels () const;
43
41
 
42
+ double sample_rate () const;
43
+
44
44
  uint nsamples () const;
45
45
 
46
46
  uint capacity () const;
@@ -23,7 +23,7 @@ namespace Beeps
23
23
  enum State
24
24
  {
25
25
 
26
- STATE_UNKNOWN = 0,
26
+ STATE_NONE = 0,
27
27
 
28
28
  PLAYING,
29
29
 
@@ -95,10 +95,10 @@ namespace Beeps
95
95
 
96
96
  SoundPlayer play ();
97
97
 
98
- double sample_rate () const;
99
-
100
98
  uint nchannels () const;
101
99
 
100
+ double sample_rate () const;
101
+
102
102
  float seconds () const;
103
103
 
104
104
  void set_gain (float gain);
data/lib/beeps/beeps.rb CHANGED
@@ -38,10 +38,10 @@ module Beeps
38
38
 
39
39
  private
40
40
 
41
- def beep_sound(time)
42
- @beep_processor ||= Oscillator.new(:square)
43
- Sound.new @beep_processor, time
44
- end
41
+ def beep_sound(time)
42
+ @beep_processor ||= Oscillator.new(:square)
43
+ Sound.new @beep_processor, time
44
+ end
45
45
 
46
46
  self
47
47
 
data/lib/beeps/sound.rb CHANGED
@@ -37,7 +37,7 @@ module Beeps
37
37
  include Xot::Setter
38
38
 
39
39
  const_symbol_reader :state, **{
40
- unknown: STATE_UNKNOWN,
40
+ none: STATE_NONE,
41
41
  playing: PLAYING,
42
42
  paused: PAUSED,
43
43
  stopped: STOPPED
data/src/mic_in.cpp CHANGED
@@ -6,6 +6,7 @@
6
6
  #include <vector>
7
7
  #include <memory>
8
8
  #include <algorithm>
9
+ #include <xot/util.h>
9
10
  #include "beeps/beeps.h"
10
11
  #include "beeps/exception.h"
11
12
  #include "openal.h"
@@ -28,7 +29,7 @@ namespace Beeps
28
29
  invalid_state_error(__FILE__, __LINE__);
29
30
 
30
31
  alcCaptureStart(self->device);
31
- OpenAL_check_error(__FILE__, __LINE__);
32
+ OpenAL_check_error(self->device, __FILE__, __LINE__);
32
33
 
33
34
  self->started = true;
34
35
  }
@@ -41,7 +42,7 @@ namespace Beeps
41
42
  invalid_state_error(__FILE__, __LINE__);
42
43
 
43
44
  alcCaptureStop(self->device);
44
- OpenAL_check_error(__FILE__, __LINE__);
45
+ OpenAL_check_error(self->device, __FILE__, __LINE__);
45
46
 
46
47
  self->started = false;
47
48
  }
@@ -59,18 +60,18 @@ namespace Beeps
59
60
  ALint nsamples = 0;
60
61
  alcGetIntegerv(
61
62
  self->device, ALC_CAPTURE_SAMPLES, sizeof(nsamples), &nsamples);
62
- OpenAL_check_error(__FILE__, __LINE__);
63
+ OpenAL_check_error(self->device, __FILE__, __LINE__);
63
64
  if (nsamples <= 0) return;
64
65
 
65
66
  auto& buffer = self->buffer;
66
67
  if (buffer.size() < (size_t) nsamples) buffer.resize(nsamples);
67
68
 
68
- alcCaptureSamples(self->device, (ALCvoid*) &buffer[0], nsamples);
69
- OpenAL_check_error(__FILE__, __LINE__);
69
+ alcCaptureSamples(self->device, (ALCvoid*) buffer.data(), nsamples);
70
+ OpenAL_check_error(self->device, __FILE__, __LINE__);
70
71
 
71
72
  auto& samples = self->samples;
72
73
  samples.reserve(samples.size() + nsamples);
73
- samples.insert(samples.end(), &buffer[0], &buffer[0] + nsamples);
74
+ samples.insert(samples.end(), buffer.data(), buffer.data() + nsamples);
74
75
 
75
76
  if (samples.size() > samples_size_max())
76
77
  {
@@ -114,7 +115,7 @@ namespace Beeps
114
115
 
115
116
  bool is_valid () const
116
117
  {
117
- return self->sample_rate > 0 && self->nchannels > 0 && self->device;
118
+ return self->nchannels > 0 && self->sample_rate > 0 && self->device;
118
119
  }
119
120
 
120
121
  struct Data
@@ -134,12 +135,12 @@ namespace Beeps
134
135
 
135
136
  ~Data ()
136
137
  {
137
- clear();
138
+ Xot::call_and_log_errors([&]() {clear();});
138
139
  }
139
140
 
140
141
  void create ()
141
142
  {
142
- assert(sample_rate > 0 && nchannels > 0);
143
+ assert(nchannels > 0 && sample_rate > 0);
143
144
 
144
145
  if (device) return;
145
146
 
data/src/openal.cpp CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
 
4
4
  #include <assert.h>
5
+ #include <algorithm>
5
6
  #include "beeps/exception.h"
6
7
  #include "beeps/debug.h"
7
8
  #include "sound.h"
@@ -14,9 +15,11 @@ namespace Beeps
14
15
  namespace global
15
16
  {
16
17
 
17
- static ALCdevice* device = NULL;
18
+ static ALCdevice* device = NULL;
18
19
 
19
- static ALCcontext* context = NULL;
20
+ static ALCcontext* context = NULL;
21
+
22
+ static uint max_playing_sources = 0;
20
23
 
21
24
  }// global
22
25
 
@@ -39,6 +42,21 @@ namespace Beeps
39
42
  }
40
43
  }
41
44
 
45
+ static uint
46
+ get_max_playing_sources ()
47
+ {
48
+ #if defined(OSX) || defined(IOS)
49
+ typedef ALint (*GetMaxBusses) ();
50
+
51
+ auto get_max_busses =
52
+ (GetMaxBusses) alcGetProcAddress(NULL, "alcMacOSXGetMixerMaxiumumBusses");
53
+ if (get_max_busses)
54
+ return (uint) std::max(get_max_busses(), 0);
55
+ #endif
56
+
57
+ return 0;
58
+ }
59
+
42
60
  void
43
61
  OpenAL_init ()
44
62
  {
@@ -56,6 +74,7 @@ namespace Beeps
56
74
  if (!alcMakeContextCurrent(global::context))
57
75
  goto FAILED;
58
76
 
77
+ global::max_playing_sources = get_max_playing_sources();
59
78
  return;
60
79
 
61
80
  FAILED:
@@ -78,22 +97,43 @@ namespace Beeps
78
97
  return global::context;
79
98
  }
80
99
 
81
- ALCenum
100
+ uint
101
+ OpenAL_get_max_playing_sources ()
102
+ {
103
+ return global::max_playing_sources;
104
+ }
105
+
106
+ ALenum
82
107
  OpenAL_get_error ()
83
108
  {
84
- assert(global::device);
109
+ assert(global::context);
85
110
 
86
- return alcGetError(global::device);
111
+ return alGetError();
87
112
  }
88
113
 
89
114
  bool
90
115
  OpenAL_no_error ()
91
116
  {
92
- return OpenAL_get_error() == ALC_NO_ERROR;
117
+ return OpenAL_get_error() == AL_NO_ERROR;
93
118
  }
94
119
 
95
120
  static String
96
121
  get_error_name (ALenum error)
122
+ {
123
+ switch (error)
124
+ {
125
+ case AL_NO_ERROR: return "AL_NO_ERROR";
126
+ case AL_INVALID_NAME: return "AL_INVALID_NAME";
127
+ case AL_INVALID_ENUM: return "AL_INVALID_ENUM";
128
+ case AL_INVALID_VALUE: return "AL_INVALID_VALUE";
129
+ case AL_INVALID_OPERATION: return "AL_INVALID_OPERATION";
130
+ case AL_OUT_OF_MEMORY: return "AL_OUT_OF_MEMORY";
131
+ default: return "UNKNOWN ERROR";
132
+ }
133
+ }
134
+
135
+ static String
136
+ get_device_error_name (ALCenum error)
97
137
  {
98
138
  switch (error)
99
139
  {
@@ -110,9 +150,27 @@ namespace Beeps
110
150
  void
111
151
  OpenAL_check_error (const char* file, int line)
112
152
  {
113
- ALCenum e = OpenAL_get_error();
153
+ ALenum e = OpenAL_get_error();
154
+ if (e != AL_NO_ERROR)
155
+ {
156
+ openal_error(
157
+ file, line, "OpenAL error %s (0x%x)",
158
+ get_error_name(e).c_str(), (uint) e);
159
+ }
160
+ }
161
+
162
+ void
163
+ OpenAL_check_error (ALCdevice* device, const char* file, int line)
164
+ {
165
+ assert(device);
166
+
167
+ ALCenum e = alcGetError(device);
114
168
  if (e != ALC_NO_ERROR)
115
- openal_error(file, line, "OpenAL error %s", get_error_name(e).c_str());
169
+ {
170
+ openal_error(
171
+ file, line, "OpenAL error %s (0x%x)",
172
+ get_device_error_name(e).c_str(), (uint) e);
173
+ }
116
174
  }
117
175
 
118
176
 
data/src/openal.h CHANGED
@@ -25,12 +25,16 @@ namespace Beeps
25
25
 
26
26
  void* OpenAL_get_context ();
27
27
 
28
- ALCenum OpenAL_get_error();
28
+ uint OpenAL_get_max_playing_sources ();
29
+
30
+ ALenum OpenAL_get_error();
29
31
 
30
32
  bool OpenAL_no_error();
31
33
 
32
34
  void OpenAL_check_error(const char* file, int line);
33
35
 
36
+ void OpenAL_check_error(ALCdevice* device, const char* file, int line);
37
+
34
38
 
35
39
  }// Beeps
36
40
 
data/src/oscillator.cpp CHANGED
@@ -289,7 +289,7 @@ namespace Beeps
289
289
  for (size_t i = 0; i < size; ++i)
290
290
  samples[i] = fun(i / (float) size);
291
291
 
292
- return new WaveformOsc(&samples[0], samples.size());
292
+ return new WaveformOsc(samples.data(), samples.size());
293
293
  }
294
294
 
295
295
  static void
data/src/signals.cpp CHANGED
@@ -623,18 +623,18 @@ namespace Beeps
623
623
  return t;
624
624
  }
625
625
 
626
- double
627
- Signals::sample_rate () const
628
- {
629
- return self->frames ? self->frames->dataRate() : Beeps::sample_rate();
630
- }
631
-
632
626
  uint
633
627
  Signals::nchannels () const
634
628
  {
635
629
  return self->frames ? self->frames->channels() : 0;
636
630
  }
637
631
 
632
+ double
633
+ Signals::sample_rate () const
634
+ {
635
+ return self->frames ? self->frames->dataRate() : Beeps::sample_rate();
636
+ }
637
+
638
638
  uint
639
639
  Signals::nsamples () const
640
640
  {