native_audio 0.5.0 → 0.5.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9a953a3fe6e4bd23e99278c28dbd273bc08268105382a4dae34854e3917aa64
4
- data.tar.gz: af2a5c84a91fa2957984d4c36637bbe914f38fab7d26903406051eb2456dbc96
3
+ metadata.gz: 8d7a019f96cab6e7939d9c7cd4ab6c238712dd7e973b9a5ded1ad565a6156af7
4
+ data.tar.gz: 6e5c823010843c54a0225433a1cd59e7980739e16ff5d607e23395da04316941
5
5
  SHA512:
6
- metadata.gz: '094beb2919f1a5e0b9e18ea7ac5e5776f5f5ed5eb213f9aac5c976ec3e74cb740ba73632f3bab2acb589afc4d2f12a1fe8485b3ddd59b5bc71d8d21fa758f357'
7
- data.tar.gz: b0c335b765410df6cfbae2a730f921388e5761639f96b329113ef398527dd46f9067680a55e0fb7541cf801784158f07b744f07e9570251ea0485503b573c81f
6
+ metadata.gz: d9b89059a4f4668c9a230f3cf543f281fa2930fee6773ab09790995deb22b454125ba50e81fec46edea5c19e61571b46f5589ffd45730e3ad0ecf12e092ff7aa
7
+ data.tar.gz: b2819672ad24fc89fccef79131eaee9711148d5b0ce608a681671d872706ef144d51053d04059e7fe523e5fdb3e0fc93815527e574161da8f8fd78c3bed3d893
data/ext/audio/audio.c CHANGED
@@ -21,6 +21,7 @@ ma_sound *sounds[MAX_SOUNDS];
21
21
  ma_sound *channels[MAX_CHANNELS];
22
22
  multi_tap_delay_node *delay_nodes[MAX_CHANNELS];
23
23
  reverb_node *reverb_nodes[MAX_CHANNELS];
24
+ ma_uint64 drain_until_frame[MAX_CHANNELS];
24
25
  int sound_count = 0;
25
26
  int engine_initialized = 0;
26
27
  int context_initialized = 0;
@@ -180,6 +181,40 @@ VALUE audio_duration(VALUE self, VALUE clip)
180
181
  // Playback Controls
181
182
  // ============================================================================
182
183
 
184
+ static void cleanup_finished_channels(void)
185
+ {
186
+ ma_uint64 now = ma_engine_get_time_in_pcm_frames(&engine);
187
+ ma_uint32 sample_rate = ma_engine_get_sample_rate(&engine);
188
+ ma_uint64 drain_frames = (ma_uint64)(REVERB_DRAIN_SECONDS * sample_rate);
189
+
190
+ for (int i = 0; i < MAX_CHANNELS; i++) {
191
+ // Phase 1: sound finished - uninit the sound, start drain timer
192
+ if (channels[i] != NULL && ma_sound_at_end(channels[i])) {
193
+ ma_sound_uninit(channels[i]);
194
+ free(channels[i]);
195
+ channels[i] = NULL;
196
+ drain_until_frame[i] = now + drain_frames;
197
+ }
198
+
199
+ // Phase 2: drain timer expired - uninit delay and reverb nodes
200
+ if (drain_until_frame[i] != 0 && now >= drain_until_frame[i]) {
201
+ if (delay_nodes[i] != NULL) {
202
+ multi_tap_delay_uninit(delay_nodes[i]);
203
+ free(delay_nodes[i]);
204
+ delay_nodes[i] = NULL;
205
+ }
206
+
207
+ if (reverb_nodes[i] != NULL) {
208
+ reverb_uninit(reverb_nodes[i]);
209
+ free(reverb_nodes[i]);
210
+ reverb_nodes[i] = NULL;
211
+ }
212
+
213
+ drain_until_frame[i] = 0;
214
+ }
215
+ }
216
+ }
217
+
183
218
  VALUE audio_play(VALUE self, VALUE channel_id, VALUE clip)
184
219
  {
185
220
  int channel = NUM2INT(channel_id);
@@ -195,6 +230,8 @@ VALUE audio_play(VALUE self, VALUE channel_id, VALUE clip)
195
230
  return Qnil;
196
231
  }
197
232
 
233
+ cleanup_finished_channels();
234
+
198
235
  // Clean up existing resources on this channel
199
236
  if (channels[channel] != NULL) {
200
237
  ma_sound_stop(channels[channel]);
@@ -295,7 +332,21 @@ VALUE audio_stop(VALUE self, VALUE channel_id)
295
332
  }
296
333
 
297
334
  ma_sound_stop(channels[channel]);
298
- ma_sound_seek_to_pcm_frame(channels[channel], 0);
335
+ ma_sound_uninit(channels[channel]);
336
+ free(channels[channel]);
337
+ channels[channel] = NULL;
338
+
339
+ if (delay_nodes[channel] != NULL) {
340
+ multi_tap_delay_uninit(delay_nodes[channel]);
341
+ free(delay_nodes[channel]);
342
+ delay_nodes[channel] = NULL;
343
+ }
344
+
345
+ if (reverb_nodes[channel] != NULL) {
346
+ reverb_uninit(reverb_nodes[channel]);
347
+ free(reverb_nodes[channel]);
348
+ reverb_nodes[channel] = NULL;
349
+ }
299
350
 
300
351
  return Qnil;
301
352
  }
@@ -540,6 +591,7 @@ void Init_audio(void)
540
591
  channels[i] = NULL;
541
592
  delay_nodes[i] = NULL;
542
593
  reverb_nodes[i] = NULL;
594
+ drain_until_frame[i] = 0;
543
595
  }
544
596
 
545
597
  VALUE mAudio = rb_define_module("Audio");
data/ext/audio/audio.h CHANGED
@@ -15,6 +15,7 @@
15
15
 
16
16
  #define MAX_SOUNDS 1024
17
17
  #define MAX_CHANNELS 1024
18
+ #define REVERB_DRAIN_SECONDS 3.0f
18
19
 
19
20
  // ============================================================================
20
21
  // Globals (defined in audio.c)
@@ -26,6 +27,7 @@ extern ma_sound *sounds[MAX_SOUNDS];
26
27
  extern ma_sound *channels[MAX_CHANNELS];
27
28
  extern multi_tap_delay_node *delay_nodes[MAX_CHANNELS];
28
29
  extern reverb_node *reverb_nodes[MAX_CHANNELS];
30
+ extern ma_uint64 drain_until_frame[MAX_CHANNELS];
29
31
  extern int sound_count;
30
32
  extern int engine_initialized;
31
33
  extern int context_initialized;
data/lib/native_audio.rb CHANGED
@@ -25,6 +25,7 @@ module NativeAudio
25
25
 
26
26
  class DelayTap
27
27
  attr_reader :id, :audio_source, :time_ms, :volume
28
+ attr_writer :id
28
29
 
29
30
  def initialize(audio_source, id, time_ms, volume)
30
31
  @audio_source = audio_source
@@ -56,11 +57,13 @@ module NativeAudio
56
57
  @clip = clip
57
58
  @channel = AudioSource.channels.count
58
59
  @delay_taps = []
60
+ @params = {}
59
61
  AudioSource.channels << self
60
62
  end
61
63
 
62
64
  def play
63
65
  NativeAudio.audio_driver.play(@channel, @clip.clip)
66
+ apply_params
64
67
  end
65
68
 
66
69
  def stop
@@ -76,18 +79,22 @@ module NativeAudio
76
79
  end
77
80
 
78
81
  def set_pos(angle, distance)
82
+ @params[:pos] = [angle, distance]
79
83
  NativeAudio.audio_driver.set_pos(@channel, angle, distance)
80
84
  end
81
85
 
82
86
  def set_volume(volume)
87
+ @params[:volume] = volume
83
88
  NativeAudio.audio_driver.set_volume(@channel, volume)
84
89
  end
85
90
 
86
91
  def set_pitch(pitch)
92
+ @params[:pitch] = pitch
87
93
  NativeAudio.audio_driver.set_pitch(@channel, pitch)
88
94
  end
89
95
 
90
96
  def set_looping(looping)
97
+ @params[:looping] = looping
91
98
  NativeAudio.audio_driver.set_looping(@channel, looping)
92
99
  end
93
100
 
@@ -99,10 +106,12 @@ module NativeAudio
99
106
  end
100
107
 
101
108
  def enable_reverb(enabled = true)
109
+ @params[:reverb_enabled] = enabled
102
110
  NativeAudio.audio_driver.enable_reverb(@channel, enabled)
103
111
  end
104
112
 
105
113
  def set_reverb(room_size: 0.5, damping: 0.3, wet: 0.3, dry: 1.0)
114
+ @params[:reverb] = { room_size: room_size, damping: damping, wet: wet, dry: dry }
106
115
  NativeAudio.audio_driver.enable_reverb(@channel, true)
107
116
  NativeAudio.audio_driver.set_reverb_room_size(@channel, room_size)
108
117
  NativeAudio.audio_driver.set_reverb_damping(@channel, damping)
@@ -117,5 +126,29 @@ module NativeAudio
117
126
  def self.channels
118
127
  @channels ||= []
119
128
  end
129
+
130
+ private
131
+
132
+ def apply_params
133
+ NativeAudio.audio_driver.set_volume(@channel, @params[:volume]) if @params.key?(:volume)
134
+ NativeAudio.audio_driver.set_pitch(@channel, @params[:pitch]) if @params.key?(:pitch)
135
+ NativeAudio.audio_driver.set_looping(@channel, @params[:looping]) if @params.key?(:looping)
136
+ NativeAudio.audio_driver.set_pos(@channel, *@params[:pos]) if @params.key?(:pos)
137
+
138
+ if @params.key?(:reverb)
139
+ r = @params[:reverb]
140
+ NativeAudio.audio_driver.enable_reverb(@channel, true)
141
+ NativeAudio.audio_driver.set_reverb_room_size(@channel, r[:room_size])
142
+ NativeAudio.audio_driver.set_reverb_damping(@channel, r[:damping])
143
+ NativeAudio.audio_driver.set_reverb_wet(@channel, r[:wet])
144
+ NativeAudio.audio_driver.set_reverb_dry(@channel, r[:dry])
145
+ elsif @params.key?(:reverb_enabled)
146
+ NativeAudio.audio_driver.enable_reverb(@channel, @params[:reverb_enabled])
147
+ end
148
+
149
+ @delay_taps.each do |tap|
150
+ tap.id = NativeAudio.audio_driver.add_delay_tap(@channel, tap.time_ms, tap.volume)
151
+ end
152
+ end
120
153
  end
121
154
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: native_audio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Hatfull