roctave 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +33 -0
- data/ext/roctave/cu8_file_reader.c +331 -0
- data/ext/roctave/cu8_file_reader.h +30 -0
- data/ext/roctave/extconf.rb +6 -0
- data/ext/roctave/fir_filter.c +795 -0
- data/ext/roctave/fir_filter.h +29 -0
- data/ext/roctave/freq_shifter.c +410 -0
- data/ext/roctave/freq_shifter.h +29 -0
- data/ext/roctave/iir_filter.c +462 -0
- data/ext/roctave/iir_filter.h +29 -0
- data/ext/roctave/roctave.c +38 -0
- data/ext/roctave/roctave.h +27 -0
- data/lib/roctave.rb +168 -0
- data/lib/roctave/bilinear.rb +92 -0
- data/lib/roctave/butter.rb +87 -0
- data/lib/roctave/cheby.rb +180 -0
- data/lib/roctave/cu8_file_reader.rb +45 -0
- data/lib/roctave/dft.rb +280 -0
- data/lib/roctave/filter.rb +64 -0
- data/lib/roctave/finite_difference_coefficients.rb +73 -0
- data/lib/roctave/fir.rb +121 -0
- data/lib/roctave/fir1.rb +134 -0
- data/lib/roctave/fir2.rb +246 -0
- data/lib/roctave/fir_design.rb +311 -0
- data/lib/roctave/firls.rb +380 -0
- data/lib/roctave/firpm.rb +499 -0
- data/lib/roctave/freq_shifter.rb +47 -0
- data/lib/roctave/freqz.rb +233 -0
- data/lib/roctave/iir.rb +80 -0
- data/lib/roctave/interp1.rb +78 -0
- data/lib/roctave/plot.rb +748 -0
- data/lib/roctave/poly.rb +46 -0
- data/lib/roctave/roots.rb +73 -0
- data/lib/roctave/sftrans.rb +157 -0
- data/lib/roctave/version.rb +3 -0
- data/lib/roctave/window.rb +116 -0
- data/roctave.gemspec +79 -0
- data/samples/butter.rb +12 -0
- data/samples/cheby.rb +28 -0
- data/samples/dft.rb +18 -0
- data/samples/differentiator.rb +48 -0
- data/samples/differentiator_frequency_scaling.rb +52 -0
- data/samples/fft.rb +40 -0
- data/samples/finite_difference_coefficient.rb +53 -0
- data/samples/fir1.rb +13 -0
- data/samples/fir2.rb +14 -0
- data/samples/fir2_windows.rb +29 -0
- data/samples/fir2bank.rb +30 -0
- data/samples/fir_low_pass.rb +44 -0
- data/samples/firls.rb +77 -0
- data/samples/firpm.rb +78 -0
- data/samples/hilbert_transformer.rb +20 -0
- data/samples/hilbert_transformer_frequency_scaling.rb +47 -0
- data/samples/plot.rb +45 -0
- data/samples/stem.rb +8 -0
- data/samples/type1.rb +25 -0
- data/samples/type3.rb +24 -0
- data/samples/windows.rb +25 -0
- metadata +123 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
/* Copyright (C) 2019 Théotime Bollengier <theotime.bollengier@gmail.com>
|
2
|
+
*
|
3
|
+
* This file is part of Roctave
|
4
|
+
*
|
5
|
+
* Roctave is free software: you can redistribute it and/or modify
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
8
|
+
* (at your option) any later version.
|
9
|
+
*
|
10
|
+
* Roctave is distributed in the hope that it will be useful,
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
* GNU General Public License for more details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU General Public License
|
16
|
+
* along with Roctave. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
*/
|
18
|
+
|
19
|
+
|
20
|
+
#ifndef FIR_FILTER_H
|
21
|
+
#define FIR_FILTER_H
|
22
|
+
|
23
|
+
#include <ruby.h>
|
24
|
+
|
25
|
+
extern VALUE c_FIR;
|
26
|
+
|
27
|
+
void Init_fir_filter();
|
28
|
+
|
29
|
+
#endif /* FIR_FILTER_H */
|
@@ -0,0 +1,410 @@
|
|
1
|
+
/* Copyright (C) 2019 Théotime Bollengier <theotime.bollengier@gmail.com>
|
2
|
+
*
|
3
|
+
* This file is part of Roctave
|
4
|
+
*
|
5
|
+
* Roctave is free software: you can redistribute it and/or modify
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
8
|
+
* (at your option) any later version.
|
9
|
+
*
|
10
|
+
* Roctave is distributed in the hope that it will be useful,
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
* GNU General Public License for more details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU General Public License
|
16
|
+
* along with Roctave. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
*/
|
18
|
+
|
19
|
+
|
20
|
+
#include <ruby.h>
|
21
|
+
#include "roctave.h"
|
22
|
+
#include "freq_shifter.h"
|
23
|
+
|
24
|
+
VALUE c_FreqShifter;
|
25
|
+
|
26
|
+
|
27
|
+
static ID id_real;
|
28
|
+
static ID id_imag;
|
29
|
+
static ID id_freq;
|
30
|
+
static ID id_fs;
|
31
|
+
static ID id_initial_phase;
|
32
|
+
|
33
|
+
|
34
|
+
struct freq_shifter {
|
35
|
+
double phase;
|
36
|
+
double sampling_frequency;
|
37
|
+
double frequency;
|
38
|
+
double phase_increment;
|
39
|
+
};
|
40
|
+
|
41
|
+
|
42
|
+
static void freq_shifter_free(void *p)
|
43
|
+
{
|
44
|
+
struct freq_shifter *frqsh = (struct freq_shifter*)p;
|
45
|
+
|
46
|
+
xfree(frqsh);
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
static size_t freq_shifter_size(const void* data)
|
51
|
+
{
|
52
|
+
return sizeof(struct freq_shifter);
|
53
|
+
}
|
54
|
+
|
55
|
+
|
56
|
+
static const rb_data_type_t freq_shifter_type = {
|
57
|
+
.wrap_struct_name = "roctave_freq_shifter_struct",
|
58
|
+
.function = {
|
59
|
+
.dmark = NULL,
|
60
|
+
.dfree = freq_shifter_free,
|
61
|
+
.dsize = freq_shifter_size,
|
62
|
+
},
|
63
|
+
.data = NULL,
|
64
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
65
|
+
};
|
66
|
+
|
67
|
+
|
68
|
+
static VALUE freq_shifter_alloc(VALUE klass)
|
69
|
+
{
|
70
|
+
VALUE obj;
|
71
|
+
struct freq_shifter *frqsh;
|
72
|
+
|
73
|
+
frqsh = ZALLOC(struct freq_shifter);
|
74
|
+
|
75
|
+
obj = TypedData_Wrap_Struct(klass, &freq_shifter_type, frqsh);
|
76
|
+
|
77
|
+
frqsh->phase = 0.0;
|
78
|
+
frqsh->sampling_frequency = 1.0;
|
79
|
+
frqsh->frequency = 1.0;
|
80
|
+
frqsh->phase_increment = 2.0*M_PI*frqsh->frequency/frqsh->sampling_frequency;
|
81
|
+
|
82
|
+
return obj;
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
/* @overload initialize(freq: 0.5, fs: 1.0, initial_phase: 0.0)
|
87
|
+
* @param freq [Float] the amount of frequency to shift
|
88
|
+
* @param fs [Float] the sampling frequency
|
89
|
+
* @param initial_phase [Float] the initial phase of the oscillator
|
90
|
+
* @return [Roctave::FreqShifter]
|
91
|
+
*/
|
92
|
+
static VALUE freq_shifter_initialize(int argc, VALUE *argv, VALUE self)
|
93
|
+
{
|
94
|
+
struct freq_shifter *frqsh;
|
95
|
+
VALUE hash;
|
96
|
+
const ID kwkeys[] = {id_freq, id_fs, id_initial_phase};
|
97
|
+
VALUE kwvalues[] = {Qundef, Qundef, Qundef};
|
98
|
+
|
99
|
+
// int i;
|
100
|
+
// for (i = 0; i < argc; i++)
|
101
|
+
// rb_warn("argv[%d] = %"PRIsVALUE, i, rb_class_name(rb_obj_class(argv[i])));
|
102
|
+
|
103
|
+
rb_scan_args(argc, argv, ":", &hash);
|
104
|
+
|
105
|
+
if (!NIL_P(hash))
|
106
|
+
rb_get_kwargs(hash, kwkeys, 0, 3, kwvalues);
|
107
|
+
|
108
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
109
|
+
|
110
|
+
if (kwvalues[0] != Qundef)
|
111
|
+
frqsh->frequency = NUM2DBL(kwvalues[0]);
|
112
|
+
else
|
113
|
+
frqsh->frequency = 0.5;
|
114
|
+
|
115
|
+
if (kwvalues[1] != Qundef)
|
116
|
+
if (NUM2DBL(kwvalues[1]) > 0.0) frqsh->sampling_frequency = NUM2DBL(kwvalues[1]);
|
117
|
+
else
|
118
|
+
frqsh->sampling_frequency = 1.0;
|
119
|
+
|
120
|
+
if (kwvalues[2] != Qundef)
|
121
|
+
frqsh->phase = fmod(NUM2DBL(kwvalues[2]), 2.0*M_PI);
|
122
|
+
else
|
123
|
+
frqsh->phase = 0.0;
|
124
|
+
|
125
|
+
frqsh->phase_increment = 2.0*M_PI*frqsh->frequency/frqsh->sampling_frequency;
|
126
|
+
|
127
|
+
// rb_warn(" ");
|
128
|
+
// rb_warn("phase = %g", frqsh->phase);
|
129
|
+
// rb_warn("frequency = %g", frqsh->frequency);
|
130
|
+
// rb_warn("sampling_frequency = %g", frqsh->sampling_frequency);
|
131
|
+
// rb_warn(" ");
|
132
|
+
|
133
|
+
return self;
|
134
|
+
}
|
135
|
+
|
136
|
+
|
137
|
+
/* Get the current phase of the oscillator.
|
138
|
+
* @return [Float] the current phase of the oscillator
|
139
|
+
*/
|
140
|
+
static VALUE freq_shifter_get_phase(VALUE self)
|
141
|
+
{
|
142
|
+
struct freq_shifter *frqsh;
|
143
|
+
|
144
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
145
|
+
|
146
|
+
return DBL2NUM(frqsh->phase);
|
147
|
+
}
|
148
|
+
|
149
|
+
|
150
|
+
/* Set the current phase of the oscillator.
|
151
|
+
* @param phase [Float] the requested phase of the oscillator
|
152
|
+
* @return [Float] the phase of the oscillator
|
153
|
+
*/
|
154
|
+
static VALUE freq_shifter_set_phase(VALUE self, VALUE phase)
|
155
|
+
{
|
156
|
+
struct freq_shifter *frqsh;
|
157
|
+
|
158
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
159
|
+
|
160
|
+
frqsh->phase = fmod(NUM2DBL(phase), 2.0*M_PI);
|
161
|
+
|
162
|
+
return DBL2NUM(frqsh->phase);
|
163
|
+
}
|
164
|
+
|
165
|
+
|
166
|
+
/* Get the sampling frequency
|
167
|
+
* @return [Float] the sampling frequency
|
168
|
+
*/
|
169
|
+
static VALUE freq_shifter_get_sampling_frequency(VALUE self)
|
170
|
+
{
|
171
|
+
struct freq_shifter *frqsh;
|
172
|
+
|
173
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
174
|
+
|
175
|
+
return DBL2NUM(frqsh->sampling_frequency);
|
176
|
+
}
|
177
|
+
|
178
|
+
|
179
|
+
/* Set the sampling frequency
|
180
|
+
* @param fs [Float] the requested sampling frequency. Must be > 0.
|
181
|
+
* @return [Float] the sampling frequency
|
182
|
+
*/
|
183
|
+
static VALUE freq_shifter_set_sampling_frequency(VALUE self, VALUE fs)
|
184
|
+
{
|
185
|
+
struct freq_shifter *frqsh;
|
186
|
+
|
187
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
188
|
+
|
189
|
+
if (NUM2DBL(fs) > 0.0)
|
190
|
+
frqsh->sampling_frequency = NUM2DBL(fs);
|
191
|
+
|
192
|
+
frqsh->phase_increment = 2.0*M_PI*frqsh->frequency/frqsh->sampling_frequency;
|
193
|
+
|
194
|
+
return DBL2NUM(frqsh->sampling_frequency);
|
195
|
+
}
|
196
|
+
|
197
|
+
|
198
|
+
/* Get the frequency
|
199
|
+
* @return [Float] the frequency
|
200
|
+
*/
|
201
|
+
static VALUE freq_shifter_get_frequency(VALUE self)
|
202
|
+
{
|
203
|
+
struct freq_shifter *frqsh;
|
204
|
+
|
205
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
206
|
+
|
207
|
+
return DBL2NUM(frqsh->frequency);
|
208
|
+
}
|
209
|
+
|
210
|
+
|
211
|
+
/* Set the frequency
|
212
|
+
* @param f [Float] the requested frequency. Must be > 0.
|
213
|
+
* @return [Float] the frequency
|
214
|
+
*/
|
215
|
+
static VALUE freq_shifter_set_frequency(VALUE self, VALUE f)
|
216
|
+
{
|
217
|
+
struct freq_shifter *frqsh;
|
218
|
+
|
219
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
220
|
+
|
221
|
+
frqsh->sampling_frequency = NUM2DBL(f);
|
222
|
+
|
223
|
+
frqsh->phase_increment = 2.0*M_PI*frqsh->frequency/frqsh->sampling_frequency;
|
224
|
+
|
225
|
+
return DBL2NUM(frqsh->frequency);
|
226
|
+
}
|
227
|
+
|
228
|
+
|
229
|
+
static VALUE freq_shifter_shift_one_sample(struct freq_shifter *frqsh, VALUE sample)
|
230
|
+
{
|
231
|
+
const double i = cos(frqsh->phase);
|
232
|
+
const double q = sin(frqsh->phase);
|
233
|
+
double real, imag;
|
234
|
+
VALUE res;
|
235
|
+
|
236
|
+
if (rb_class_of(sample) == rb_cComplex) {
|
237
|
+
real = NUM2DBL(rb_funcallv(sample, id_real, 0, NULL));
|
238
|
+
imag = NUM2DBL(rb_funcallv(sample, id_imag, 0, NULL));
|
239
|
+
res = rb_complex_raw(
|
240
|
+
DBL2NUM(real*i - imag*q),
|
241
|
+
DBL2NUM(real*q + imag*i));
|
242
|
+
}
|
243
|
+
else {
|
244
|
+
real = NUM2DBL(sample);
|
245
|
+
res = rb_complex_raw(
|
246
|
+
DBL2NUM(real*i),
|
247
|
+
DBL2NUM(real*q));
|
248
|
+
}
|
249
|
+
|
250
|
+
frqsh->phase = fmod(frqsh->phase + frqsh->phase_increment, 2*M_PI);
|
251
|
+
|
252
|
+
return res;
|
253
|
+
}
|
254
|
+
|
255
|
+
|
256
|
+
static VALUE freq_shifter_am_one_sample(struct freq_shifter *frqsh, VALUE sample)
|
257
|
+
{
|
258
|
+
const double i = cos(frqsh->phase);
|
259
|
+
double real, imag;
|
260
|
+
VALUE res;
|
261
|
+
|
262
|
+
if (rb_class_of(sample) == rb_cComplex) {
|
263
|
+
real = NUM2DBL(rb_funcallv(sample, id_real, 0, NULL));
|
264
|
+
imag = NUM2DBL(rb_funcallv(sample, id_imag, 0, NULL));
|
265
|
+
res = rb_complex_raw(
|
266
|
+
DBL2NUM(real*i),
|
267
|
+
DBL2NUM(imag*i));
|
268
|
+
}
|
269
|
+
else
|
270
|
+
res = DBL2NUM(NUM2DBL(sample) * i);
|
271
|
+
|
272
|
+
frqsh->phase = fmod(frqsh->phase + frqsh->phase_increment, 2*M_PI);
|
273
|
+
|
274
|
+
return res;
|
275
|
+
}
|
276
|
+
|
277
|
+
|
278
|
+
/* Multiply the signal with exp(2*i*pi*f*t)
|
279
|
+
* @param signal [Array<Float,Complex>, Float, Complex] a single or and array of float or complex numbers
|
280
|
+
* @return [Array<Float,Complex>, Float, Complex] a single or and array of float or complex numbers
|
281
|
+
*/
|
282
|
+
static VALUE freq_shifter_shift(VALUE self, VALUE sig)
|
283
|
+
{
|
284
|
+
struct freq_shifter *frqsh;
|
285
|
+
VALUE res;
|
286
|
+
int len, i;
|
287
|
+
|
288
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
289
|
+
|
290
|
+
if (rb_class_of(sig) == rb_cArray) {
|
291
|
+
len = rb_array_len(sig);
|
292
|
+
res = rb_ary_new_capa(len);
|
293
|
+
for (i = 0; i < len; i++)
|
294
|
+
rb_ary_store(res, i, freq_shifter_shift_one_sample(frqsh, rb_ary_entry(sig, i)));
|
295
|
+
}
|
296
|
+
else {
|
297
|
+
res = freq_shifter_shift_one_sample(frqsh, sig);
|
298
|
+
}
|
299
|
+
|
300
|
+
return res;
|
301
|
+
}
|
302
|
+
|
303
|
+
|
304
|
+
/* Multiply the signal with cos(2*i*pi*f*t)
|
305
|
+
* @param signal [Array<Float,Complex>, Float, Complex] a single or and array of float or complex numbers
|
306
|
+
* @return [Array<Float,Complex>, Float, Complex] a single or and array of float or complex numbers
|
307
|
+
*/
|
308
|
+
static VALUE freq_shifter_am(VALUE self, VALUE sig)
|
309
|
+
{
|
310
|
+
struct freq_shifter *frqsh;
|
311
|
+
VALUE res;
|
312
|
+
int len, i;
|
313
|
+
|
314
|
+
TypedData_Get_Struct(self, struct freq_shifter, &freq_shifter_type, frqsh);
|
315
|
+
|
316
|
+
if (rb_class_of(sig) == rb_cArray) {
|
317
|
+
len = rb_array_len(sig);
|
318
|
+
res = rb_ary_new_capa(len);
|
319
|
+
for (i = 0; i < len; i++)
|
320
|
+
rb_ary_store(res, i, freq_shifter_am_one_sample(frqsh, rb_ary_entry(sig, i)));
|
321
|
+
}
|
322
|
+
else {
|
323
|
+
res = freq_shifter_am_one_sample(frqsh, sig);
|
324
|
+
}
|
325
|
+
|
326
|
+
return res;
|
327
|
+
}
|
328
|
+
|
329
|
+
|
330
|
+
#if 0
|
331
|
+
// Makes segmentation faults, maybe because rbo is garbage collected
|
332
|
+
// befor it can finish its shift.
|
333
|
+
|
334
|
+
/* Multiply the signal with exp(2*i*pi*f*t)
|
335
|
+
* @overload shift(signal, freq: 0.5, fs: 1.0, initial_phase: 0.0)
|
336
|
+
* @param signal [Array<Float,Complex>, Float, Complex] a single or and array of float or complex numbers
|
337
|
+
* @param freq [Float] the amount of frequency to shift
|
338
|
+
* @param fs [Float] the sampling frequency
|
339
|
+
* @param initial_phase [Float] the initial phase of the oscillator
|
340
|
+
* @return [Array<Float,Complex>, Float, Complex] a single or and array of float or complex numbers
|
341
|
+
*/
|
342
|
+
static VALUE freq_shifter_module_shift(int argc, VALUE *argv, VALUE self)
|
343
|
+
{
|
344
|
+
VALUE sig;
|
345
|
+
VALUE hash;
|
346
|
+
VALUE rbo;
|
347
|
+
VALUE res;
|
348
|
+
|
349
|
+
rb_scan_args(argc, argv, "1:", &sig, &hash);
|
350
|
+
|
351
|
+
if (NIL_P(hash))
|
352
|
+
hash = rb_hash_new();
|
353
|
+
|
354
|
+
rbo = rb_class_new_instance(1, &hash, c_FreqShifter);
|
355
|
+
res = freq_shifter_shift(rbo, sig);
|
356
|
+
|
357
|
+
return res;
|
358
|
+
}
|
359
|
+
|
360
|
+
|
361
|
+
/* Multiply the signal with cos(2*i*pi*f*t)
|
362
|
+
* @overload shift(signal, freq: 0.5, fs: 1.0, initial_phase: 0.0)
|
363
|
+
* @param signal [Array<Float,Complex>, Float, Complex] a single or and array of float or complex numbers
|
364
|
+
* @param freq [Float] the amount of frequency to shift
|
365
|
+
* @param fs [Float] the sampling frequency
|
366
|
+
* @param initial_phase [Float] the initial phase of the oscillator
|
367
|
+
* @return [Array<Float,Complex>, Float, Complex] a single or and array of float or complex numbers
|
368
|
+
*/
|
369
|
+
static VALUE freq_shifter_module_am(int argc, VALUE *argv, VALUE self)
|
370
|
+
{
|
371
|
+
VALUE sig;
|
372
|
+
VALUE hash;
|
373
|
+
VALUE rbo;
|
374
|
+
|
375
|
+
rb_scan_args(argc, argv, "1:", &sig, &hash);
|
376
|
+
|
377
|
+
if (NIL_P(hash))
|
378
|
+
hash = rb_hash_new();
|
379
|
+
|
380
|
+
rbo = rb_class_new_instance(1, &hash, c_FreqShifter);
|
381
|
+
|
382
|
+
return freq_shifter_am(rbo, sig);
|
383
|
+
}
|
384
|
+
#endif
|
385
|
+
|
386
|
+
|
387
|
+
void Init_freq_shifter()
|
388
|
+
{
|
389
|
+
id_real = rb_intern("real");
|
390
|
+
id_imag = rb_intern("imag");
|
391
|
+
id_freq = rb_intern("freq");
|
392
|
+
id_fs = rb_intern("fs");
|
393
|
+
id_initial_phase = rb_intern("initial_phase");
|
394
|
+
|
395
|
+
c_FreqShifter = rb_define_class_under(m_Roctave, "FreqShifter", rb_cData);
|
396
|
+
|
397
|
+
rb_define_alloc_func(c_FreqShifter, freq_shifter_alloc);
|
398
|
+
//rb_define_singleton_method(c_FreqShifter, "shift", freq_shifter_module_shift, -1);
|
399
|
+
//rb_define_singleton_method(c_FreqShifter, "amplitude_modulate", freq_shifter_module_am, -1);
|
400
|
+
rb_define_method(c_FreqShifter, "initialize", freq_shifter_initialize, -1);
|
401
|
+
rb_define_method(c_FreqShifter, "shift", freq_shifter_shift, 1);
|
402
|
+
rb_define_method(c_FreqShifter, "amplitude_modulate", freq_shifter_am, 1);
|
403
|
+
rb_define_method(c_FreqShifter, "frequency", freq_shifter_get_frequency, 0);
|
404
|
+
rb_define_method(c_FreqShifter, "frequency=", freq_shifter_set_frequency, 1);
|
405
|
+
rb_define_method(c_FreqShifter, "sampling_frequency", freq_shifter_get_sampling_frequency, 0);
|
406
|
+
rb_define_method(c_FreqShifter, "sampling_frequency=", freq_shifter_set_sampling_frequency, 1);
|
407
|
+
rb_define_method(c_FreqShifter, "phase", freq_shifter_get_phase, 0);
|
408
|
+
rb_define_method(c_FreqShifter, "phase=", freq_shifter_set_phase, 1);
|
409
|
+
}
|
410
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
/* Copyright (C) 2019 Théotime Bollengier <theotime.bollengier@gmail.com>
|
2
|
+
*
|
3
|
+
* This file is part of Roctave
|
4
|
+
*
|
5
|
+
* Roctave is free software: you can redistribute it and/or modify
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
8
|
+
* (at your option) any later version.
|
9
|
+
*
|
10
|
+
* Roctave is distributed in the hope that it will be useful,
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
* GNU General Public License for more details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU General Public License
|
16
|
+
* along with Roctave. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
*/
|
18
|
+
|
19
|
+
|
20
|
+
#ifndef FREQ_SHIFTER_H
|
21
|
+
#define FREQ_SHIFTER_H
|
22
|
+
|
23
|
+
#include <ruby.h>
|
24
|
+
|
25
|
+
extern VALUE c_FreqShifter;
|
26
|
+
|
27
|
+
void Init_freq_shifter();
|
28
|
+
|
29
|
+
#endif /* FREQ_SHIFTER_H */
|