rsox 0.0.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.
- data/README.md +57 -0
- data/ext/extconf.rb +38 -0
- data/ext/rsox.c +441 -0
- data/setup.rb +1585 -0
- data/spec/effect_spec.rb +63 -0
- data/spec/general_spec.rb +44 -0
- metadata +69 -0
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
## RSox is a libSoX binding for Ruby
|
2
|
+
|
3
|
+
---
|
4
|
+
|
5
|
+
### Usage
|
6
|
+
|
7
|
+
rewritten `example0.c` from [sox](http://sox.sourceforge.net/)
|
8
|
+
|
9
|
+
require 'rsox'
|
10
|
+
|
11
|
+
sox = RSox.new
|
12
|
+
|
13
|
+
input = sox.open_read 'file.mp3'
|
14
|
+
output = sox.open_write 'file.wav', input.signal
|
15
|
+
|
16
|
+
chain = sox.chain input, output
|
17
|
+
chain.add 'input', input
|
18
|
+
chain.add 'vol', '3dB'
|
19
|
+
chain.add 'flanger'
|
20
|
+
chain.add 'output', output
|
21
|
+
|
22
|
+
chain.flow
|
23
|
+
|
24
|
+
processing samples in Ruby
|
25
|
+
|
26
|
+
require 'rsox'
|
27
|
+
|
28
|
+
sox = RSox.new
|
29
|
+
|
30
|
+
input = sox.open_read 'file.mp3'
|
31
|
+
output = sox.open_write 'file.wav', input.signal
|
32
|
+
|
33
|
+
chain = sox.chain input, output
|
34
|
+
chain.add 'input', input
|
35
|
+
chain.add 'vol', '3dB'
|
36
|
+
chain.add 'flanger'
|
37
|
+
chain.add 'block' do |buffer|
|
38
|
+
# samples in buffer
|
39
|
+
buffer.size # or buffer.length
|
40
|
+
|
41
|
+
# access samples
|
42
|
+
buffer[0] # or buffer.at(0)
|
43
|
+
buffer[buffer.size-1] # last sample
|
44
|
+
|
45
|
+
# each sample is a 32bit signed integer converted to Fixnum
|
46
|
+
buffer[0].class == Fixnum
|
47
|
+
end
|
48
|
+
|
49
|
+
# all output data will be passed to `block` effect
|
50
|
+
# and processed by Ruby code block
|
51
|
+
chain.flow
|
52
|
+
|
53
|
+
---
|
54
|
+
|
55
|
+
### Thanks
|
56
|
+
|
57
|
+
[Roman Golomidov](https://github.com/golomidov) for idea and support
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
LIBDIR = Config::CONFIG['libdir']
|
4
|
+
INCLUDEDIR = Config::CONFIG['includedir']
|
5
|
+
|
6
|
+
HEADER_DIRS = [
|
7
|
+
# First search /opt/local for macports
|
8
|
+
'/opt/local/include',
|
9
|
+
|
10
|
+
# Then search /usr/local for people that installed from source
|
11
|
+
'/usr/local/include',
|
12
|
+
|
13
|
+
# Check the ruby install locations
|
14
|
+
INCLUDEDIR,
|
15
|
+
|
16
|
+
# Finally fall back to /usr
|
17
|
+
'/usr/include',
|
18
|
+
]
|
19
|
+
|
20
|
+
LIB_DIRS = [
|
21
|
+
# First search /opt/local for macports
|
22
|
+
'/opt/local/lib',
|
23
|
+
|
24
|
+
# Then search /usr/local for people that installed from source
|
25
|
+
'/usr/local/lib',
|
26
|
+
|
27
|
+
# Check the ruby install locations
|
28
|
+
LIBDIR,
|
29
|
+
|
30
|
+
# Finally fall back to /usr
|
31
|
+
'/usr/lib',
|
32
|
+
]
|
33
|
+
|
34
|
+
dir_config('rsox', HEADER_DIRS, LIB_DIRS)
|
35
|
+
|
36
|
+
if have_library("sox", "sox_format_init") && have_header("sox.h")
|
37
|
+
create_makefile('rsox')
|
38
|
+
end
|
data/ext/rsox.c
ADDED
@@ -0,0 +1,441 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <sox.h>
|
3
|
+
|
4
|
+
static VALUE RSox;
|
5
|
+
|
6
|
+
static VALUE RSoxFormat;
|
7
|
+
static VALUE RSoxEffect;
|
8
|
+
static VALUE RSoxEffectsChain;
|
9
|
+
static VALUE RSoxSignal;
|
10
|
+
static VALUE RSoxEncoding;
|
11
|
+
static VALUE RSoxBuffer;
|
12
|
+
|
13
|
+
static void rsox_destroy(void *instance) {/*{{{*/
|
14
|
+
int *instance_count;
|
15
|
+
|
16
|
+
instance_count = (int*)instance;
|
17
|
+
*instance_count -= 1;
|
18
|
+
if (*instance_count == 0)
|
19
|
+
sox_quit();
|
20
|
+
rb_iv_set(RSox, "@instance_count", INT2NUM(*instance_count));
|
21
|
+
}/*}}}*/
|
22
|
+
|
23
|
+
VALUE rsox_new(VALUE class) {/*{{{*/
|
24
|
+
static int rsox_instance_count = 0;
|
25
|
+
VALUE instance_num;
|
26
|
+
|
27
|
+
rsox_instance_count++;
|
28
|
+
instance_num = Data_Wrap_Struct(RSox, 0, rsox_destroy, &rsox_instance_count);
|
29
|
+
|
30
|
+
rb_iv_set(class, "@instance_count", INT2NUM(rsox_instance_count));
|
31
|
+
rb_obj_call_init(instance_num, 0, 0);
|
32
|
+
|
33
|
+
return instance_num;
|
34
|
+
}/*}}}*/
|
35
|
+
|
36
|
+
VALUE rsox_count(VALUE class) {/*{{{*/
|
37
|
+
return rb_iv_get(class, "@count");
|
38
|
+
}/*}}}*/
|
39
|
+
|
40
|
+
VALUE rsox_initialize(VALUE self) {/*{{{*/
|
41
|
+
int *instance_count;
|
42
|
+
|
43
|
+
Data_Get_Struct(self, int, instance_count);
|
44
|
+
if (*instance_count == 1)
|
45
|
+
sox_init();
|
46
|
+
|
47
|
+
return self;
|
48
|
+
}/*}}}*/
|
49
|
+
|
50
|
+
VALUE rsox_set_bufsize(VALUE self, VALUE bufsize) {
|
51
|
+
sox_globals.bufsiz = FIX2INT(bufsize);
|
52
|
+
|
53
|
+
return Qtrue;
|
54
|
+
}
|
55
|
+
|
56
|
+
VALUE rsox_get_bufsize(VALUE self) {
|
57
|
+
return INT2FIX(sox_globals.bufsiz);
|
58
|
+
}
|
59
|
+
|
60
|
+
VALUE rsox_format_init(VALUE self) {/*{{{*/
|
61
|
+
int i = sox_format_init();
|
62
|
+
return INT2NUM(i);
|
63
|
+
}/*}}}*/
|
64
|
+
|
65
|
+
VALUE rsox_format_quit(VALUE self) {/*{{{*/
|
66
|
+
sox_format_quit();
|
67
|
+
return Qnil;
|
68
|
+
}/*}}}*/
|
69
|
+
|
70
|
+
static void rsox_format_close(void *ptr) {/*{{{*/
|
71
|
+
sox_close(ptr);
|
72
|
+
}/*}}}*/
|
73
|
+
|
74
|
+
VALUE rsox_open_read(int argc, VALUE *argv, VALUE self) {/*{{{*/
|
75
|
+
VALUE path, signal, encoding, filetype;
|
76
|
+
sox_signalinfo_t *c_signal = NULL;
|
77
|
+
sox_encodinginfo_t *c_encoding = NULL;
|
78
|
+
sox_format_t *c_format;
|
79
|
+
|
80
|
+
rb_scan_args(argc, argv, "13", &path, &signal, &encoding, &filetype);
|
81
|
+
|
82
|
+
if (!NIL_P(signal)) Data_Get_Struct(signal, sox_signalinfo_t, c_signal);
|
83
|
+
if (!NIL_P(encoding)) Data_Get_Struct(encoding, sox_encodinginfo_t, c_encoding);
|
84
|
+
|
85
|
+
c_format = sox_open_read(StringValuePtr(path), c_signal, c_encoding, filetype == Qnil ? NULL : StringValuePtr(filetype));
|
86
|
+
|
87
|
+
return Data_Wrap_Struct(RSoxFormat, 0, rsox_format_close, c_format);
|
88
|
+
}/*}}}*/
|
89
|
+
|
90
|
+
sox_bool rsox_overwrite_callback(const char *filename) {/*{{{*/
|
91
|
+
return sox_false;
|
92
|
+
}/*}}}*/
|
93
|
+
|
94
|
+
VALUE rsox_open_write(int argc, VALUE *argv, VALUE self) {/*{{{*/
|
95
|
+
VALUE path, signal, encoding, filetype, oob;
|
96
|
+
sox_signalinfo_t *c_signal = NULL;
|
97
|
+
sox_encodinginfo_t *c_encoding = NULL;
|
98
|
+
sox_oob_t *c_oob = NULL;
|
99
|
+
sox_format_t *c_format;
|
100
|
+
|
101
|
+
rb_scan_args(argc, argv, "14", &path, &signal, &encoding, &filetype, &oob);
|
102
|
+
|
103
|
+
if (signal != Qnil) Data_Get_Struct(signal, sox_signalinfo_t, c_signal);
|
104
|
+
if (encoding != Qnil) Data_Get_Struct(encoding, sox_encodinginfo_t, c_encoding);
|
105
|
+
if (oob != Qnil) Data_Get_Struct(oob, sox_oob_t, c_oob);
|
106
|
+
|
107
|
+
c_format = sox_open_write(StringValuePtr(path),
|
108
|
+
c_signal,
|
109
|
+
c_encoding,
|
110
|
+
filetype == Qnil ? NULL : StringValuePtr(filetype),
|
111
|
+
c_oob,
|
112
|
+
rb_block_given_p() ? rsox_overwrite_callback : NULL);
|
113
|
+
|
114
|
+
return Data_Wrap_Struct(RSoxFormat, 0, 0, c_format);
|
115
|
+
}/*}}}*/
|
116
|
+
|
117
|
+
VALUE rsoxformat_signal(VALUE self) {/*{{{*/
|
118
|
+
sox_format_t *c_format;
|
119
|
+
sox_signalinfo_t *c_info;
|
120
|
+
|
121
|
+
Data_Get_Struct(self, sox_format_t, c_format);
|
122
|
+
|
123
|
+
return Data_Wrap_Struct(RSoxSignal, 0, 0, &c_format->signal);
|
124
|
+
}/*}}}*/
|
125
|
+
|
126
|
+
VALUE rsoxsignal_rate(VALUE self) {/*{{{*/
|
127
|
+
sox_signalinfo_t *c;
|
128
|
+
|
129
|
+
Data_Get_Struct(self, sox_signalinfo_t, c);
|
130
|
+
|
131
|
+
return DBL2NUM(c->rate);
|
132
|
+
}/*}}}*/
|
133
|
+
|
134
|
+
VALUE rsoxsignal_rate_set(VALUE self, VALUE rate) {/*{{{*/
|
135
|
+
sox_signalinfo_t *c;
|
136
|
+
double val = NUM2DBL(rate);
|
137
|
+
|
138
|
+
Data_Get_Struct(self, sox_signalinfo_t, c);
|
139
|
+
c->rate = val;
|
140
|
+
|
141
|
+
return rate;
|
142
|
+
}/*}}}*/
|
143
|
+
|
144
|
+
VALUE rsoxsignal_channels(VALUE self) {/*{{{*/
|
145
|
+
sox_signalinfo_t *c_signal;
|
146
|
+
|
147
|
+
Data_Get_Struct(self, sox_signalinfo_t, c_signal);
|
148
|
+
|
149
|
+
return UINT2NUM(c_signal->channels);
|
150
|
+
}/*}}}*/
|
151
|
+
|
152
|
+
VALUE rsoxsignal_channels_set(VALUE self, VALUE channels) {/*{{{*/
|
153
|
+
sox_signalinfo_t *c_signal;
|
154
|
+
unsigned int val = NUM2UINT(channels);
|
155
|
+
|
156
|
+
Data_Get_Struct(self, sox_signalinfo_t, c_signal);
|
157
|
+
c_signal->channels = val;
|
158
|
+
|
159
|
+
return channels;
|
160
|
+
}/*}}}*/
|
161
|
+
|
162
|
+
VALUE rsoxsignal_bits(VALUE self) {/*{{{*/
|
163
|
+
sox_signalinfo_t *c_signal;
|
164
|
+
|
165
|
+
Data_Get_Struct(self, sox_signalinfo_t, c_signal);
|
166
|
+
|
167
|
+
return UINT2NUM(c_signal->precision);
|
168
|
+
}/*}}}*/
|
169
|
+
|
170
|
+
VALUE rsoxsignal_bits_set(VALUE self, VALUE bits) {/*{{{*/
|
171
|
+
sox_signalinfo_t *c_signal;
|
172
|
+
unsigned int val = NUM2UINT(bits);
|
173
|
+
|
174
|
+
Data_Get_Struct(self, sox_signalinfo_t, c_signal);
|
175
|
+
c_signal->precision = val;
|
176
|
+
|
177
|
+
return bits;
|
178
|
+
}/*}}}*/
|
179
|
+
|
180
|
+
VALUE rsoxformat_encoding(VALUE self) {/*{{{*/
|
181
|
+
sox_format_t *c_format;
|
182
|
+
|
183
|
+
Data_Get_Struct(self, sox_format_t, c_format);
|
184
|
+
|
185
|
+
return Data_Wrap_Struct(RSoxEncoding, 0, 0, &c_format->encoding);
|
186
|
+
}/*}}}*/
|
187
|
+
|
188
|
+
VALUE rsoxformat_filename(VALUE self) {/*{{{*/
|
189
|
+
sox_format_t *c_format;
|
190
|
+
|
191
|
+
Data_Get_Struct(self, sox_format_t, c_format);
|
192
|
+
|
193
|
+
return rb_str_new2(c_format->filename);
|
194
|
+
}/*}}}*/
|
195
|
+
|
196
|
+
VALUE rsoxformat_read(VALUE self, VALUE buffer) { //, VALUE length) {/*{{{*/
|
197
|
+
sox_format_t *c_format;
|
198
|
+
sox_sample_t *c_buffer;
|
199
|
+
|
200
|
+
Data_Get_Struct(self, sox_format_t, c_format);
|
201
|
+
Data_Get_Struct(rb_iv_get(buffer, "@buffer"), sox_sample_t, c_buffer);
|
202
|
+
|
203
|
+
return INT2NUM(sox_read(c_format, c_buffer, NUM2INT(rb_iv_get(buffer, "@length"))));
|
204
|
+
}/*}}}*/
|
205
|
+
|
206
|
+
VALUE rsoxformat_write(VALUE self, VALUE buffer, VALUE length) {/*{{{*/
|
207
|
+
sox_format_t *c_format;
|
208
|
+
sox_sample_t *c_buffer;
|
209
|
+
int write_len = NUM2INT(length == Qnil ? rb_iv_get(buffer, "@length") : length);
|
210
|
+
|
211
|
+
Data_Get_Struct(self, sox_format_t, c_format);
|
212
|
+
Data_Get_Struct(rb_iv_get(buffer, "@buffer"), sox_sample_t, c_buffer);
|
213
|
+
|
214
|
+
return INT2NUM(sox_write(c_format, c_buffer, write_len));
|
215
|
+
}/*}}}*/
|
216
|
+
|
217
|
+
VALUE rsoxformat_seek(VALUE self, VALUE offset, VALUE whence){/*{{{*/
|
218
|
+
sox_format_t *c_format;
|
219
|
+
|
220
|
+
Data_Get_Struct(self, sox_format_t, c_format);
|
221
|
+
|
222
|
+
return INT2NUM(sox_seek(c_format, NUM2LONG(offset), NUM2INT(whence)));
|
223
|
+
}/*}}}*/
|
224
|
+
|
225
|
+
typedef struct {/*{{{ rsox_block_with_id_t */
|
226
|
+
VALUE block;
|
227
|
+
ID func;
|
228
|
+
} rsox_block_with_id_t;/*}}}*/
|
229
|
+
|
230
|
+
static int rsox_rubyblock_flow(sox_effect_t *effect, sox_sample_t const *ibuf, sox_sample_t *obuf UNUSED, size_t *isamp, size_t *osamp) {/*{{{*/
|
231
|
+
size_t i;
|
232
|
+
rsox_block_with_id_t *param = (rsox_block_with_id_t *)effect->priv;
|
233
|
+
VALUE buffer = Data_Wrap_Struct(RSoxBuffer, 0, 0, ibuf);
|
234
|
+
rb_iv_set(buffer, "@length", INT2NUM(*isamp));
|
235
|
+
|
236
|
+
if (*isamp > 0)
|
237
|
+
rb_funcall(param->block, param->func, 1, buffer);
|
238
|
+
|
239
|
+
*osamp = 0;
|
240
|
+
|
241
|
+
return SOX_SUCCESS;
|
242
|
+
}/*}}}*/
|
243
|
+
|
244
|
+
static sox_effect_handler_t const *rsox_rubyblock_handler(void) {/*{{{*/
|
245
|
+
static sox_effect_handler_t handler = {
|
246
|
+
"block", NULL, SOX_EFF_MCHAN, NULL, NULL, rsox_rubyblock_flow, NULL, NULL, NULL, sizeof(rsox_block_with_id_t)
|
247
|
+
};
|
248
|
+
|
249
|
+
return &handler;
|
250
|
+
}/*}}}*/
|
251
|
+
|
252
|
+
VALUE rsoxeffectschain_add(int argc, VALUE *argv, VALUE self) {/*{{{*/
|
253
|
+
sox_effects_chain_t *c_chain;
|
254
|
+
sox_effect_t *c_effect;
|
255
|
+
sox_format_t *c_input, *c_output, *c_tmp_format;
|
256
|
+
VALUE name, options, tmp, input, output;
|
257
|
+
sox_effect_handler_t const *c_handler;
|
258
|
+
char *c_options[10], *c_name;
|
259
|
+
int i, j, t;
|
260
|
+
rsox_block_with_id_t *block_param;
|
261
|
+
|
262
|
+
rb_scan_args(argc, argv, "1*", &name, &options);
|
263
|
+
|
264
|
+
c_name = StringValuePtr(name);
|
265
|
+
|
266
|
+
if (strncmp(c_name, "block", 5) == 0) {
|
267
|
+
if (!rb_block_given_p())
|
268
|
+
rb_raise(rb_eArgError, "no block given");
|
269
|
+
|
270
|
+
c_handler = rsox_rubyblock_handler();
|
271
|
+
c_effect = sox_create_effect(c_handler);
|
272
|
+
|
273
|
+
block_param = (rsox_block_with_id_t *)c_effect->priv;
|
274
|
+
block_param->block = rb_block_proc();
|
275
|
+
block_param->func = rb_intern("call");
|
276
|
+
} else {
|
277
|
+
c_handler = sox_find_effect(StringValuePtr(name));
|
278
|
+
if (c_handler == NULL)
|
279
|
+
rb_raise(rb_eArgError, "no such effect: %s", StringValuePtr(name));
|
280
|
+
c_effect = sox_create_effect(c_handler);
|
281
|
+
|
282
|
+
for (i = j = 0; i < RARRAY_LEN(options); i++) {
|
283
|
+
if (TYPE(RARRAY_PTR(options)[i]) == T_DATA) {
|
284
|
+
Data_Get_Struct(RARRAY_PTR(options)[i], sox_format_t, c_tmp_format);
|
285
|
+
c_options[j++] = (char *)c_tmp_format;
|
286
|
+
} else {
|
287
|
+
tmp = rb_check_string_type(RARRAY_PTR(options)[i]);
|
288
|
+
c_options[j++] = NIL_P(tmp) ? NULL : RSTRING_PTR(tmp);
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
292
|
+
i = sox_effect_options(c_effect, j, j > 0 ? c_options : NULL);
|
293
|
+
if (i != SOX_SUCCESS)
|
294
|
+
rb_raise(rb_eArgError, "wrong arguments (%d)", j);
|
295
|
+
}
|
296
|
+
|
297
|
+
Data_Get_Struct(self, sox_effects_chain_t, c_chain);
|
298
|
+
Data_Get_Struct(rb_iv_get(self, "@input"), sox_format_t, c_input);
|
299
|
+
Data_Get_Struct(rb_iv_get(self, "@output"), sox_format_t, c_output);
|
300
|
+
|
301
|
+
i = sox_add_effect(c_chain, c_effect, &c_input->signal, &c_output->signal);
|
302
|
+
|
303
|
+
return INT2NUM(i);
|
304
|
+
}/*}}}*/
|
305
|
+
|
306
|
+
VALUE rsoxbuffer_initialize(int argc, VALUE *argv, VALUE self) {/*{{{*/
|
307
|
+
sox_sample_t *buffer;
|
308
|
+
VALUE length;
|
309
|
+
int llen;
|
310
|
+
|
311
|
+
rb_scan_args(argc, argv, "01", &length);
|
312
|
+
llen = NIL_P(length) ? 2048 : NUM2INT(length);
|
313
|
+
buffer = ALLOC_N(sox_sample_t, llen);
|
314
|
+
|
315
|
+
rb_iv_set(self, "@buffer", Data_Wrap_Struct(RSoxBuffer, 0, free, buffer));
|
316
|
+
rb_iv_set(self, "@length", INT2NUM(llen));
|
317
|
+
|
318
|
+
return self;
|
319
|
+
}/*}}}*/
|
320
|
+
|
321
|
+
VALUE rsoxbuffer_at(VALUE self, VALUE index) {
|
322
|
+
sox_sample_t *c_buffer;
|
323
|
+
|
324
|
+
if (index < rb_iv_get(self, "@length")) {
|
325
|
+
Data_Get_Struct(self, sox_sample_t, c_buffer);
|
326
|
+
return INT2NUM(c_buffer[NUM2INT(index)]);
|
327
|
+
}
|
328
|
+
|
329
|
+
return Qnil;
|
330
|
+
}
|
331
|
+
|
332
|
+
VALUE rsoxbuffer_length(VALUE self) {/*{{{*/
|
333
|
+
return rb_iv_get(self, "@length");
|
334
|
+
}/*}}}*/
|
335
|
+
|
336
|
+
VALUE rsoxbuffer_buffer(VALUE self) {/*{{{*/
|
337
|
+
return rb_iv_get(self, "@buffer");
|
338
|
+
}/*}}}*/
|
339
|
+
|
340
|
+
VALUE rsoxencoding_bps(VALUE self) {/*{{{*/
|
341
|
+
sox_encodinginfo_t *c_enc;
|
342
|
+
|
343
|
+
Data_Get_Struct(self, sox_encodinginfo_t, c_enc);
|
344
|
+
|
345
|
+
return UINT2NUM(c_enc->bits_per_sample);
|
346
|
+
}/*}}}*/
|
347
|
+
|
348
|
+
VALUE rsoxencoding_bps_set(VALUE self, VALUE bps) {/*{{{*/
|
349
|
+
sox_encodinginfo_t *c_enc;
|
350
|
+
unsigned int val = NUM2UINT(bps);
|
351
|
+
|
352
|
+
Data_Get_Struct(self, sox_encodinginfo_t, c_enc);
|
353
|
+
c_enc->bits_per_sample = val;
|
354
|
+
|
355
|
+
return bps;
|
356
|
+
}/*}}}*/
|
357
|
+
|
358
|
+
static void rsoxeffectschain_free(void *ptr) {/*{{{*/
|
359
|
+
sox_delete_effects_chain(ptr);
|
360
|
+
}/*}}}*/
|
361
|
+
|
362
|
+
VALUE rsox_effectschain(VALUE self, VALUE input, VALUE output) {/*{{{*/
|
363
|
+
sox_format_t *c_input, *c_output;
|
364
|
+
sox_effects_chain_t *c_chain;
|
365
|
+
VALUE chain;
|
366
|
+
|
367
|
+
Data_Get_Struct(input, sox_format_t, c_input);
|
368
|
+
Data_Get_Struct(output, sox_format_t, c_output);
|
369
|
+
|
370
|
+
c_chain = sox_create_effects_chain(&c_input->encoding, &c_output->encoding);
|
371
|
+
chain = Data_Wrap_Struct(RSoxEffectsChain, 0, rsoxeffectschain_free, c_chain);
|
372
|
+
rb_iv_set(chain, "@input", input);
|
373
|
+
rb_iv_set(chain, "@output", output);
|
374
|
+
|
375
|
+
rb_iv_set(self, "@chain", chain);
|
376
|
+
|
377
|
+
return chain;
|
378
|
+
}/*}}}*/
|
379
|
+
|
380
|
+
int rsoxeffectschain_flow_callback(sox_bool all_done, void *data) {/*{{{*/
|
381
|
+
return SOX_SUCCESS;
|
382
|
+
}/*}}}*/
|
383
|
+
|
384
|
+
VALUE rsoxeffectschain_flow(int argc, VALUE *argv, VALUE self) {/*{{{*/
|
385
|
+
sox_effects_chain_t *c_chain;
|
386
|
+
|
387
|
+
Data_Get_Struct(self, sox_effects_chain_t, c_chain);
|
388
|
+
|
389
|
+
return INT2NUM(sox_flow_effects(c_chain, NULL, NULL));
|
390
|
+
}/*}}}*/
|
391
|
+
|
392
|
+
void Init_rsox(void) {/*{{{*/
|
393
|
+
rb_define_global_const("SOX_SUCCESS", INT2NUM(0));
|
394
|
+
rb_define_global_const("SOX_EOF", INT2NUM(-1));
|
395
|
+
|
396
|
+
RSox = rb_define_class("RSox", rb_cObject);
|
397
|
+
rb_define_singleton_method(RSox, "new", rsox_new, 0);
|
398
|
+
rb_define_singleton_method(RSox, "count", rsox_count, 0);
|
399
|
+
rb_define_method(RSox, "initialize", rsox_initialize, 0);
|
400
|
+
rb_define_method(RSox, "format_init", rsox_format_init, 0);
|
401
|
+
rb_define_method(RSox, "format_quit", rsox_format_quit, 0);
|
402
|
+
rb_define_method(RSox, "open_read", rsox_open_read, -1);
|
403
|
+
rb_define_method(RSox, "open_write", rsox_open_write, -1);
|
404
|
+
rb_define_method(RSox, "chain", rsox_effectschain, 2);
|
405
|
+
rb_define_method(RSox, "buffer_size", rsox_get_bufsize, 0);
|
406
|
+
rb_define_method(RSox, "buffer_size=", rsox_set_bufsize, 1);
|
407
|
+
|
408
|
+
RSoxFormat = rb_define_class("RSoxFormat", rb_cObject);
|
409
|
+
rb_define_method(RSoxFormat, "signal", rsoxformat_signal, 0);
|
410
|
+
rb_define_method(RSoxFormat, "encoding", rsoxformat_encoding, 0);
|
411
|
+
rb_define_method(RSoxFormat, "filename", rsoxformat_filename, 0);
|
412
|
+
rb_define_method(RSoxFormat, "read", rsoxformat_read, 1);
|
413
|
+
rb_define_method(RSoxFormat, "write", rsoxformat_write, 2);
|
414
|
+
rb_define_method(RSoxFormat, "seek", rsoxformat_seek, 2);
|
415
|
+
|
416
|
+
RSoxBuffer = rb_define_class("RSoxBuffer", rb_cObject);
|
417
|
+
rb_define_method(RSoxBuffer, "initialize", rsoxbuffer_initialize, -1);
|
418
|
+
rb_define_method(RSoxBuffer, "length", rsoxbuffer_length, 0);
|
419
|
+
rb_define_method(RSoxBuffer, "size", rsoxbuffer_length, 0);
|
420
|
+
rb_define_method(RSoxBuffer, "buffer", rsoxbuffer_buffer, 0);
|
421
|
+
rb_define_method(RSoxBuffer, "[]", rsoxbuffer_at, 1);
|
422
|
+
rb_define_method(RSoxBuffer, "at", rsoxbuffer_at, 1);
|
423
|
+
|
424
|
+
RSoxSignal = rb_define_class("RSoxSignal", rb_cObject);
|
425
|
+
rb_define_method(RSoxSignal, "rate", rsoxsignal_rate, 0);
|
426
|
+
rb_define_method(RSoxSignal, "channels", rsoxsignal_channels, 0);
|
427
|
+
rb_define_method(RSoxSignal, "bits", rsoxsignal_bits, 0);
|
428
|
+
rb_define_method(RSoxSignal, "rate=", rsoxsignal_rate_set, 1);
|
429
|
+
rb_define_method(RSoxSignal, "channels=", rsoxsignal_channels_set, 1);
|
430
|
+
rb_define_method(RSoxSignal, "bits=", rsoxsignal_bits_set, 1);
|
431
|
+
|
432
|
+
RSoxEncoding = rb_define_class("RSoxEncoding", rb_cObject);
|
433
|
+
rb_define_method(RSoxEncoding, "bps", rsoxencoding_bps, 0);
|
434
|
+
rb_define_method(RSoxEncoding, "bps=", rsoxencoding_bps, 1);
|
435
|
+
|
436
|
+
RSoxEffect = rb_define_class("RSoxEffect", rb_cObject);
|
437
|
+
|
438
|
+
RSoxEffectsChain = rb_define_class("RSoxEffectsChain", rb_cObject);
|
439
|
+
rb_define_method(RSoxEffectsChain, "add", rsoxeffectschain_add, -1);
|
440
|
+
rb_define_method(RSoxEffectsChain, "flow", rsoxeffectschain_flow, -1);
|
441
|
+
}/*}}}*/
|