beeps 0.3.16 → 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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/beeps/analyser.cpp +4 -4
  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 +2 -2
  10. data/.doc/ext/beeps/oscillator.cpp +3 -3
  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 +2 -2
  15. data/.doc/ext/beeps/signals.cpp +3 -3
  16. data/.doc/ext/beeps/sound.cpp +16 -8
  17. data/.doc/ext/beeps/sound_player.cpp +13 -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 +2 -2
  21. data/.github/workflows/release-gem.yml +2 -40
  22. data/.github/workflows/tag.yml +5 -28
  23. data/.github/workflows/test.yml +1 -28
  24. data/ChangeLog.md +28 -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 +4 -4
  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 +2 -2
  37. data/ext/beeps/oscillator.cpp +3 -3
  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 +2 -2
  42. data/ext/beeps/signals.cpp +3 -3
  43. data/ext/beeps/sound.cpp +17 -8
  44. data/ext/beeps/sound_player.cpp +14 -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 +2 -2
  48. data/include/beeps/defs.h +14 -4
  49. data/include/beeps/signals.h +2 -2
  50. data/include/beeps/sound.h +9 -3
  51. data/lib/beeps/beeps.rb +4 -4
  52. data/lib/beeps/extension.rb +1 -1
  53. data/lib/beeps/sound.rb +2 -2
  54. data/src/file_in.cpp +2 -0
  55. data/src/mic_in.cpp +10 -9
  56. data/src/openal.cpp +66 -8
  57. data/src/openal.h +5 -1
  58. data/src/oscillator.cpp +1 -1
  59. data/src/signals.cpp +6 -6
  60. data/src/sound.cpp +382 -160
  61. data/src/win32/beeps.cpp +25 -2
  62. data/src/win32/signals.cpp +103 -29
  63. data/test/test_file_in.rb +38 -0
  64. data/test/test_sound.rb +6 -6
  65. data/test/test_sound_player.rb +86 -20
  66. metadata +7 -8
  67. data/.github/workflows/utils.rb +0 -127
data/ext/beeps/gain.cpp CHANGED
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Gain)
9
9
 
10
10
  #define THIS to<Beeps::Gain*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::Gain, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::Gain, self)
13
13
 
14
14
 
15
15
  static
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::HighPass)
9
9
 
10
10
  #define THIS to<Beeps::HighPass*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::HighPass, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::HighPass, self)
13
13
 
14
14
 
15
15
  static
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::LowPass)
9
9
 
10
10
  #define THIS to<Beeps::LowPass*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::LowPass, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::LowPass, self)
13
13
 
14
14
 
15
15
  static
data/ext/beeps/mic_in.cpp CHANGED
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::MicIn)
9
9
 
10
10
  #define THIS to<Beeps::MicIn*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::MicIn, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::MicIn, self)
13
13
 
14
14
 
15
15
  static
data/ext/beeps/mixer.cpp CHANGED
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Mixer)
9
9
 
10
10
  #define THIS to<Beeps::Mixer*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::Mixer, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::Mixer, self)
13
13
 
14
14
 
15
15
  static
@@ -54,7 +54,7 @@ RUCY_DEF0(each_input)
54
54
 
55
55
  Value ret;
56
56
  for (auto& input : *THIS)
57
- ret = rb_yield(value(input.get()));
57
+ ret = yield(value(input.get()));
58
58
  return ret;
59
59
  }
60
60
  RUCY_END
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Oscillator)
9
9
 
10
10
  #define THIS to<Beeps::Oscillator*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::Oscillator, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::Oscillator, self)
13
13
 
14
14
 
15
15
  static
@@ -51,7 +51,7 @@ RUCY_DEF1(set_samples, samples)
51
51
  for (size_t i = 0; i < size; ++i)
52
52
  data.push_back(to<Beeps::Sample>(array[i]));
53
53
 
54
- THIS->set_samples(&data[0], data.size());
54
+ THIS->set_samples(data.data(), data.size());
55
55
  }
56
56
  RUCY_END
57
57
 
@@ -66,7 +66,7 @@ RUCY_DEF0(each_sample)
66
66
 
67
67
  Value ret;
68
68
  for (size_t i = 0; i < size; ++i)
69
- ret = rb_yield(value((float) samples[i]));
69
+ ret = yield(value((float) samples[i]));
70
70
  return ret;
71
71
  }
72
72
  RUCY_END
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::PitchShift)
9
9
 
10
10
  #define THIS to<Beeps::PitchShift*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::PitchShift, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::PitchShift, self)
13
13
 
14
14
 
15
15
  static
@@ -10,7 +10,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Processor)
10
10
 
11
11
  #define THIS to<Beeps::Processor*>(self)
12
12
 
13
- #define CHECK RUCY_CHECK_OBJ(Beeps::Processor, self)
13
+ #define CHECK RUCY_CHECK_PTR(Beeps::Processor, self)
14
14
 
15
15
  #define CALL(fun) RUCY_CALL_SUPER(THIS, fun)
16
16
 
data/ext/beeps/reverb.cpp CHANGED
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Reverb)
9
9
 
10
10
  #define THIS to<Beeps::Reverb*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::Reverb, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::Reverb, self)
13
13
 
14
14
 
15
15
  static
@@ -9,7 +9,7 @@ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Sequencer)
9
9
 
10
10
  #define THIS to<Beeps::Sequencer*>(self)
11
11
 
12
- #define CHECK RUCY_CHECK_OBJ(Beeps::Sequencer, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::Sequencer, self)
13
13
 
14
14
 
15
15
  static
@@ -69,7 +69,7 @@ RUCY_DEF0(each_note)
69
69
  Value ret;
70
70
  for (auto it = THIS->begin(), end = THIS->end(); it != end; ++it)
71
71
  {
72
- ret = rb_yield_values(3,
72
+ ret = yield(
73
73
  value(it->processor.get()),
74
74
  value(it->offset),
75
75
  value(it->duration));
@@ -8,7 +8,7 @@ RUCY_DEFINE_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::Signals)
8
8
 
9
9
  #define THIS to<Beeps::Signals*>(self)
10
10
 
11
- #define CHECK RUCY_CHECK_OBJ(Beeps::Signals, self)
11
+ #define CHECK RUCY_CHECK_PTR(Beeps::Signals, self)
12
12
 
13
13
 
14
14
  static
@@ -91,13 +91,13 @@ RUCY_DEF1(each, channel_)
91
91
 
92
92
  const auto* p = samples + channel;
93
93
  for (uint i = 0; i < nsamples; ++i, p += nchannels)
94
- rb_yield(value(*p));
94
+ yield(value(*p));
95
95
  }
96
96
  else
97
97
  {
98
98
  uint size = nsamples * nchannels;
99
99
  for (uint i = 0; i < size; ++i)
100
- rb_yield(value(samples[i]));
100
+ yield(value(samples[i]));
101
101
  }
102
102
  }
103
103
  RUCY_END
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
@@ -19,7 +19,7 @@ RUCY_DEF_ALLOC(alloc, klass)
19
19
  RUCY_END
20
20
 
21
21
  static
22
- RUCY_DEF4(setup, processor, seconds, nchannels, sample_rate)
22
+ RUCY_DEF4(initialize, processor, seconds, nchannels, sample_rate)
23
23
  {
24
24
  CHECK;
25
25
 
@@ -30,6 +30,14 @@ RUCY_DEF4(setup, processor, seconds, nchannels, sample_rate)
30
30
  }
31
31
  RUCY_END
32
32
 
33
+ static
34
+ RUCY_DEF1(initialize_copy, obj)
35
+ {
36
+ CHECK;
37
+ *THIS = to<Beeps::Sound&>(obj).dup();
38
+ }
39
+ RUCY_END
40
+
33
41
  static
34
42
  RUCY_DEF0(play)
35
43
  {
@@ -40,20 +48,20 @@ RUCY_DEF0(play)
40
48
  RUCY_END
41
49
 
42
50
  static
43
- RUCY_DEF0(get_sample_rate)
51
+ RUCY_DEF0(get_nchannels)
44
52
  {
45
53
  CHECK;
46
54
 
47
- return value(THIS->sample_rate());
55
+ return value(THIS->nchannels());
48
56
  }
49
57
  RUCY_END
50
58
 
51
59
  static
52
- RUCY_DEF0(get_nchannels)
60
+ RUCY_DEF0(get_sample_rate)
53
61
  {
54
62
  CHECK;
55
63
 
56
- return value(THIS->nchannels());
64
+ return value(THIS->sample_rate());
57
65
  }
58
66
  RUCY_END
59
67
 
@@ -131,10 +139,11 @@ Init_beeps_sound ()
131
139
 
132
140
  cSound = mBeeps.define_class("Sound");
133
141
  cSound.define_alloc_func(alloc);
134
- cSound.define_private_method("setup", setup);
142
+ cSound.define_private_method("initialize!", initialize);
143
+ cSound.define_private_method("initialize_copy", initialize_copy);
135
144
  cSound.define_private_method("play!", play);
136
- cSound.define_method("sample_rate", get_sample_rate);
137
145
  cSound.define_method("nchannels", get_nchannels);
146
+ cSound.define_method("sample_rate", get_sample_rate);
138
147
  cSound.define_method("seconds", get_seconds);
139
148
  cSound.define_method("gain=", set_gain);
140
149
  cSound.define_method("gain", get_gain);
@@ -1,6 +1,7 @@
1
1
  #include "beeps/ruby/sound.h"
2
2
 
3
3
 
4
+ #include "beeps/exception.h"
4
5
  #include "defs.h"
5
6
 
6
7
 
@@ -8,7 +9,7 @@ RUCY_DEFINE_VALUE_FROM_TO(BEEPS_EXPORT, Beeps::SoundPlayer)
8
9
 
9
10
  #define THIS to<Beeps::SoundPlayer*>(self)
10
11
 
11
- #define CHECK RUCY_CHECK_OBJ(Beeps::SoundPlayer, self)
12
+ #define CHECK RUCY_CHECK_PTR(Beeps::SoundPlayer, self)
12
13
 
13
14
 
14
15
  static
@@ -18,6 +19,13 @@ RUCY_DEF_ALLOC(alloc, klass)
18
19
  }
19
20
  RUCY_END
20
21
 
22
+ static
23
+ RUCY_DEF1(initialize_copy, obj)
24
+ {
25
+ Beeps::beeps_error(__FILE__, __LINE__, "can not duplicate SoundPlayer");
26
+ }
27
+ RUCY_END
28
+
21
29
  static
22
30
  RUCY_DEF0(play)
23
31
  {
@@ -179,6 +187,7 @@ Init_beeps_sound_player ()
179
187
 
180
188
  cSoundPlayer = mBeeps.define_class("SoundPlayer");
181
189
  cSoundPlayer.define_alloc_func(alloc);
190
+ cSoundPlayer.define_private_method("initialize_copy", initialize_copy);
182
191
  cSoundPlayer.define_method("play", play);
183
192
  cSoundPlayer.define_method("pause", pause);
184
193
  cSoundPlayer.define_method("rewind", rewind);
@@ -196,10 +205,10 @@ Init_beeps_sound_player ()
196
205
  cSoundPlayer.define_method("loop", get_loop);
197
206
  cSoundPlayer.define_singleton_method("stop_all", stop_all);
198
207
 
199
- cSoundPlayer.define_const("STATE_UNKNOWN", Beeps::SoundPlayer::STATE_UNKNOWN);
200
- cSoundPlayer.define_const("PLAYING", Beeps::SoundPlayer::PLAYING);
201
- cSoundPlayer.define_const("PAUSED", Beeps::SoundPlayer::PAUSED);
202
- 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);
203
212
  }
204
213
 
205
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
@@ -73,7 +73,7 @@ RUCY_DEF0(each_value)
73
73
 
74
74
  Value ret;
75
75
  for (auto it = THIS->begin(), end = THIS->end(); it != end; ++it)
76
- ret = rb_yield_values(2, value(it->value), value(it->time));
76
+ ret = yield(value(it->value), value(it->time));
77
77
  return ret;
78
78
  }
79
79
  RUCY_END
data/include/beeps/defs.h CHANGED
@@ -19,14 +19,24 @@ namespace Beeps
19
19
  {
20
20
 
21
21
 
22
- using namespace Xot::Types;
22
+ namespace Types
23
+ {
23
24
 
24
- using Xot::String;
25
25
 
26
- using Xot::StringList;
26
+ typedef double Sample;
27
+
28
+
29
+ }// Types
30
+
27
31
 
32
+ using namespace Xot ::Types;
28
33
 
29
- typedef double Sample;
34
+ using namespace Beeps::Types;
35
+
36
+
37
+ using Xot::String;
38
+
39
+ using Xot::StringList;
30
40
 
31
41
 
32
42
  }// Beeps
@@ -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
 
@@ -91,12 +91,14 @@ namespace Beeps
91
91
 
92
92
  ~Sound ();
93
93
 
94
- SoundPlayer play ();
94
+ Sound dup () const;
95
95
 
96
- double sample_rate () const;
96
+ SoundPlayer play ();
97
97
 
98
98
  uint nchannels () const;
99
99
 
100
+ double sample_rate () const;
101
+
100
102
  float seconds () const;
101
103
 
102
104
  void set_gain (float gain);
@@ -117,6 +119,10 @@ namespace Beeps
117
119
 
118
120
  Xot::PSharedImpl<Data> self;
119
121
 
122
+ private:
123
+
124
+ Sound (Data* data);
125
+
120
126
  };// Sound
121
127
 
122
128
 
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
 
@@ -6,7 +6,7 @@ module Beeps
6
6
  module_function
7
7
 
8
8
  def name(downcase = false)
9
- super().split('::')[-2].then {|s|
9
+ super().split('::')[..-2].join.then {|s|
10
10
  downcase ? s.gsub(/([a-z])([A-Z])/) {"#{$1}-#{$2}"}.downcase : s
11
11
  }
12
12
  end
data/lib/beeps/sound.rb CHANGED
@@ -15,7 +15,7 @@ module Beeps
15
15
  def initialize(
16
16
  processor, seconds = 0, nchannels: 1, sample_rate: 0, **options, &block)
17
17
 
18
- setup processor, seconds, nchannels, sample_rate
18
+ initialize! processor, seconds, nchannels, sample_rate
19
19
  set(**options) unless options.empty?
20
20
  Xot::BlockUtil.instance_eval_or_block_call self, &block if block
21
21
  end
@@ -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/file_in.cpp CHANGED
@@ -37,6 +37,8 @@ namespace Beeps
37
37
  void
38
38
  FileIn::set_path (const char* path)
39
39
  {
40
+ if (!path)
41
+ argument_error(__FILE__, __LINE__, "path is NULL");
40
42
  if (*this)
41
43
  invalid_state_error(__FILE__, __LINE__, "path is already set");
42
44
 
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