native_audio 0.3.0 → 0.5.0

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -0
  3. data/README.md +152 -0
  4. data/ext/audio/audio.c +541 -43
  5. data/ext/audio/audio.h +34 -0
  6. data/ext/audio/delay_node.c +185 -0
  7. data/ext/audio/delay_node.h +51 -0
  8. data/ext/audio/extconf.rb +12 -110
  9. data/ext/audio/miniaudio.h +95844 -0
  10. data/ext/audio/reverb_node.c +224 -0
  11. data/ext/audio/reverb_node.h +63 -0
  12. data/lib/dummy_audio.rb +94 -0
  13. data/lib/native_audio.rb +78 -7
  14. metadata +12 -132
  15. data/assets/include/SDL2/SDL.h +0 -233
  16. data/assets/include/SDL2/SDL_assert.h +0 -326
  17. data/assets/include/SDL2/SDL_atomic.h +0 -415
  18. data/assets/include/SDL2/SDL_audio.h +0 -1500
  19. data/assets/include/SDL2/SDL_bits.h +0 -126
  20. data/assets/include/SDL2/SDL_blendmode.h +0 -198
  21. data/assets/include/SDL2/SDL_clipboard.h +0 -141
  22. data/assets/include/SDL2/SDL_config.h +0 -61
  23. data/assets/include/SDL2/SDL_config_android.h +0 -194
  24. data/assets/include/SDL2/SDL_config_emscripten.h +0 -218
  25. data/assets/include/SDL2/SDL_config_iphoneos.h +0 -217
  26. data/assets/include/SDL2/SDL_config_macosx.h +0 -277
  27. data/assets/include/SDL2/SDL_config_minimal.h +0 -95
  28. data/assets/include/SDL2/SDL_config_ngage.h +0 -89
  29. data/assets/include/SDL2/SDL_config_os2.h +0 -207
  30. data/assets/include/SDL2/SDL_config_pandora.h +0 -141
  31. data/assets/include/SDL2/SDL_config_windows.h +0 -331
  32. data/assets/include/SDL2/SDL_config_wingdk.h +0 -253
  33. data/assets/include/SDL2/SDL_config_winrt.h +0 -220
  34. data/assets/include/SDL2/SDL_config_xbox.h +0 -235
  35. data/assets/include/SDL2/SDL_copying.h +0 -20
  36. data/assets/include/SDL2/SDL_cpuinfo.h +0 -594
  37. data/assets/include/SDL2/SDL_egl.h +0 -2352
  38. data/assets/include/SDL2/SDL_endian.h +0 -348
  39. data/assets/include/SDL2/SDL_error.h +0 -163
  40. data/assets/include/SDL2/SDL_events.h +0 -1166
  41. data/assets/include/SDL2/SDL_filesystem.h +0 -149
  42. data/assets/include/SDL2/SDL_gamecontroller.h +0 -1074
  43. data/assets/include/SDL2/SDL_gesture.h +0 -117
  44. data/assets/include/SDL2/SDL_guid.h +0 -100
  45. data/assets/include/SDL2/SDL_haptic.h +0 -1341
  46. data/assets/include/SDL2/SDL_hidapi.h +0 -451
  47. data/assets/include/SDL2/SDL_hints.h +0 -2569
  48. data/assets/include/SDL2/SDL_image.h +0 -2173
  49. data/assets/include/SDL2/SDL_joystick.h +0 -1066
  50. data/assets/include/SDL2/SDL_keyboard.h +0 -353
  51. data/assets/include/SDL2/SDL_keycode.h +0 -358
  52. data/assets/include/SDL2/SDL_loadso.h +0 -115
  53. data/assets/include/SDL2/SDL_locale.h +0 -103
  54. data/assets/include/SDL2/SDL_log.h +0 -404
  55. data/assets/include/SDL2/SDL_main.h +0 -275
  56. data/assets/include/SDL2/SDL_messagebox.h +0 -193
  57. data/assets/include/SDL2/SDL_metal.h +0 -113
  58. data/assets/include/SDL2/SDL_misc.h +0 -79
  59. data/assets/include/SDL2/SDL_mixer.h +0 -2784
  60. data/assets/include/SDL2/SDL_mouse.h +0 -465
  61. data/assets/include/SDL2/SDL_mutex.h +0 -471
  62. data/assets/include/SDL2/SDL_name.h +0 -33
  63. data/assets/include/SDL2/SDL_opengl.h +0 -2132
  64. data/assets/include/SDL2/SDL_opengl_glext.h +0 -13209
  65. data/assets/include/SDL2/SDL_opengles.h +0 -39
  66. data/assets/include/SDL2/SDL_opengles2.h +0 -52
  67. data/assets/include/SDL2/SDL_opengles2_gl2.h +0 -656
  68. data/assets/include/SDL2/SDL_opengles2_gl2ext.h +0 -4033
  69. data/assets/include/SDL2/SDL_opengles2_gl2platform.h +0 -27
  70. data/assets/include/SDL2/SDL_opengles2_khrplatform.h +0 -311
  71. data/assets/include/SDL2/SDL_pixels.h +0 -644
  72. data/assets/include/SDL2/SDL_platform.h +0 -261
  73. data/assets/include/SDL2/SDL_power.h +0 -88
  74. data/assets/include/SDL2/SDL_quit.h +0 -58
  75. data/assets/include/SDL2/SDL_rect.h +0 -376
  76. data/assets/include/SDL2/SDL_render.h +0 -1919
  77. data/assets/include/SDL2/SDL_revision.h +0 -6
  78. data/assets/include/SDL2/SDL_rwops.h +0 -841
  79. data/assets/include/SDL2/SDL_scancode.h +0 -438
  80. data/assets/include/SDL2/SDL_sensor.h +0 -322
  81. data/assets/include/SDL2/SDL_shape.h +0 -155
  82. data/assets/include/SDL2/SDL_stdinc.h +0 -830
  83. data/assets/include/SDL2/SDL_surface.h +0 -997
  84. data/assets/include/SDL2/SDL_system.h +0 -623
  85. data/assets/include/SDL2/SDL_syswm.h +0 -386
  86. data/assets/include/SDL2/SDL_test.h +0 -69
  87. data/assets/include/SDL2/SDL_test_assert.h +0 -105
  88. data/assets/include/SDL2/SDL_test_common.h +0 -236
  89. data/assets/include/SDL2/SDL_test_compare.h +0 -69
  90. data/assets/include/SDL2/SDL_test_crc32.h +0 -124
  91. data/assets/include/SDL2/SDL_test_font.h +0 -168
  92. data/assets/include/SDL2/SDL_test_fuzzer.h +0 -386
  93. data/assets/include/SDL2/SDL_test_harness.h +0 -134
  94. data/assets/include/SDL2/SDL_test_images.h +0 -78
  95. data/assets/include/SDL2/SDL_test_log.h +0 -67
  96. data/assets/include/SDL2/SDL_test_md5.h +0 -129
  97. data/assets/include/SDL2/SDL_test_memory.h +0 -63
  98. data/assets/include/SDL2/SDL_test_random.h +0 -115
  99. data/assets/include/SDL2/SDL_thread.h +0 -464
  100. data/assets/include/SDL2/SDL_timer.h +0 -222
  101. data/assets/include/SDL2/SDL_touch.h +0 -150
  102. data/assets/include/SDL2/SDL_ttf.h +0 -2316
  103. data/assets/include/SDL2/SDL_types.h +0 -29
  104. data/assets/include/SDL2/SDL_version.h +0 -204
  105. data/assets/include/SDL2/SDL_video.h +0 -2150
  106. data/assets/include/SDL2/SDL_vulkan.h +0 -215
  107. data/assets/include/SDL2/begin_code.h +0 -187
  108. data/assets/include/SDL2/close_code.h +0 -40
  109. data/assets/macos/universal/lib/libFLAC.a +0 -0
  110. data/assets/macos/universal/lib/libSDL2.a +0 -0
  111. data/assets/macos/universal/lib/libSDL2_mixer.a +0 -0
  112. data/assets/macos/universal/lib/libmodplug.a +0 -0
  113. data/assets/macos/universal/lib/libmpg123.a +0 -0
  114. data/assets/macos/universal/lib/libogg.a +0 -0
  115. data/assets/macos/universal/lib/libvorbis.a +0 -0
  116. data/assets/macos/universal/lib/libvorbisfile.a +0 -0
  117. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libFLAC.a +0 -0
  118. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2.a +0 -0
  119. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_mixer.a +0 -0
  120. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmodplug.a +0 -0
  121. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmpg123.a +0 -0
  122. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libogg.a +0 -0
  123. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopus.a +0 -0
  124. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopusfile.a +0 -0
  125. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libsndfile.a +0 -0
  126. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libstdc++.a +0 -0
  127. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbis.a +0 -0
  128. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbisfile.a +0 -0
  129. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libz.a +0 -0
  130. data/assets/windows/mingw-w64-x86_64/lib/libFLAC.a +0 -0
  131. data/assets/windows/mingw-w64-x86_64/lib/libSDL2.a +0 -0
  132. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_mixer.a +0 -0
  133. data/assets/windows/mingw-w64-x86_64/lib/libmodplug.a +0 -0
  134. data/assets/windows/mingw-w64-x86_64/lib/libmpg123.a +0 -0
  135. data/assets/windows/mingw-w64-x86_64/lib/libogg.a +0 -0
  136. data/assets/windows/mingw-w64-x86_64/lib/libopus.a +0 -0
  137. data/assets/windows/mingw-w64-x86_64/lib/libopusfile.a +0 -0
  138. data/assets/windows/mingw-w64-x86_64/lib/libsndfile.a +0 -0
  139. data/assets/windows/mingw-w64-x86_64/lib/libstdc++.a +0 -0
  140. data/assets/windows/mingw-w64-x86_64/lib/libvorbis.a +0 -0
  141. data/assets/windows/mingw-w64-x86_64/lib/libvorbisfile.a +0 -0
  142. data/assets/windows/mingw-w64-x86_64/lib/libz.a +0 -0
  143. data/ext/audio/extconf.h +0 -3
@@ -0,0 +1,224 @@
1
+ // ============================================================================
2
+ // reverb_node.c - Schroeder reverb node implementation
3
+ // ============================================================================
4
+
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include "reverb_node.h"
8
+
9
+ // ============================================================================
10
+ // Delay Line Helpers
11
+ // ============================================================================
12
+
13
+ // Base delay times in seconds (Schroeder-style, prime-ish ratios)
14
+ static const float COMB_DELAYS[NUM_COMBS] = { 0.0297f, 0.0371f, 0.0411f, 0.0437f };
15
+ static const float ALLPASS_DELAYS[NUM_ALLPASSES] = { 0.005f, 0.0017f };
16
+
17
+ static void delay_line_init(delay_line *dl, ma_uint32 size)
18
+ {
19
+ dl->size = size;
20
+ dl->pos = 0;
21
+ dl->buffer = (float *)calloc(size, sizeof(float));
22
+ }
23
+
24
+ static void delay_line_free(delay_line *dl)
25
+ {
26
+ if (dl->buffer) {
27
+ free(dl->buffer);
28
+ dl->buffer = NULL;
29
+ }
30
+ }
31
+
32
+ static inline float delay_line_read(delay_line *dl)
33
+ {
34
+ return dl->buffer[dl->pos];
35
+ }
36
+
37
+ static inline void delay_line_write(delay_line *dl, float value)
38
+ {
39
+ dl->buffer[dl->pos] = value;
40
+ dl->pos = (dl->pos + 1) % dl->size;
41
+ }
42
+
43
+ // ============================================================================
44
+ // Filter Processing
45
+ // ============================================================================
46
+
47
+ // Comb filter: output = buffer[pos], then write input + feedback * output (with damping)
48
+ static inline float comb_process(delay_line *dl, float input, float feedback,
49
+ float damp, float *damp_prev)
50
+ {
51
+ float output = delay_line_read(dl);
52
+ // Low-pass filter on feedback for damping (high freq decay faster)
53
+ *damp_prev = output * (1.0f - damp) + (*damp_prev) * damp;
54
+ delay_line_write(dl, input + feedback * (*damp_prev));
55
+ return output;
56
+ }
57
+
58
+ // Allpass filter: output = -g*input + buffer[pos], write input + g*buffer[pos]
59
+ static inline float allpass_process(delay_line *dl, float input, float feedback)
60
+ {
61
+ float buffered = delay_line_read(dl);
62
+ float output = buffered - feedback * input;
63
+ delay_line_write(dl, input + feedback * buffered);
64
+ return output;
65
+ }
66
+
67
+ // ============================================================================
68
+ // DSP Callback
69
+ // ============================================================================
70
+
71
+ static void reverb_process(ma_node *pNode, const float **ppFramesIn,
72
+ ma_uint32 *pFrameCountIn, float **ppFramesOut,
73
+ ma_uint32 *pFrameCountOut)
74
+ {
75
+ reverb_node *node = (reverb_node *)pNode;
76
+ const float *pFramesIn = ppFramesIn[0];
77
+ float *pFramesOut = ppFramesOut[0];
78
+ ma_uint32 frameCount = *pFrameCountOut;
79
+ ma_uint32 numChannels = node->channels;
80
+
81
+ if (!node->enabled) {
82
+ // Bypass: copy input to output
83
+ memcpy(pFramesOut, pFramesIn, frameCount * numChannels * sizeof(float));
84
+ return;
85
+ }
86
+
87
+ for (ma_uint32 iFrame = 0; iFrame < frameCount; iFrame++) {
88
+ for (ma_uint32 iChannel = 0; iChannel < numChannels && iChannel < 2; iChannel++) {
89
+ ma_uint32 sampleIndex = iFrame * numChannels + iChannel;
90
+ float input = pFramesIn[sampleIndex];
91
+
92
+ // Sum of parallel comb filters
93
+ float combSum = 0.0f;
94
+ for (int c = 0; c < NUM_COMBS; c++) {
95
+ combSum += comb_process(&node->combs[iChannel][c], input,
96
+ node->comb_feedback, node->comb_damp,
97
+ &node->comb_damp_prev[iChannel][c]);
98
+ }
99
+ combSum *= 0.25f; // Average the 4 combs
100
+
101
+ // Series allpass filters
102
+ float allpassOut = combSum;
103
+ for (int a = 0; a < NUM_ALLPASSES; a++) {
104
+ allpassOut = allpass_process(&node->allpasses[iChannel][a],
105
+ allpassOut, node->allpass_feedback);
106
+ }
107
+
108
+ // Mix dry and wet
109
+ pFramesOut[sampleIndex] = input * node->dry + allpassOut * node->wet;
110
+ }
111
+
112
+ // Handle mono->stereo or more channels by copying
113
+ for (ma_uint32 iChannel = 2; iChannel < numChannels; iChannel++) {
114
+ ma_uint32 sampleIndex = iFrame * numChannels + iChannel;
115
+ pFramesOut[sampleIndex] = pFramesIn[sampleIndex];
116
+ }
117
+ }
118
+ }
119
+
120
+ static ma_node_vtable g_reverb_vtable = {
121
+ reverb_process,
122
+ NULL,
123
+ 1,
124
+ 1,
125
+ 0
126
+ };
127
+
128
+ // ============================================================================
129
+ // Lifecycle
130
+ // ============================================================================
131
+
132
+ ma_result reverb_init(reverb_node *pNode, ma_node_graph *pNodeGraph,
133
+ ma_uint32 sampleRate, ma_uint32 numChannels)
134
+ {
135
+ if (pNode == NULL) {
136
+ return MA_INVALID_ARGS;
137
+ }
138
+
139
+ memset(pNode, 0, sizeof(*pNode));
140
+ pNode->sample_rate = sampleRate;
141
+ pNode->channels = numChannels;
142
+ pNode->enabled = MA_FALSE;
143
+
144
+ // Default parameters
145
+ pNode->room_size = 0.5f;
146
+ pNode->comb_feedback = 0.7f;
147
+ pNode->comb_damp = 0.3f;
148
+ pNode->allpass_feedback = 0.5f;
149
+ pNode->wet = 0.3f;
150
+ pNode->dry = 1.0f;
151
+
152
+ // Initialize delay lines for up to 2 audio channels
153
+ ma_uint32 chans = numChannels < 2 ? numChannels : 2;
154
+ for (ma_uint32 ch = 0; ch < chans; ch++) {
155
+ for (int c = 0; c < NUM_COMBS; c++) {
156
+ ma_uint32 delaySize = (ma_uint32)(COMB_DELAYS[c] * pNode->room_size * 2.0f * sampleRate);
157
+ if (delaySize < 1) delaySize = 1;
158
+ delay_line_init(&pNode->combs[ch][c], delaySize);
159
+ }
160
+ for (int a = 0; a < NUM_ALLPASSES; a++) {
161
+ ma_uint32 delaySize = (ma_uint32)(ALLPASS_DELAYS[a] * sampleRate);
162
+ if (delaySize < 1) delaySize = 1;
163
+ delay_line_init(&pNode->allpasses[ch][a], delaySize);
164
+ }
165
+ }
166
+
167
+ // Set up node
168
+ ma_uint32 channelsArray[1] = { numChannels };
169
+ ma_node_config nodeConfig = ma_node_config_init();
170
+ nodeConfig.vtable = &g_reverb_vtable;
171
+ nodeConfig.pInputChannels = channelsArray;
172
+ nodeConfig.pOutputChannels = channelsArray;
173
+
174
+ return ma_node_init(pNodeGraph, &nodeConfig, NULL, &pNode->base);
175
+ }
176
+
177
+ void reverb_uninit(reverb_node *pNode)
178
+ {
179
+ if (pNode == NULL) return;
180
+
181
+ ma_node_uninit(&pNode->base, NULL);
182
+
183
+ for (int ch = 0; ch < 2; ch++) {
184
+ for (int c = 0; c < NUM_COMBS; c++) {
185
+ delay_line_free(&pNode->combs[ch][c]);
186
+ }
187
+ for (int a = 0; a < NUM_ALLPASSES; a++) {
188
+ delay_line_free(&pNode->allpasses[ch][a]);
189
+ }
190
+ }
191
+ }
192
+
193
+ // ============================================================================
194
+ // Parameter Control
195
+ // ============================================================================
196
+
197
+ void reverb_set_enabled(reverb_node *pNode, ma_bool32 enabled)
198
+ {
199
+ if (pNode) pNode->enabled = enabled;
200
+ }
201
+
202
+ void reverb_set_room_size(reverb_node *pNode, float size)
203
+ {
204
+ if (pNode == NULL) return;
205
+ pNode->room_size = size;
206
+ // Note: changing room_size after init would require reallocating buffers
207
+ // For now, this affects feedback calculation
208
+ pNode->comb_feedback = 0.6f + size * 0.35f; // 0.6 to 0.95
209
+ }
210
+
211
+ void reverb_set_damping(reverb_node *pNode, float damp)
212
+ {
213
+ if (pNode) pNode->comb_damp = damp;
214
+ }
215
+
216
+ void reverb_set_wet(reverb_node *pNode, float wet)
217
+ {
218
+ if (pNode) pNode->wet = wet;
219
+ }
220
+
221
+ void reverb_set_dry(reverb_node *pNode, float dry)
222
+ {
223
+ if (pNode) pNode->dry = dry;
224
+ }
@@ -0,0 +1,63 @@
1
+ // ============================================================================
2
+ // reverb_node.h - Schroeder reverb node for native_audio
3
+ // ============================================================================
4
+
5
+ #ifndef REVERB_NODE_H
6
+ #define REVERB_NODE_H
7
+
8
+ #include "miniaudio.h"
9
+
10
+ // ============================================================================
11
+ // Constants
12
+ // ============================================================================
13
+
14
+ #define NUM_COMBS 4
15
+ #define NUM_ALLPASSES 2
16
+
17
+ // ============================================================================
18
+ // Types
19
+ // ============================================================================
20
+
21
+ typedef struct {
22
+ float *buffer;
23
+ ma_uint32 size;
24
+ ma_uint32 pos;
25
+ } delay_line;
26
+
27
+ typedef struct {
28
+ ma_node_base base;
29
+ ma_uint32 channels;
30
+ ma_uint32 sample_rate;
31
+
32
+ // 4 parallel comb filters per audio channel
33
+ delay_line combs[2][NUM_COMBS]; // [audio_channel][comb_index]
34
+ float comb_feedback;
35
+ float comb_damp;
36
+ float comb_damp_prev[2][NUM_COMBS];
37
+
38
+ // 2 series allpass filters per audio channel
39
+ delay_line allpasses[2][NUM_ALLPASSES];
40
+ float allpass_feedback;
41
+
42
+ // Mix control
43
+ float wet;
44
+ float dry;
45
+ float room_size;
46
+ ma_bool32 enabled;
47
+ } reverb_node;
48
+
49
+ // ============================================================================
50
+ // Public API
51
+ // ============================================================================
52
+
53
+ ma_result reverb_init(reverb_node *pNode, ma_node_graph *pNodeGraph,
54
+ ma_uint32 sampleRate, ma_uint32 numChannels);
55
+ void reverb_uninit(reverb_node *pNode);
56
+
57
+ void reverb_set_enabled(reverb_node *pNode, ma_bool32 enabled);
58
+ void reverb_set_room_size(reverb_node *pNode, float size);
59
+ void reverb_set_damping(reverb_node *pNode, float damp);
60
+ void reverb_set_wet(reverb_node *pNode, float wet);
61
+ void reverb_set_dry(reverb_node *pNode, float dry);
62
+
63
+ #endif // REVERB_NODE_H
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Dummy audio backend for CI/testing environments without audio hardware.
4
+ # Has the same interface as the Audio C extension but does nothing.
5
+ module DummyAudio
6
+ @sound_count = 0
7
+ @tap_counts = {}
8
+
9
+ def self.init
10
+ nil
11
+ end
12
+
13
+ def self.load(path)
14
+ id = @sound_count
15
+ @sound_count += 1
16
+ id
17
+ end
18
+
19
+ def self.duration(clip)
20
+ 5.0
21
+ end
22
+
23
+ def self.play(channel, clip)
24
+ @tap_counts[channel] = 0
25
+ channel
26
+ end
27
+
28
+ def self.stop(channel)
29
+ nil
30
+ end
31
+
32
+ def self.pause(channel)
33
+ nil
34
+ end
35
+
36
+ def self.resume(channel)
37
+ nil
38
+ end
39
+
40
+ def self.set_volume(channel, volume)
41
+ nil
42
+ end
43
+
44
+ def self.set_pitch(channel, pitch)
45
+ nil
46
+ end
47
+
48
+ def self.set_pos(channel, angle, distance)
49
+ nil
50
+ end
51
+
52
+ def self.set_looping(channel, looping)
53
+ nil
54
+ end
55
+
56
+ def self.add_delay_tap(channel, time_ms, volume)
57
+ @tap_counts[channel] ||= 0
58
+ tap_id = @tap_counts[channel]
59
+ @tap_counts[channel] += 1
60
+ tap_id
61
+ end
62
+
63
+ def self.remove_delay_tap(channel, tap_id)
64
+ nil
65
+ end
66
+
67
+ def self.set_delay_tap_volume(channel, tap_id, volume)
68
+ nil
69
+ end
70
+
71
+ def self.set_delay_tap_time(channel, tap_id, time_ms)
72
+ nil
73
+ end
74
+
75
+ def self.enable_reverb(channel, enabled)
76
+ nil
77
+ end
78
+
79
+ def self.set_reverb_room_size(channel, size)
80
+ nil
81
+ end
82
+
83
+ def self.set_reverb_damping(channel, damp)
84
+ nil
85
+ end
86
+
87
+ def self.set_reverb_wet(channel, wet)
88
+ nil
89
+ end
90
+
91
+ def self.set_reverb_dry(channel, dry)
92
+ nil
93
+ end
94
+ end
data/lib/native_audio.rb CHANGED
@@ -1,46 +1,117 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative './audio'
4
+ require_relative './dummy_audio'
5
+
6
+ Audio.init unless ENV['DUMMY_AUDIO_BACKEND'] == 'true'
4
7
 
5
8
  module NativeAudio
9
+ def self.audio_driver
10
+ ENV['DUMMY_AUDIO_BACKEND'] == 'true' ? DummyAudio : Audio
11
+ end
12
+
6
13
  class Clip
7
14
  attr_reader :clip
8
15
 
9
16
  def initialize(path)
10
17
  @path = path
11
- @clip = Audio.load(path)
18
+ @clip = NativeAudio.audio_driver.load(path)
19
+ end
20
+
21
+ def duration
22
+ NativeAudio.audio_driver.duration(@clip)
23
+ end
24
+ end
25
+
26
+ class DelayTap
27
+ attr_reader :id, :audio_source, :time_ms, :volume
28
+
29
+ def initialize(audio_source, id, time_ms, volume)
30
+ @audio_source = audio_source
31
+ @id = id
32
+ @time_ms = time_ms
33
+ @volume = volume
34
+ end
35
+
36
+ def volume=(val)
37
+ NativeAudio.audio_driver.set_delay_tap_volume(@audio_source.channel, @id, val)
38
+ @volume = val
39
+ end
40
+
41
+ def time_ms=(val)
42
+ NativeAudio.audio_driver.set_delay_tap_time(@audio_source.channel, @id, val)
43
+ @time_ms = val
44
+ end
45
+
46
+ def remove
47
+ NativeAudio.audio_driver.remove_delay_tap(@audio_source.channel, @id)
48
+ @audio_source.delay_taps.delete(self)
12
49
  end
13
50
  end
14
51
 
15
52
  class AudioSource
53
+ attr_reader :channel
54
+
16
55
  def initialize(clip)
17
56
  @clip = clip
18
57
  @channel = AudioSource.channels.count
58
+ @delay_taps = []
19
59
  AudioSource.channels << self
20
60
  end
21
61
 
22
62
  def play
23
- Audio.play(@channel, @clip.clip)
63
+ NativeAudio.audio_driver.play(@channel, @clip.clip)
24
64
  end
25
65
 
26
66
  def stop
27
- Audio.stop(@channel)
67
+ NativeAudio.audio_driver.stop(@channel)
28
68
  end
29
69
 
30
70
  def pause
31
- Audio.pause(@channel)
71
+ NativeAudio.audio_driver.pause(@channel)
32
72
  end
33
73
 
34
74
  def resume
35
- Audio.resume(@channel)
75
+ NativeAudio.audio_driver.resume(@channel)
36
76
  end
37
77
 
38
78
  def set_pos(angle, distance)
39
- Audio.set_pos(@channel, angle, distance)
79
+ NativeAudio.audio_driver.set_pos(@channel, angle, distance)
40
80
  end
41
81
 
42
82
  def set_volume(volume)
43
- Audio.set_volume(@channel, volume)
83
+ NativeAudio.audio_driver.set_volume(@channel, volume)
84
+ end
85
+
86
+ def set_pitch(pitch)
87
+ NativeAudio.audio_driver.set_pitch(@channel, pitch)
88
+ end
89
+
90
+ def set_looping(looping)
91
+ NativeAudio.audio_driver.set_looping(@channel, looping)
92
+ end
93
+
94
+ def add_delay_tap(time_ms:, volume:)
95
+ tap_id = NativeAudio.audio_driver.add_delay_tap(@channel, time_ms, volume)
96
+ tap = DelayTap.new(self, tap_id, time_ms, volume)
97
+ @delay_taps << tap
98
+ tap
99
+ end
100
+
101
+ def enable_reverb(enabled = true)
102
+ NativeAudio.audio_driver.enable_reverb(@channel, enabled)
103
+ end
104
+
105
+ def set_reverb(room_size: 0.5, damping: 0.3, wet: 0.3, dry: 1.0)
106
+ NativeAudio.audio_driver.enable_reverb(@channel, true)
107
+ NativeAudio.audio_driver.set_reverb_room_size(@channel, room_size)
108
+ NativeAudio.audio_driver.set_reverb_damping(@channel, damping)
109
+ NativeAudio.audio_driver.set_reverb_wet(@channel, wet)
110
+ NativeAudio.audio_driver.set_reverb_dry(@channel, dry)
111
+ end
112
+
113
+ def delay_taps
114
+ @delay_taps
44
115
  end
45
116
 
46
117
  def self.channels
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: native_audio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Hatfull
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-01-26 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: A simple audio library for Ruby
13
13
  email:
@@ -17,137 +17,17 @@ extensions:
17
17
  - ext/audio/extconf.rb
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - assets/include/SDL2/SDL.h
21
- - assets/include/SDL2/SDL_assert.h
22
- - assets/include/SDL2/SDL_atomic.h
23
- - assets/include/SDL2/SDL_audio.h
24
- - assets/include/SDL2/SDL_bits.h
25
- - assets/include/SDL2/SDL_blendmode.h
26
- - assets/include/SDL2/SDL_clipboard.h
27
- - assets/include/SDL2/SDL_config.h
28
- - assets/include/SDL2/SDL_config_android.h
29
- - assets/include/SDL2/SDL_config_emscripten.h
30
- - assets/include/SDL2/SDL_config_iphoneos.h
31
- - assets/include/SDL2/SDL_config_macosx.h
32
- - assets/include/SDL2/SDL_config_minimal.h
33
- - assets/include/SDL2/SDL_config_ngage.h
34
- - assets/include/SDL2/SDL_config_os2.h
35
- - assets/include/SDL2/SDL_config_pandora.h
36
- - assets/include/SDL2/SDL_config_windows.h
37
- - assets/include/SDL2/SDL_config_wingdk.h
38
- - assets/include/SDL2/SDL_config_winrt.h
39
- - assets/include/SDL2/SDL_config_xbox.h
40
- - assets/include/SDL2/SDL_copying.h
41
- - assets/include/SDL2/SDL_cpuinfo.h
42
- - assets/include/SDL2/SDL_egl.h
43
- - assets/include/SDL2/SDL_endian.h
44
- - assets/include/SDL2/SDL_error.h
45
- - assets/include/SDL2/SDL_events.h
46
- - assets/include/SDL2/SDL_filesystem.h
47
- - assets/include/SDL2/SDL_gamecontroller.h
48
- - assets/include/SDL2/SDL_gesture.h
49
- - assets/include/SDL2/SDL_guid.h
50
- - assets/include/SDL2/SDL_haptic.h
51
- - assets/include/SDL2/SDL_hidapi.h
52
- - assets/include/SDL2/SDL_hints.h
53
- - assets/include/SDL2/SDL_image.h
54
- - assets/include/SDL2/SDL_joystick.h
55
- - assets/include/SDL2/SDL_keyboard.h
56
- - assets/include/SDL2/SDL_keycode.h
57
- - assets/include/SDL2/SDL_loadso.h
58
- - assets/include/SDL2/SDL_locale.h
59
- - assets/include/SDL2/SDL_log.h
60
- - assets/include/SDL2/SDL_main.h
61
- - assets/include/SDL2/SDL_messagebox.h
62
- - assets/include/SDL2/SDL_metal.h
63
- - assets/include/SDL2/SDL_misc.h
64
- - assets/include/SDL2/SDL_mixer.h
65
- - assets/include/SDL2/SDL_mouse.h
66
- - assets/include/SDL2/SDL_mutex.h
67
- - assets/include/SDL2/SDL_name.h
68
- - assets/include/SDL2/SDL_opengl.h
69
- - assets/include/SDL2/SDL_opengl_glext.h
70
- - assets/include/SDL2/SDL_opengles.h
71
- - assets/include/SDL2/SDL_opengles2.h
72
- - assets/include/SDL2/SDL_opengles2_gl2.h
73
- - assets/include/SDL2/SDL_opengles2_gl2ext.h
74
- - assets/include/SDL2/SDL_opengles2_gl2platform.h
75
- - assets/include/SDL2/SDL_opengles2_khrplatform.h
76
- - assets/include/SDL2/SDL_pixels.h
77
- - assets/include/SDL2/SDL_platform.h
78
- - assets/include/SDL2/SDL_power.h
79
- - assets/include/SDL2/SDL_quit.h
80
- - assets/include/SDL2/SDL_rect.h
81
- - assets/include/SDL2/SDL_render.h
82
- - assets/include/SDL2/SDL_revision.h
83
- - assets/include/SDL2/SDL_rwops.h
84
- - assets/include/SDL2/SDL_scancode.h
85
- - assets/include/SDL2/SDL_sensor.h
86
- - assets/include/SDL2/SDL_shape.h
87
- - assets/include/SDL2/SDL_stdinc.h
88
- - assets/include/SDL2/SDL_surface.h
89
- - assets/include/SDL2/SDL_system.h
90
- - assets/include/SDL2/SDL_syswm.h
91
- - assets/include/SDL2/SDL_test.h
92
- - assets/include/SDL2/SDL_test_assert.h
93
- - assets/include/SDL2/SDL_test_common.h
94
- - assets/include/SDL2/SDL_test_compare.h
95
- - assets/include/SDL2/SDL_test_crc32.h
96
- - assets/include/SDL2/SDL_test_font.h
97
- - assets/include/SDL2/SDL_test_fuzzer.h
98
- - assets/include/SDL2/SDL_test_harness.h
99
- - assets/include/SDL2/SDL_test_images.h
100
- - assets/include/SDL2/SDL_test_log.h
101
- - assets/include/SDL2/SDL_test_md5.h
102
- - assets/include/SDL2/SDL_test_memory.h
103
- - assets/include/SDL2/SDL_test_random.h
104
- - assets/include/SDL2/SDL_thread.h
105
- - assets/include/SDL2/SDL_timer.h
106
- - assets/include/SDL2/SDL_touch.h
107
- - assets/include/SDL2/SDL_ttf.h
108
- - assets/include/SDL2/SDL_types.h
109
- - assets/include/SDL2/SDL_version.h
110
- - assets/include/SDL2/SDL_video.h
111
- - assets/include/SDL2/SDL_vulkan.h
112
- - assets/include/SDL2/begin_code.h
113
- - assets/include/SDL2/close_code.h
114
- - assets/macos/universal/lib/libFLAC.a
115
- - assets/macos/universal/lib/libSDL2.a
116
- - assets/macos/universal/lib/libSDL2_mixer.a
117
- - assets/macos/universal/lib/libmodplug.a
118
- - assets/macos/universal/lib/libmpg123.a
119
- - assets/macos/universal/lib/libogg.a
120
- - assets/macos/universal/lib/libvorbis.a
121
- - assets/macos/universal/lib/libvorbisfile.a
122
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libFLAC.a
123
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2.a
124
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_mixer.a
125
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libmodplug.a
126
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libmpg123.a
127
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libogg.a
128
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libopus.a
129
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libopusfile.a
130
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libsndfile.a
131
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libstdc++.a
132
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbis.a
133
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbisfile.a
134
- - assets/windows/mingw-w64-ucrt-x86_64/lib/libz.a
135
- - assets/windows/mingw-w64-x86_64/lib/libFLAC.a
136
- - assets/windows/mingw-w64-x86_64/lib/libSDL2.a
137
- - assets/windows/mingw-w64-x86_64/lib/libSDL2_mixer.a
138
- - assets/windows/mingw-w64-x86_64/lib/libmodplug.a
139
- - assets/windows/mingw-w64-x86_64/lib/libmpg123.a
140
- - assets/windows/mingw-w64-x86_64/lib/libogg.a
141
- - assets/windows/mingw-w64-x86_64/lib/libopus.a
142
- - assets/windows/mingw-w64-x86_64/lib/libopusfile.a
143
- - assets/windows/mingw-w64-x86_64/lib/libsndfile.a
144
- - assets/windows/mingw-w64-x86_64/lib/libstdc++.a
145
- - assets/windows/mingw-w64-x86_64/lib/libvorbis.a
146
- - assets/windows/mingw-w64-x86_64/lib/libvorbisfile.a
147
- - assets/windows/mingw-w64-x86_64/lib/libz.a
20
+ - LICENSE
21
+ - README.md
148
22
  - ext/audio/audio.c
149
- - ext/audio/extconf.h
23
+ - ext/audio/audio.h
24
+ - ext/audio/delay_node.c
25
+ - ext/audio/delay_node.h
150
26
  - ext/audio/extconf.rb
27
+ - ext/audio/miniaudio.h
28
+ - ext/audio/reverb_node.c
29
+ - ext/audio/reverb_node.h
30
+ - lib/dummy_audio.rb
151
31
  - lib/native_audio.rb
152
32
  homepage: https://github.com/rubyrpg/native_audio
153
33
  licenses:
@@ -167,7 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
47
  - !ruby/object:Gem::Version
168
48
  version: '0'
169
49
  requirements: []
170
- rubygems_version: 3.6.2
50
+ rubygems_version: 4.0.3
171
51
  specification_version: 4
172
52
  summary: A simple audio library for Ruby
173
53
  test_files: []