sfml3-rb 0.0.1 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +321 -0
- data/README.md +44 -14
- data/TODO.md +199 -0
- data/ext/audio/audio_enums.c +131 -0
- data/ext/audio/audio_enums.h +18 -0
- data/ext/audio/effect_processor.c +233 -0
- data/ext/audio/effect_processor.h +25 -0
- data/ext/audio/listener.c +83 -0
- data/ext/audio/listener.h +8 -0
- data/ext/audio/music.c +174 -0
- data/ext/audio/music.h +14 -0
- data/ext/audio/sound.c +139 -0
- data/ext/audio/sound.h +14 -0
- data/ext/audio/sound_buffer.c +274 -0
- data/ext/audio/sound_buffer.h +18 -0
- data/ext/audio/sound_buffer_recorder.c +109 -0
- data/ext/audio/sound_buffer_recorder.h +14 -0
- data/ext/audio/sound_recorder.c +268 -0
- data/ext/audio/sound_recorder.h +14 -0
- data/ext/audio/sound_source.h +13 -0
- data/ext/audio/sound_source.inc +271 -0
- data/ext/audio/sound_source_cone.c +138 -0
- data/ext/audio/sound_source_cone.h +20 -0
- data/ext/audio/sound_stream.c +294 -0
- data/ext/audio/sound_stream.h +14 -0
- data/ext/{exceptions.c → core/exceptions.c} +10 -8
- data/ext/{ext → core}/exceptions.h +3 -3
- data/ext/core/foreign_thread.c +149 -0
- data/ext/core/foreign_thread.h +31 -0
- data/ext/core/macros.h +8 -0
- data/ext/{ext → core}/sfml.h +5 -3
- data/ext/core/unicode.c +46 -0
- data/ext/core/unicode.h +25 -0
- data/ext/ext.c +125 -14
- data/ext/extconf.rb +51 -6
- data/ext/graphics/blend_mode.c +261 -0
- data/ext/graphics/blend_mode.h +18 -0
- data/ext/graphics/circle.c +319 -0
- data/ext/{ext/klass/drawable → graphics}/circle.h +3 -3
- data/ext/graphics/color.c +318 -0
- data/ext/graphics/color.h +37 -0
- data/ext/{drawable.c → graphics/drawable.c} +11 -11
- data/ext/graphics/drawable.h +10 -0
- data/ext/graphics/enums.c +123 -0
- data/ext/graphics/enums.h +20 -0
- data/ext/graphics/font.c +148 -0
- data/ext/graphics/font.h +14 -0
- data/ext/graphics/glyph.c +60 -0
- data/ext/graphics/glyph.h +14 -0
- data/ext/graphics/image.c +205 -0
- data/ext/graphics/image.h +16 -0
- data/ext/graphics/polygon.c +300 -0
- data/ext/graphics/polygon.h +10 -0
- data/ext/graphics/rect.c +287 -0
- data/ext/graphics/rect.h +30 -0
- data/ext/graphics/rectangle.c +302 -0
- data/ext/graphics/rectangle.h +10 -0
- data/ext/graphics/render_state.c +204 -0
- data/ext/graphics/render_state.h +18 -0
- data/ext/graphics/render_target.inc +181 -0
- data/ext/graphics/render_texture.c +182 -0
- data/ext/graphics/render_texture.h +14 -0
- data/ext/graphics/shader.c +540 -0
- data/ext/graphics/shader.h +14 -0
- data/ext/graphics/shape.c +311 -0
- data/ext/graphics/shape.h +10 -0
- data/ext/graphics/sprite.c +249 -0
- data/ext/graphics/sprite.h +10 -0
- data/ext/graphics/stencil_mode.c +211 -0
- data/ext/graphics/stencil_mode.h +18 -0
- data/ext/graphics/target.c +133 -0
- data/ext/graphics/target.h +40 -0
- data/ext/graphics/text.c +344 -0
- data/ext/graphics/text.h +10 -0
- data/ext/graphics/texture.c +379 -0
- data/ext/graphics/texture.h +16 -0
- data/ext/graphics/transform.c +372 -0
- data/ext/graphics/transform.h +35 -0
- data/ext/{transformable.c → graphics/transformable.c} +168 -144
- data/ext/{ext/klass → graphics}/transformable.h +3 -3
- data/ext/graphics/vertex.c +179 -0
- data/ext/graphics/vertex.h +23 -0
- data/ext/graphics/vertex_array.c +127 -0
- data/ext/graphics/vertex_array.h +10 -0
- data/ext/graphics/vertex_buffer.c +211 -0
- data/ext/graphics/vertex_buffer.h +14 -0
- data/ext/{view.c → graphics/view.c} +168 -169
- data/ext/{ext/klass → graphics}/view.h +3 -3
- data/ext/network/ftp.c +405 -0
- data/ext/network/ftp.h +20 -0
- data/ext/network/http.c +243 -0
- data/ext/network/http.h +18 -0
- data/ext/network/ip_address.c +164 -0
- data/ext/network/ip_address.h +20 -0
- data/ext/network/network_enums.c +298 -0
- data/ext/network/network_enums.h +26 -0
- data/ext/network/packet.c +189 -0
- data/ext/network/packet.h +14 -0
- data/ext/network/socket_selector.c +142 -0
- data/ext/network/socket_selector.h +14 -0
- data/ext/network/tcp_listener.c +115 -0
- data/ext/network/tcp_listener.h +14 -0
- data/ext/network/tcp_socket.c +199 -0
- data/ext/network/tcp_socket.h +17 -0
- data/ext/network/udp_socket.c +190 -0
- data/ext/network/udp_socket.h +14 -0
- data/ext/ports.rb +88 -21
- data/ext/system/buffer.c +77 -0
- data/ext/system/buffer.h +14 -0
- data/ext/system/clock.c +100 -0
- data/ext/{ext/klass → system}/clock.h +3 -3
- data/ext/system/input_stream.c +229 -0
- data/ext/system/input_stream.h +23 -0
- data/ext/system/sleep.c +16 -0
- data/ext/system/sleep.h +8 -0
- data/ext/system/time.c +218 -0
- data/ext/system/time.h +18 -0
- data/ext/system/vec2.c +251 -0
- data/ext/system/vec2.h +55 -0
- data/ext/system/vec3.c +219 -0
- data/ext/system/vec3.h +18 -0
- data/ext/window/clipboard.c +89 -0
- data/ext/window/clipboard.h +8 -0
- data/ext/window/context.c +70 -0
- data/ext/window/context.h +8 -0
- data/ext/window/context_settings.c +220 -0
- data/ext/window/context_settings.h +18 -0
- data/ext/window/cursor.c +56 -0
- data/ext/window/cursor.h +14 -0
- data/ext/window/event.c +216 -0
- data/ext/window/event.h +14 -0
- data/ext/{event_name.c → window/event_name.c} +2 -2
- data/ext/window/event_name.h +8 -0
- data/ext/window/input_enums.c +261 -0
- data/ext/window/input_enums.h +36 -0
- data/ext/window/joystick.c +60 -0
- data/ext/window/joystick.h +8 -0
- data/ext/{keyboard.c → window/keyboard.c} +74 -2
- data/ext/window/keyboard.h +12 -0
- data/ext/window/mouse.c +70 -0
- data/ext/window/mouse.h +8 -0
- data/ext/window/sensor.c +30 -0
- data/ext/window/sensor.h +8 -0
- data/ext/window/touch.c +49 -0
- data/ext/window/touch.h +8 -0
- data/ext/window/video_mode.c +133 -0
- data/ext/window/video_mode.h +14 -0
- data/ext/window/vulkan.c +44 -0
- data/ext/window/vulkan.h +8 -0
- data/ext/window/window.c +414 -0
- data/ext/{ext/klass → window}/window.h +3 -3
- data/lib/sfml/version.rb +4 -2
- data/lib/sfml.rb +2 -0
- metadata +163 -56
- data/ext/circle.c +0 -198
- data/ext/clock.c +0 -65
- data/ext/color.c +0 -43
- data/ext/event.c +0 -148
- data/ext/ext/klass/color.h +0 -26
- data/ext/ext/klass/drawable/image.h +0 -4
- data/ext/ext/klass/drawable/polygon.h +0 -4
- data/ext/ext/klass/drawable/rectangle.h +0 -4
- data/ext/ext/klass/drawable/sprite.h +0 -4
- data/ext/ext/klass/drawable/texture.h +0 -4
- data/ext/ext/klass/event/event_name.h +0 -8
- data/ext/ext/klass/event.h +0 -12
- data/ext/ext/klass/keyboard.h +0 -8
- data/ext/ext/klass/render_state.h +0 -16
- data/ext/ext/klass/target.h +0 -18
- data/ext/ext/klass/transform.h +0 -17
- data/ext/ext/klass/video_mode.h +0 -12
- data/ext/ext/module/drawable/drawable.h +0 -10
- data/ext/ext/module/transform.h +0 -18
- data/ext/ext/module.h +0 -10
- data/ext/ext/rect.h +0 -16
- data/ext/ext/style_name.h +0 -11
- data/ext/ext/vec2.h +0 -38
- data/ext/image.c +0 -5
- data/ext/polygon.c +0 -5
- data/ext/rect.c +0 -26
- data/ext/rectangle.c +0 -5
- data/ext/render_state.c +0 -109
- data/ext/sprite.c +0 -5
- data/ext/style_name.c +0 -15
- data/ext/target.c +0 -106
- data/ext/texture.c +0 -5
- data/ext/transform.c +0 -107
- data/ext/vec2.c +0 -42
- data/ext/video_mode.c +0 -78
- data/ext/window.c +0 -274
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#include "audio/sound_recorder.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
#include <ruby/thread.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
#include <stdlib.h>
|
|
7
|
+
|
|
8
|
+
#include "audio/audio_enums.h"
|
|
9
|
+
#include "core/macros.h"
|
|
10
|
+
|
|
11
|
+
/* A subclassable recorder. The capture callbacks arrive on SFML's audio
|
|
12
|
+
thread, so each re-enters Ruby through rb_thread_call_with_gvl and treats an
|
|
13
|
+
exception as "stop capturing" instead of unwinding into the audio engine.
|
|
14
|
+
A subclass only has to implement #on_process; #on_start and #on_stop are
|
|
15
|
+
optional and default to continuing. */
|
|
16
|
+
typedef struct {
|
|
17
|
+
VALUE rb_self;
|
|
18
|
+
sfSoundRecorder *handle;
|
|
19
|
+
} SoundRecorder;
|
|
20
|
+
|
|
21
|
+
static VALUE rb_cSoundRecorder;
|
|
22
|
+
|
|
23
|
+
static void SoundRecorder_mark(void *ptr) {
|
|
24
|
+
SoundRecorder *recorder = ptr;
|
|
25
|
+
|
|
26
|
+
rb_gc_mark(recorder->rb_self);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static void SoundRecorder_free(void *ptr) {
|
|
30
|
+
SoundRecorder *recorder = ptr;
|
|
31
|
+
|
|
32
|
+
if (recorder->handle != NULL) {
|
|
33
|
+
sfSoundRecorder_destroy(recorder->handle);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
free(recorder);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static const rb_data_type_t SoundRecorder_data_type = {
|
|
40
|
+
.wrap_struct_name = "SFML::SoundRecorder",
|
|
41
|
+
.function = {.dmark = SoundRecorder_mark, .dfree = SoundRecorder_free, .dsize = NULL},
|
|
42
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
typedef struct {
|
|
46
|
+
VALUE self;
|
|
47
|
+
ID method;
|
|
48
|
+
} InvokeContext;
|
|
49
|
+
|
|
50
|
+
static VALUE SoundRecorder_invoke_body(VALUE raw) {
|
|
51
|
+
InvokeContext *ctx = (InvokeContext *) raw;
|
|
52
|
+
|
|
53
|
+
return rb_funcall(ctx->self, ctx->method, 0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Calls a zero-argument Ruby method, swallowing any exception it raises. */
|
|
57
|
+
static void SoundRecorder_invoke(VALUE self, ID method) {
|
|
58
|
+
InvokeContext ctx = {.self = self, .method = method};
|
|
59
|
+
int state = 0;
|
|
60
|
+
|
|
61
|
+
rb_protect(SoundRecorder_invoke_body, (VALUE) &ctx, &state);
|
|
62
|
+
|
|
63
|
+
if (state) {
|
|
64
|
+
rb_set_errinfo(Qnil);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static bool SoundRecorder_on_start(void *userData) {
|
|
69
|
+
SoundRecorder *recorder = userData;
|
|
70
|
+
|
|
71
|
+
if (rb_respond_to(recorder->rb_self, rb_intern("on_start"))) {
|
|
72
|
+
SoundRecorder_invoke(recorder->rb_self, rb_intern("on_start"));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
typedef struct {
|
|
79
|
+
SoundRecorder *recorder;
|
|
80
|
+
const int16_t *samples;
|
|
81
|
+
size_t sample_count;
|
|
82
|
+
int ok;
|
|
83
|
+
} ProcessContext;
|
|
84
|
+
|
|
85
|
+
static VALUE SoundRecorder_process_body(VALUE raw) {
|
|
86
|
+
ProcessContext *ctx = (ProcessContext *) raw;
|
|
87
|
+
VALUE rb_samples = rb_ary_new_capa((long) ctx->sample_count);
|
|
88
|
+
VALUE result;
|
|
89
|
+
size_t i;
|
|
90
|
+
|
|
91
|
+
for (i = 0; i < ctx->sample_count; i++) {
|
|
92
|
+
rb_ary_push(rb_samples, INT2NUM(ctx->samples[i]));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
result = rb_funcall(ctx->recorder->rb_self, rb_intern("on_process"), 1, rb_samples);
|
|
96
|
+
ctx->ok = RTEST(result) ? 1 : 0;
|
|
97
|
+
|
|
98
|
+
return Qnil;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static void *SoundRecorder_process_gvl(void *raw) {
|
|
102
|
+
int state = 0;
|
|
103
|
+
|
|
104
|
+
rb_protect(SoundRecorder_process_body, (VALUE) raw, &state);
|
|
105
|
+
|
|
106
|
+
if (state) {
|
|
107
|
+
rb_set_errinfo(Qnil);
|
|
108
|
+
((ProcessContext *) raw)->ok = 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return NULL;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static bool SoundRecorder_on_process(const int16_t *samples, size_t sample_count, void *userData) {
|
|
115
|
+
SoundRecorder *recorder = userData;
|
|
116
|
+
ProcessContext ctx = {
|
|
117
|
+
.recorder = recorder, .samples = samples, .sample_count = sample_count, .ok = 0
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
rb_thread_call_with_gvl(SoundRecorder_process_gvl, &ctx);
|
|
121
|
+
|
|
122
|
+
return ctx.ok ? true : false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
static void SoundRecorder_on_stop(void *userData) {
|
|
126
|
+
SoundRecorder *recorder = userData;
|
|
127
|
+
|
|
128
|
+
if (rb_respond_to(recorder->rb_self, rb_intern("on_stop"))) {
|
|
129
|
+
SoundRecorder_invoke(recorder->rb_self, rb_intern("on_stop"));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static VALUE SoundRecorder_new(VALUE klass) {
|
|
134
|
+
SoundRecorder *ptr;
|
|
135
|
+
sfSoundRecorder *handle;
|
|
136
|
+
VALUE self;
|
|
137
|
+
|
|
138
|
+
ptr = malloc(sizeof(SoundRecorder));
|
|
139
|
+
ptr->rb_self = Qnil;
|
|
140
|
+
ptr->handle = NULL;
|
|
141
|
+
|
|
142
|
+
self = TypedData_Wrap_Struct(klass, &SoundRecorder_data_type, ptr);
|
|
143
|
+
ptr->rb_self = self;
|
|
144
|
+
|
|
145
|
+
if (!rb_respond_to(self, rb_intern("on_process"))) {
|
|
146
|
+
/* Ruby already owns the wrapper; SoundRecorder_free handles the NULL
|
|
147
|
+
handle, so let GC clean up after the raise. */
|
|
148
|
+
rb_raise(rb_eNotImpError, "subclass must define #on_process");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
handle = sfSoundRecorder_create(SoundRecorder_on_start, SoundRecorder_on_process,
|
|
152
|
+
SoundRecorder_on_stop, ptr);
|
|
153
|
+
|
|
154
|
+
if (handle == NULL) {
|
|
155
|
+
rb_raise(rb_eRuntimeError, "failed to create sound recorder (no capture device?)");
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
ptr->handle = handle;
|
|
159
|
+
|
|
160
|
+
return self;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static VALUE SoundRecorder_start(VALUE self, VALUE rb_sample_rate) {
|
|
164
|
+
return BOOL2RB(sfSoundRecorder_start(Get_SoundRecorder_Struct(self),
|
|
165
|
+
(unsigned int) NUM2INT(rb_sample_rate)));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static VALUE SoundRecorder_stop(VALUE self) {
|
|
169
|
+
sfSoundRecorder_stop(Get_SoundRecorder_Struct(self));
|
|
170
|
+
return self;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
static VALUE SoundRecorder_sample_rate(VALUE self) {
|
|
174
|
+
return UINT2NUM(sfSoundRecorder_getSampleRate(Get_SoundRecorder_Struct(self)));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static VALUE SoundRecorder_available(VALUE klass) {
|
|
178
|
+
return BOOL2RB(sfSoundRecorder_isAvailable());
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static VALUE SoundRecorder_available_devices(VALUE klass) {
|
|
182
|
+
size_t count = 0;
|
|
183
|
+
const char *const *devices = sfSoundRecorder_getAvailableDevices(&count);
|
|
184
|
+
VALUE rb_array;
|
|
185
|
+
size_t i;
|
|
186
|
+
|
|
187
|
+
if (devices == NULL) {
|
|
188
|
+
return rb_ary_new();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
rb_array = rb_ary_new_capa((long) count);
|
|
192
|
+
|
|
193
|
+
for (i = 0; i < count; i++) {
|
|
194
|
+
rb_ary_push(rb_array, rb_str_new_cstr(devices[i]));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return rb_array;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static VALUE SoundRecorder_default_device(VALUE klass) {
|
|
201
|
+
return rb_str_new_cstr(sfSoundRecorder_getDefaultDevice());
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
static VALUE SoundRecorder_device(VALUE self) {
|
|
205
|
+
return rb_str_new_cstr(sfSoundRecorder_getDevice(Get_SoundRecorder_Struct(self)));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
static VALUE SoundRecorder_set_device(VALUE self, VALUE rb_name) {
|
|
209
|
+
return BOOL2RB(
|
|
210
|
+
sfSoundRecorder_setDevice(Get_SoundRecorder_Struct(self), StringValueCStr(rb_name)));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
static VALUE SoundRecorder_channel_count(VALUE self) {
|
|
214
|
+
return UINT2NUM(sfSoundRecorder_getChannelCount(Get_SoundRecorder_Struct(self)));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
static VALUE SoundRecorder_set_channel_count(VALUE self, VALUE rb_count) {
|
|
218
|
+
sfSoundRecorder_setChannelCount(Get_SoundRecorder_Struct(self), (unsigned int) NUM2INT(rb_count));
|
|
219
|
+
return rb_count;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
static VALUE SoundRecorder_channel_map(VALUE self) {
|
|
223
|
+
size_t count = 0;
|
|
224
|
+
sfSoundChannel *map = sfSoundRecorder_getChannelMap(Get_SoundRecorder_Struct(self), &count);
|
|
225
|
+
VALUE rb_array;
|
|
226
|
+
size_t i;
|
|
227
|
+
|
|
228
|
+
if (map == NULL) {
|
|
229
|
+
return rb_ary_new();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
rb_array = rb_ary_new_capa((long) count);
|
|
233
|
+
|
|
234
|
+
for (i = 0; i < count; i++) {
|
|
235
|
+
rb_ary_push(rb_array, ID2SYM(rb_intern(sound_channel_name(map[i]))));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return rb_array;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
void Init_SoundRecorder(VALUE rb_module) {
|
|
242
|
+
rb_cSoundRecorder = rb_define_class_under(rb_module, "SoundRecorder", rb_cObject);
|
|
243
|
+
|
|
244
|
+
rb_define_singleton_method(rb_cSoundRecorder, "new", SoundRecorder_new, 0);
|
|
245
|
+
rb_define_singleton_method(rb_cSoundRecorder, "available?", SoundRecorder_available, 0);
|
|
246
|
+
rb_define_singleton_method(rb_cSoundRecorder, "available_devices",
|
|
247
|
+
SoundRecorder_available_devices, 0);
|
|
248
|
+
rb_define_singleton_method(rb_cSoundRecorder, "default_device", SoundRecorder_default_device, 0);
|
|
249
|
+
|
|
250
|
+
rb_define_method(rb_cSoundRecorder, "start", SoundRecorder_start, 1);
|
|
251
|
+
rb_define_method(rb_cSoundRecorder, "stop", SoundRecorder_stop, 0);
|
|
252
|
+
rb_define_method(rb_cSoundRecorder, "sample_rate", SoundRecorder_sample_rate, 0);
|
|
253
|
+
rb_define_method(rb_cSoundRecorder, "device", SoundRecorder_device, 0);
|
|
254
|
+
rb_define_method(rb_cSoundRecorder, "device=", SoundRecorder_set_device, 1);
|
|
255
|
+
rb_define_method(rb_cSoundRecorder, "channel_count", SoundRecorder_channel_count, 0);
|
|
256
|
+
rb_define_method(rb_cSoundRecorder, "channel_count=", SoundRecorder_set_channel_count, 1);
|
|
257
|
+
rb_define_method(rb_cSoundRecorder, "channel_map", SoundRecorder_channel_map, 0);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
VALUE Get_Klass_SoundRecorder(void) {
|
|
261
|
+
return rb_cSoundRecorder;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
void *Get_SoundRecorder_Struct(VALUE self) {
|
|
265
|
+
SoundRecorder *ptr;
|
|
266
|
+
TypedData_Get_Struct(self, SoundRecorder, &SoundRecorder_data_type, ptr);
|
|
267
|
+
return ptr->handle;
|
|
268
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef SFML_RB_AUDIO_SOUND_RECORDER_H
|
|
2
|
+
#define SFML_RB_AUDIO_SOUND_RECORDER_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
void Init_SoundRecorder(VALUE rb_module);
|
|
9
|
+
|
|
10
|
+
VALUE Get_Klass_SoundRecorder(void);
|
|
11
|
+
|
|
12
|
+
void *Get_SoundRecorder_Struct(VALUE self);
|
|
13
|
+
|
|
14
|
+
#endif //SFML_RB_AUDIO_SOUND_RECORDER_H
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#ifndef SFML_RB_AUDIO_SOUND_SOURCE_H
|
|
2
|
+
#define SFML_RB_AUDIO_SOUND_SOURCE_H
|
|
3
|
+
|
|
4
|
+
/* Every wrapper that mixes in the SoundSource methods (Sound, Music,
|
|
5
|
+
SoundStream) starts with this prefix, so the shared method bodies in
|
|
6
|
+
sound_source.inc can reach the underlying handle and the effect-processor
|
|
7
|
+
slot through RTYPEDDATA_DATA without knowing the concrete struct. */
|
|
8
|
+
typedef struct {
|
|
9
|
+
void *handle;
|
|
10
|
+
int effect_slot;
|
|
11
|
+
} SoundSource;
|
|
12
|
+
|
|
13
|
+
#endif //SFML_RB_AUDIO_SOUND_SOURCE_H
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/* Shared method bodies for every sound source (Sound, Music, SoundStream).
|
|
2
|
+
Included from three translation units; each defines SS_FN and SS_METHOD
|
|
3
|
+
before including this file, then undefines them after. Generating concrete
|
|
4
|
+
methods per class keeps the compiler's function-pointer type checks happy,
|
|
5
|
+
which a runtime vtable of cast function pointers would not.
|
|
6
|
+
|
|
7
|
+
The wrapper structs all begin with a SoundSource prefix, so the handle and
|
|
8
|
+
the effect-processor slot are reachable without knowing the concrete type. */
|
|
9
|
+
|
|
10
|
+
#include <ruby/thread.h>
|
|
11
|
+
|
|
12
|
+
#include "audio/sound_source.h"
|
|
13
|
+
#include "audio/audio_enums.h"
|
|
14
|
+
#include "audio/effect_processor.h"
|
|
15
|
+
#include "audio/sound_source_cone.h"
|
|
16
|
+
#include "core/macros.h"
|
|
17
|
+
#include "system/time.h"
|
|
18
|
+
#include "system/vec3.h"
|
|
19
|
+
|
|
20
|
+
#define SS_HANDLE(self) (((SoundSource *) RTYPEDDATA_DATA(self))->handle)
|
|
21
|
+
#define SS_SLOT(self) (((SoundSource *) RTYPEDDATA_DATA(self))->effect_slot)
|
|
22
|
+
|
|
23
|
+
static VALUE SS_METHOD(play)(VALUE self) {
|
|
24
|
+
SS_FN(play)(SS_HANDLE(self));
|
|
25
|
+
return self;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static VALUE SS_METHOD(pause)(VALUE self) {
|
|
29
|
+
SS_FN(pause)(SS_HANDLE(self));
|
|
30
|
+
return self;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* stop() blocks until any in-flight audio-thread callback for this source
|
|
34
|
+
finishes (SFML's AudioDevice::waitForReadingComplete()). If that callback
|
|
35
|
+
is itself waiting on the foreign-thread worker (e.g. an effect processor
|
|
36
|
+
or SoundStream#on_get_data), holding the GVL here for the whole wait would
|
|
37
|
+
deadlock: worker needs the GVL, we are blocked holding it waiting for the
|
|
38
|
+
very callback the worker is servicing. Releasing the GVL around the call
|
|
39
|
+
breaks the cycle. */
|
|
40
|
+
static void *SS_METHOD(stop_without_gvl)(void *handle) {
|
|
41
|
+
SS_FN(stop)(handle);
|
|
42
|
+
return NULL;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static VALUE SS_METHOD(stop)(VALUE self) {
|
|
46
|
+
rb_thread_call_without_gvl(SS_METHOD(stop_without_gvl), SS_HANDLE(self), RUBY_UBF_IO, NULL);
|
|
47
|
+
return self;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static VALUE SS_METHOD(status)(VALUE self) {
|
|
51
|
+
return ID2SYM(rb_intern(sound_status_name(SS_FN(getStatus)(SS_HANDLE(self)))));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static VALUE SS_METHOD(looping)(VALUE self) {
|
|
55
|
+
return BOOL2RB(SS_FN(isLooping)(SS_HANDLE(self)));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static VALUE SS_METHOD(set_looping)(VALUE self, VALUE rb_value) {
|
|
59
|
+
SS_FN(setLooping)(SS_HANDLE(self), RTEST(rb_value));
|
|
60
|
+
return rb_value;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static VALUE SS_METHOD(pitch)(VALUE self) {
|
|
64
|
+
return DBL2NUM(SS_FN(getPitch)(SS_HANDLE(self)));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static VALUE SS_METHOD(set_pitch)(VALUE self, VALUE rb_value) {
|
|
68
|
+
SS_FN(setPitch)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
69
|
+
return rb_value;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static VALUE SS_METHOD(pan)(VALUE self) {
|
|
73
|
+
return DBL2NUM(SS_FN(getPan)(SS_HANDLE(self)));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static VALUE SS_METHOD(set_pan)(VALUE self, VALUE rb_value) {
|
|
77
|
+
SS_FN(setPan)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
78
|
+
return rb_value;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static VALUE SS_METHOD(volume)(VALUE self) {
|
|
82
|
+
return DBL2NUM(SS_FN(getVolume)(SS_HANDLE(self)));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static VALUE SS_METHOD(set_volume)(VALUE self, VALUE rb_value) {
|
|
86
|
+
SS_FN(setVolume)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
87
|
+
return rb_value;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static VALUE SS_METHOD(spatialization_enabled)(VALUE self) {
|
|
91
|
+
return BOOL2RB(SS_FN(isSpatializationEnabled)(SS_HANDLE(self)));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static VALUE SS_METHOD(set_spatialization_enabled)(VALUE self, VALUE rb_value) {
|
|
95
|
+
SS_FN(setSpatializationEnabled)(SS_HANDLE(self), RTEST(rb_value));
|
|
96
|
+
return rb_value;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static VALUE SS_METHOD(position)(VALUE self) {
|
|
100
|
+
return vec3f_to_rb(SS_FN(getPosition)(SS_HANDLE(self)));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static VALUE SS_METHOD(set_position)(VALUE self, VALUE rb_value) {
|
|
104
|
+
SS_FN(setPosition)(SS_HANDLE(self), vec3f_from_rb(rb_value));
|
|
105
|
+
return rb_value;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static VALUE SS_METHOD(direction)(VALUE self) {
|
|
109
|
+
return vec3f_to_rb(SS_FN(getDirection)(SS_HANDLE(self)));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static VALUE SS_METHOD(set_direction)(VALUE self, VALUE rb_value) {
|
|
113
|
+
SS_FN(setDirection)(SS_HANDLE(self), vec3f_from_rb(rb_value));
|
|
114
|
+
return rb_value;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static VALUE SS_METHOD(velocity)(VALUE self) {
|
|
118
|
+
return vec3f_to_rb(SS_FN(getVelocity)(SS_HANDLE(self)));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static VALUE SS_METHOD(set_velocity)(VALUE self, VALUE rb_value) {
|
|
122
|
+
SS_FN(setVelocity)(SS_HANDLE(self), vec3f_from_rb(rb_value));
|
|
123
|
+
return rb_value;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static VALUE SS_METHOD(cone)(VALUE self) {
|
|
127
|
+
return sound_source_cone_to_rb(SS_FN(getCone)(SS_HANDLE(self)));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static VALUE SS_METHOD(set_cone)(VALUE self, VALUE rb_value) {
|
|
131
|
+
SS_FN(setCone)(SS_HANDLE(self), sound_source_cone_from_rb(rb_value));
|
|
132
|
+
return rb_value;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static VALUE SS_METHOD(doppler_factor)(VALUE self) {
|
|
136
|
+
return DBL2NUM(SS_FN(getDopplerFactor)(SS_HANDLE(self)));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static VALUE SS_METHOD(set_doppler_factor)(VALUE self, VALUE rb_value) {
|
|
140
|
+
SS_FN(setDopplerFactor)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
141
|
+
return rb_value;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static VALUE SS_METHOD(directional_attenuation_factor)(VALUE self) {
|
|
145
|
+
return DBL2NUM(SS_FN(getDirectionalAttenuationFactor)(SS_HANDLE(self)));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
static VALUE SS_METHOD(set_directional_attenuation_factor)(VALUE self, VALUE rb_value) {
|
|
149
|
+
SS_FN(setDirectionalAttenuationFactor)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
150
|
+
return rb_value;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static VALUE SS_METHOD(relative_to_listener)(VALUE self) {
|
|
154
|
+
return BOOL2RB(SS_FN(isRelativeToListener)(SS_HANDLE(self)));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static VALUE SS_METHOD(set_relative_to_listener)(VALUE self, VALUE rb_value) {
|
|
158
|
+
SS_FN(setRelativeToListener)(SS_HANDLE(self), RTEST(rb_value));
|
|
159
|
+
return rb_value;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static VALUE SS_METHOD(min_distance)(VALUE self) {
|
|
163
|
+
return DBL2NUM(SS_FN(getMinDistance)(SS_HANDLE(self)));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
static VALUE SS_METHOD(set_min_distance)(VALUE self, VALUE rb_value) {
|
|
167
|
+
SS_FN(setMinDistance)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
168
|
+
return rb_value;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static VALUE SS_METHOD(max_distance)(VALUE self) {
|
|
172
|
+
return DBL2NUM(SS_FN(getMaxDistance)(SS_HANDLE(self)));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
static VALUE SS_METHOD(set_max_distance)(VALUE self, VALUE rb_value) {
|
|
176
|
+
SS_FN(setMaxDistance)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
177
|
+
return rb_value;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
static VALUE SS_METHOD(min_gain)(VALUE self) {
|
|
181
|
+
return DBL2NUM(SS_FN(getMinGain)(SS_HANDLE(self)));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
static VALUE SS_METHOD(set_min_gain)(VALUE self, VALUE rb_value) {
|
|
185
|
+
SS_FN(setMinGain)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
186
|
+
return rb_value;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
static VALUE SS_METHOD(max_gain)(VALUE self) {
|
|
190
|
+
return DBL2NUM(SS_FN(getMaxGain)(SS_HANDLE(self)));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
static VALUE SS_METHOD(set_max_gain)(VALUE self, VALUE rb_value) {
|
|
194
|
+
SS_FN(setMaxGain)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
195
|
+
return rb_value;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
static VALUE SS_METHOD(attenuation)(VALUE self) {
|
|
199
|
+
return DBL2NUM(SS_FN(getAttenuation)(SS_HANDLE(self)));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static VALUE SS_METHOD(set_attenuation)(VALUE self, VALUE rb_value) {
|
|
203
|
+
SS_FN(setAttenuation)(SS_HANDLE(self), (float) NUM2DBL(rb_value));
|
|
204
|
+
return rb_value;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static VALUE SS_METHOD(playing_offset)(VALUE self) {
|
|
208
|
+
return time_to_rb(SS_FN(getPlayingOffset)(SS_HANDLE(self)));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static VALUE SS_METHOD(set_playing_offset)(VALUE self, VALUE rb_value) {
|
|
212
|
+
SS_FN(setPlayingOffset)(SS_HANDLE(self), time_from_rb(rb_value));
|
|
213
|
+
return rb_value;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
static VALUE SS_METHOD(set_effect_processor)(VALUE self, VALUE rb_proc) {
|
|
217
|
+
sfEffectProcessor processor = effect_processor_acquire(rb_proc, &SS_SLOT(self));
|
|
218
|
+
|
|
219
|
+
SS_FN(setEffectProcessor)(SS_HANDLE(self), processor);
|
|
220
|
+
|
|
221
|
+
return rb_proc;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static void SS_METHOD(define_sound_source_methods)(VALUE klass) {
|
|
225
|
+
rb_define_method(klass, "play", SS_METHOD(play), 0);
|
|
226
|
+
rb_define_method(klass, "pause", SS_METHOD(pause), 0);
|
|
227
|
+
rb_define_method(klass, "stop", SS_METHOD(stop), 0);
|
|
228
|
+
rb_define_method(klass, "status", SS_METHOD(status), 0);
|
|
229
|
+
rb_define_method(klass, "looping?", SS_METHOD(looping), 0);
|
|
230
|
+
rb_define_method(klass, "looping=", SS_METHOD(set_looping), 1);
|
|
231
|
+
rb_define_method(klass, "pitch", SS_METHOD(pitch), 0);
|
|
232
|
+
rb_define_method(klass, "pitch=", SS_METHOD(set_pitch), 1);
|
|
233
|
+
rb_define_method(klass, "pan", SS_METHOD(pan), 0);
|
|
234
|
+
rb_define_method(klass, "pan=", SS_METHOD(set_pan), 1);
|
|
235
|
+
rb_define_method(klass, "volume", SS_METHOD(volume), 0);
|
|
236
|
+
rb_define_method(klass, "volume=", SS_METHOD(set_volume), 1);
|
|
237
|
+
rb_define_method(klass, "spatialization_enabled?", SS_METHOD(spatialization_enabled), 0);
|
|
238
|
+
rb_define_method(klass, "spatialization_enabled=", SS_METHOD(set_spatialization_enabled), 1);
|
|
239
|
+
rb_define_method(klass, "position", SS_METHOD(position), 0);
|
|
240
|
+
rb_define_method(klass, "position=", SS_METHOD(set_position), 1);
|
|
241
|
+
rb_define_method(klass, "direction", SS_METHOD(direction), 0);
|
|
242
|
+
rb_define_method(klass, "direction=", SS_METHOD(set_direction), 1);
|
|
243
|
+
rb_define_method(klass, "velocity", SS_METHOD(velocity), 0);
|
|
244
|
+
rb_define_method(klass, "velocity=", SS_METHOD(set_velocity), 1);
|
|
245
|
+
rb_define_method(klass, "cone", SS_METHOD(cone), 0);
|
|
246
|
+
rb_define_method(klass, "cone=", SS_METHOD(set_cone), 1);
|
|
247
|
+
rb_define_method(klass, "doppler_factor", SS_METHOD(doppler_factor), 0);
|
|
248
|
+
rb_define_method(klass, "doppler_factor=", SS_METHOD(set_doppler_factor), 1);
|
|
249
|
+
rb_define_method(klass, "directional_attenuation_factor",
|
|
250
|
+
SS_METHOD(directional_attenuation_factor), 0);
|
|
251
|
+
rb_define_method(klass, "directional_attenuation_factor=",
|
|
252
|
+
SS_METHOD(set_directional_attenuation_factor), 1);
|
|
253
|
+
rb_define_method(klass, "relative_to_listener?", SS_METHOD(relative_to_listener), 0);
|
|
254
|
+
rb_define_method(klass, "relative_to_listener=", SS_METHOD(set_relative_to_listener), 1);
|
|
255
|
+
rb_define_method(klass, "min_distance", SS_METHOD(min_distance), 0);
|
|
256
|
+
rb_define_method(klass, "min_distance=", SS_METHOD(set_min_distance), 1);
|
|
257
|
+
rb_define_method(klass, "max_distance", SS_METHOD(max_distance), 0);
|
|
258
|
+
rb_define_method(klass, "max_distance=", SS_METHOD(set_max_distance), 1);
|
|
259
|
+
rb_define_method(klass, "min_gain", SS_METHOD(min_gain), 0);
|
|
260
|
+
rb_define_method(klass, "min_gain=", SS_METHOD(set_min_gain), 1);
|
|
261
|
+
rb_define_method(klass, "max_gain", SS_METHOD(max_gain), 0);
|
|
262
|
+
rb_define_method(klass, "max_gain=", SS_METHOD(set_max_gain), 1);
|
|
263
|
+
rb_define_method(klass, "attenuation", SS_METHOD(attenuation), 0);
|
|
264
|
+
rb_define_method(klass, "attenuation=", SS_METHOD(set_attenuation), 1);
|
|
265
|
+
rb_define_method(klass, "playing_offset", SS_METHOD(playing_offset), 0);
|
|
266
|
+
rb_define_method(klass, "playing_offset=", SS_METHOD(set_playing_offset), 1);
|
|
267
|
+
rb_define_method(klass, "effect_processor=", SS_METHOD(set_effect_processor), 1);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
#undef SS_HANDLE
|
|
271
|
+
#undef SS_SLOT
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#include "audio/sound_source_cone.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
#include <stdlib.h>
|
|
5
|
+
|
|
6
|
+
#include "core/exceptions.h"
|
|
7
|
+
#include "core/macros.h"
|
|
8
|
+
|
|
9
|
+
typedef struct {
|
|
10
|
+
sfSoundSourceCone cone;
|
|
11
|
+
} SoundSourceCone;
|
|
12
|
+
|
|
13
|
+
static VALUE rb_cSoundSourceCone;
|
|
14
|
+
|
|
15
|
+
static void SoundSourceCone_free(void *ptr) {
|
|
16
|
+
free(ptr);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static const rb_data_type_t SoundSourceCone_data_type = {
|
|
20
|
+
.wrap_struct_name = "SFML::SoundSourceCone",
|
|
21
|
+
.function = {.dmark = NULL, .dfree = SoundSourceCone_free, .dsize = NULL},
|
|
22
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
static VALUE SoundSourceCone_wrap(sfSoundSourceCone cone) {
|
|
26
|
+
SoundSourceCone *ptr = malloc(sizeof(SoundSourceCone));
|
|
27
|
+
|
|
28
|
+
ptr->cone = cone;
|
|
29
|
+
|
|
30
|
+
return TypedData_Wrap_Struct(rb_cSoundSourceCone, &SoundSourceCone_data_type, ptr);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static VALUE SoundSourceCone_new(VALUE klass, VALUE rb_inner, VALUE rb_outer, VALUE rb_gain) {
|
|
34
|
+
sfSoundSourceCone cone = {
|
|
35
|
+
.innerAngle = (float) NUM2DBL(rb_inner),
|
|
36
|
+
.outerAngle = (float) NUM2DBL(rb_outer),
|
|
37
|
+
.outerGain = (float) NUM2DBL(rb_gain)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return SoundSourceCone_wrap(cone);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static VALUE SoundSourceCone_get_inner_angle(VALUE self) {
|
|
44
|
+
return DBL2NUM(((SoundSourceCone *) Get_SoundSourceCone_Struct(self))->cone.innerAngle);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static VALUE SoundSourceCone_get_outer_angle(VALUE self) {
|
|
48
|
+
return DBL2NUM(((SoundSourceCone *) Get_SoundSourceCone_Struct(self))->cone.outerAngle);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static VALUE SoundSourceCone_get_outer_gain(VALUE self) {
|
|
52
|
+
return DBL2NUM(((SoundSourceCone *) Get_SoundSourceCone_Struct(self))->cone.outerGain);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static VALUE SoundSourceCone_set_inner_angle(VALUE self, VALUE rb_value) {
|
|
56
|
+
((SoundSourceCone *) Get_SoundSourceCone_Struct(self))->cone.innerAngle = (float) NUM2DBL(rb_value);
|
|
57
|
+
return rb_value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static VALUE SoundSourceCone_set_outer_angle(VALUE self, VALUE rb_value) {
|
|
61
|
+
((SoundSourceCone *) Get_SoundSourceCone_Struct(self))->cone.outerAngle = (float) NUM2DBL(rb_value);
|
|
62
|
+
return rb_value;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static VALUE SoundSourceCone_set_outer_gain(VALUE self, VALUE rb_value) {
|
|
66
|
+
((SoundSourceCone *) Get_SoundSourceCone_Struct(self))->cone.outerGain = (float) NUM2DBL(rb_value);
|
|
67
|
+
return rb_value;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static VALUE SoundSourceCone_to_a(VALUE self) {
|
|
71
|
+
sfSoundSourceCone cone = ((SoundSourceCone *) Get_SoundSourceCone_Struct(self))->cone;
|
|
72
|
+
|
|
73
|
+
return rb_ary_new_from_args(3, DBL2NUM(cone.innerAngle), DBL2NUM(cone.outerAngle),
|
|
74
|
+
DBL2NUM(cone.outerGain));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static VALUE SoundSourceCone_eql(VALUE self, VALUE rb_other) {
|
|
78
|
+
sfSoundSourceCone a = ((SoundSourceCone *) Get_SoundSourceCone_Struct(self))->cone;
|
|
79
|
+
sfSoundSourceCone b;
|
|
80
|
+
|
|
81
|
+
if (!rb_obj_is_kind_of(rb_other, rb_cSoundSourceCone)) {
|
|
82
|
+
return Qfalse;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
b = ((SoundSourceCone *) Get_SoundSourceCone_Struct(rb_other))->cone;
|
|
86
|
+
|
|
87
|
+
return BOOL2RB(a.innerAngle == b.innerAngle && a.outerAngle == b.outerAngle &&
|
|
88
|
+
a.outerGain == b.outerGain);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void Init_SoundSourceCone(VALUE rb_module) {
|
|
92
|
+
rb_cSoundSourceCone = rb_define_class_under(rb_module, "SoundSourceCone", rb_cObject);
|
|
93
|
+
|
|
94
|
+
rb_define_singleton_method(rb_cSoundSourceCone, "new", SoundSourceCone_new, 3);
|
|
95
|
+
|
|
96
|
+
rb_define_method(rb_cSoundSourceCone, "inner_angle", SoundSourceCone_get_inner_angle, 0);
|
|
97
|
+
rb_define_method(rb_cSoundSourceCone, "outer_angle", SoundSourceCone_get_outer_angle, 0);
|
|
98
|
+
rb_define_method(rb_cSoundSourceCone, "outer_gain", SoundSourceCone_get_outer_gain, 0);
|
|
99
|
+
rb_define_method(rb_cSoundSourceCone, "inner_angle=", SoundSourceCone_set_inner_angle, 1);
|
|
100
|
+
rb_define_method(rb_cSoundSourceCone, "outer_angle=", SoundSourceCone_set_outer_angle, 1);
|
|
101
|
+
rb_define_method(rb_cSoundSourceCone, "outer_gain=", SoundSourceCone_set_outer_gain, 1);
|
|
102
|
+
rb_define_method(rb_cSoundSourceCone, "to_a", SoundSourceCone_to_a, 0);
|
|
103
|
+
rb_define_method(rb_cSoundSourceCone, "==", SoundSourceCone_eql, 1);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
VALUE Get_Klass_SoundSourceCone(void) {
|
|
107
|
+
return rb_cSoundSourceCone;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
void *Get_SoundSourceCone_Struct(VALUE self) {
|
|
111
|
+
SoundSourceCone *ptr;
|
|
112
|
+
TypedData_Get_Struct(self, SoundSourceCone, &SoundSourceCone_data_type, ptr);
|
|
113
|
+
return ptr;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
sfSoundSourceCone sound_source_cone_from_rb(VALUE rb_cone) {
|
|
117
|
+
if (rb_obj_is_kind_of(rb_cone, rb_cSoundSourceCone)) {
|
|
118
|
+
return ((SoundSourceCone *) Get_SoundSourceCone_Struct(rb_cone))->cone;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (RB_TYPE_P(rb_cone, T_ARRAY) && RARRAY_LEN(rb_cone) == 3) {
|
|
122
|
+
sfSoundSourceCone cone = {
|
|
123
|
+
.innerAngle = (float) NUM2DBL(rb_ary_entry(rb_cone, 0)),
|
|
124
|
+
.outerAngle = (float) NUM2DBL(rb_ary_entry(rb_cone, 1)),
|
|
125
|
+
.outerGain = (float) NUM2DBL(rb_ary_entry(rb_cone, 2))
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return cone;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
raise_invalid_argument_class(rb_cSoundSourceCone);
|
|
132
|
+
|
|
133
|
+
return (sfSoundSourceCone) {0.0f, 0.0f, 0.0f};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
VALUE sound_source_cone_to_rb(sfSoundSourceCone cone) {
|
|
137
|
+
return SoundSourceCone_wrap(cone);
|
|
138
|
+
}
|