ruby-audio 1.0.0 → 1.1.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.
- data/Rakefile +1 -1
- data/ext/ra_buffer.c +53 -23
- data/ext/ra_buffer.h +1 -0
- data/ext/ra_sound.c +244 -16
- data/spec/buffer_spec.rb +12 -0
- data/spec/sound_spec.rb +38 -3
- metadata +2 -2
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'spec/rake/spectask'
|
|
6
6
|
|
7
7
|
spec = Gem::Specification.new do |s|
|
8
8
|
s.name = 'ruby-audio'
|
9
|
-
s.version = '1.
|
9
|
+
s.version = '1.1.0'
|
10
10
|
s.summary = 'ruby-audio wraps around libsndfile to provide simplified sound reading and writing support to ruby programs'
|
11
11
|
s.authors = ['Stephen Augenstein']
|
12
12
|
s.email = 'perl.programmer@gmail.com'
|
data/ext/ra_buffer.c
CHANGED
@@ -16,14 +16,15 @@ void Init_ra_buffer() {
|
|
16
16
|
VALUE mRubyAudio = rb_define_module("RubyAudio");
|
17
17
|
VALUE cRABuffer = rb_define_class_under(mRubyAudio, "CBuffer", rb_cObject);
|
18
18
|
rb_define_alloc_func(cRABuffer, ra_buffer_allocate);
|
19
|
-
rb_define_method(cRABuffer, "initialize",
|
20
|
-
rb_define_method(cRABuffer, "
|
21
|
-
rb_define_method(cRABuffer, "
|
22
|
-
rb_define_method(cRABuffer, "
|
23
|
-
rb_define_method(cRABuffer, "real_size
|
24
|
-
rb_define_method(cRABuffer, "
|
25
|
-
rb_define_method(cRABuffer, "
|
26
|
-
rb_define_method(cRABuffer, "[]
|
19
|
+
rb_define_method(cRABuffer, "initialize", ra_buffer_init, -1);
|
20
|
+
rb_define_method(cRABuffer, "initialize_copy", ra_buffer_init_copy, 1);
|
21
|
+
rb_define_method(cRABuffer, "channels", ra_buffer_channels, 0);
|
22
|
+
rb_define_method(cRABuffer, "size", ra_buffer_size, 0);
|
23
|
+
rb_define_method(cRABuffer, "real_size", ra_buffer_real_size, 0);
|
24
|
+
rb_define_method(cRABuffer, "real_size=", ra_buffer_real_size_set, 1);
|
25
|
+
rb_define_method(cRABuffer, "type", ra_buffer_type, 0);
|
26
|
+
rb_define_method(cRABuffer, "[]", ra_buffer_aref, 1);
|
27
|
+
rb_define_method(cRABuffer, "[]=", ra_buffer_aset, 2);
|
27
28
|
|
28
29
|
ra_short_sym = rb_intern("short");
|
29
30
|
ra_int_sym = rb_intern("int");
|
@@ -43,6 +44,22 @@ static void ra_buffer_free(RA_BUFFER *buf) {
|
|
43
44
|
xfree(buf);
|
44
45
|
}
|
45
46
|
|
47
|
+
/*
|
48
|
+
* Uses size, channels, and type to allocate a properly sized array and set data
|
49
|
+
* to the pointer for that data. Returns size.
|
50
|
+
*/
|
51
|
+
static int ra_buffer_alloc_data(RA_BUFFER *buf) {
|
52
|
+
int size;
|
53
|
+
switch(buf->type) {
|
54
|
+
case RA_BUFFER_TYPE_SHORT: size = sizeof(short)*buf->size*buf->channels; break;
|
55
|
+
case RA_BUFFER_TYPE_INT: size = sizeof(int)*buf->size*buf->channels; break;
|
56
|
+
case RA_BUFFER_TYPE_FLOAT: size = sizeof(float)*buf->size*buf->channels; break;
|
57
|
+
case RA_BUFFER_TYPE_DOUBLE: size = sizeof(double)*buf->size*buf->channels; break;
|
58
|
+
}
|
59
|
+
buf->data = (void*)xmalloc(size);
|
60
|
+
return size;
|
61
|
+
}
|
62
|
+
|
46
63
|
/*
|
47
64
|
* call-seq:
|
48
65
|
* RubyAudio::CBuffer.new(type, size, channels=1) => buf
|
@@ -80,26 +97,39 @@ static VALUE ra_buffer_init(int argc, VALUE *argv, VALUE self) {
|
|
80
97
|
// Allocate data array based on type
|
81
98
|
buf->size = FIX2INT(argv[1]);
|
82
99
|
buf->real_size = 0;
|
83
|
-
if(strcmp(buf_type, "short") == 0)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
} else if(strcmp(buf_type, "float") == 0) {
|
90
|
-
buf->type = RA_BUFFER_TYPE_FLOAT;
|
91
|
-
buf->data = ALLOC_N(float, buf->size * buf->channels);
|
92
|
-
} else if(strcmp(buf_type, "double") == 0) {
|
93
|
-
buf->type = RA_BUFFER_TYPE_DOUBLE;
|
94
|
-
buf->data = ALLOC_N(double, buf->size * buf->channels);
|
95
|
-
} else {
|
96
|
-
rb_raise(rb_eArgError, "Invalid type: %s", buf_type);
|
97
|
-
}
|
100
|
+
if(strcmp(buf_type, "short") == 0) buf->type = RA_BUFFER_TYPE_SHORT;
|
101
|
+
else if(strcmp(buf_type, "int") == 0) buf->type = RA_BUFFER_TYPE_INT;
|
102
|
+
else if(strcmp(buf_type, "float") == 0) buf->type = RA_BUFFER_TYPE_FLOAT;
|
103
|
+
else if(strcmp(buf_type, "double") == 0) buf->type = RA_BUFFER_TYPE_DOUBLE;
|
104
|
+
else rb_raise(rb_eArgError, "Invalid type: %s", buf_type);
|
105
|
+
ra_buffer_alloc_data(buf);
|
98
106
|
|
99
107
|
// Return self
|
100
108
|
return self;
|
101
109
|
}
|
102
110
|
|
111
|
+
/* :nodoc: */
|
112
|
+
static VALUE ra_buffer_init_copy(VALUE copy, VALUE buf) {
|
113
|
+
if (copy == buf) return copy;
|
114
|
+
|
115
|
+
// Checks
|
116
|
+
rb_check_frozen(copy);
|
117
|
+
if (!rb_obj_is_instance_of(buf, rb_obj_class(copy))) {
|
118
|
+
rb_raise(rb_eTypeError, "wrong argument class");
|
119
|
+
}
|
120
|
+
|
121
|
+
RA_BUFFER *copy_struct, *buf_struct;
|
122
|
+
Data_Get_Struct(copy, RA_BUFFER, copy_struct);
|
123
|
+
Data_Get_Struct(buf, RA_BUFFER, buf_struct);
|
124
|
+
|
125
|
+
// Clone data
|
126
|
+
memcpy(copy_struct, buf_struct, sizeof(RA_BUFFER));
|
127
|
+
int size = ra_buffer_alloc_data(copy_struct);
|
128
|
+
memcpy(copy_struct->data, buf_struct->data, size);
|
129
|
+
|
130
|
+
return copy;
|
131
|
+
}
|
132
|
+
|
103
133
|
/*
|
104
134
|
* call-seq:
|
105
135
|
* buf.channels => integer
|
data/ext/ra_buffer.h
CHANGED
@@ -26,6 +26,7 @@ static void ra_buffer_free(RA_BUFFER *buf);
|
|
26
26
|
|
27
27
|
/*** Instance Methods ***/
|
28
28
|
static VALUE ra_buffer_init(int argc, VALUE *argv, VALUE self);
|
29
|
+
static VALUE ra_buffer_init_copy(VALUE copy, VALUE buf);
|
29
30
|
static VALUE ra_buffer_channels(VALUE self);
|
30
31
|
static VALUE ra_buffer_size(VALUE self);
|
31
32
|
static VALUE ra_buffer_real_size(VALUE self);
|
data/ext/ra_sound.c
CHANGED
@@ -127,6 +127,238 @@ static VALUE ra_sound_seek(VALUE self, VALUE frames, VALUE whence) {
|
|
127
127
|
return INT2FIX(0);
|
128
128
|
}
|
129
129
|
|
130
|
+
static void ra_sound_read_short(RA_SOUND *snd, RA_BUFFER *buf, sf_count_t frames) {
|
131
|
+
static short temp[1024];
|
132
|
+
int temp_len = 1024;
|
133
|
+
short *data = (short*)buf->data;
|
134
|
+
|
135
|
+
// Get info struct
|
136
|
+
SF_INFO *info;
|
137
|
+
Data_Get_Struct(snd->info, SF_INFO, info);
|
138
|
+
|
139
|
+
// Up/Downmix based on channel matching
|
140
|
+
sf_count_t read = 0, r, amount;
|
141
|
+
int i, k;
|
142
|
+
if(buf->channels == info->channels) { // Simply read data without mix
|
143
|
+
read = sf_readf_short(snd->snd, data, frames);
|
144
|
+
} else if(buf->channels == 1) { // Downmix to mono
|
145
|
+
sf_count_t max = temp_len / info->channels;
|
146
|
+
int channels, mix_sum;
|
147
|
+
|
148
|
+
while(read < frames) {
|
149
|
+
// Calculate # of frames to read
|
150
|
+
amount = frames - read;
|
151
|
+
if(amount > max) amount = max;
|
152
|
+
|
153
|
+
r = sf_readf_short(snd->snd, temp, amount);
|
154
|
+
if(r == 0) break;
|
155
|
+
|
156
|
+
// Mix channels together by averaging all channels and store to buffer
|
157
|
+
for(i = 0; i < r; i++) {
|
158
|
+
mix_sum = 0;
|
159
|
+
for(k = 0; k < info->channels; k++) mix_sum += temp[i * info->channels + k];
|
160
|
+
data[read] = mix_sum/info->channels;
|
161
|
+
read++;
|
162
|
+
}
|
163
|
+
}
|
164
|
+
} else if(info->channels == 1) { // Upmix from mono by copying channel
|
165
|
+
while(read < frames) {
|
166
|
+
// Calculate # of frames to read
|
167
|
+
amount = frames - read;
|
168
|
+
if(amount > temp_len) amount = temp_len;
|
169
|
+
|
170
|
+
r = sf_readf_short(snd->snd, temp, amount);
|
171
|
+
if(r == 0) break;
|
172
|
+
|
173
|
+
// Write every frame channel times to the buffer
|
174
|
+
for(i = 0; i < r; i++) {
|
175
|
+
for(k = 0; k < buf->channels; k++) {
|
176
|
+
data[read * buf->channels + k] = temp[i];
|
177
|
+
}
|
178
|
+
read++;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
} else {
|
182
|
+
rb_raise(eRubyAudioError, "unsupported mix from %d to %d", buf->channels, info->channels);
|
183
|
+
}
|
184
|
+
|
185
|
+
buf->real_size = read;
|
186
|
+
}
|
187
|
+
|
188
|
+
static void ra_sound_read_int(RA_SOUND *snd, RA_BUFFER *buf, sf_count_t frames) {
|
189
|
+
static int temp[1024];
|
190
|
+
int temp_len = 1024;
|
191
|
+
int *data = (int*)buf->data;
|
192
|
+
|
193
|
+
// Get info struct
|
194
|
+
SF_INFO *info;
|
195
|
+
Data_Get_Struct(snd->info, SF_INFO, info);
|
196
|
+
|
197
|
+
// Up/Downmix based on channel matching
|
198
|
+
sf_count_t read = 0, r, amount;
|
199
|
+
int i, k;
|
200
|
+
if(buf->channels == info->channels) { // Simply read data without mix
|
201
|
+
read = sf_readf_int(snd->snd, data, frames);
|
202
|
+
} else if(buf->channels == 1) { // Downmix to mono
|
203
|
+
sf_count_t max = temp_len / info->channels;
|
204
|
+
int channels, mix_sum;
|
205
|
+
|
206
|
+
while(read < frames) {
|
207
|
+
// Calculate # of frames to read
|
208
|
+
amount = frames - read;
|
209
|
+
if(amount > max) amount = max;
|
210
|
+
|
211
|
+
r = sf_readf_int(snd->snd, temp, amount);
|
212
|
+
if(r == 0) break;
|
213
|
+
|
214
|
+
// Mix channels together by averaging all channels and store to buffer
|
215
|
+
for(i = 0; i < r; i++) {
|
216
|
+
mix_sum = 0;
|
217
|
+
for(k = 0; k < info->channels; k++) mix_sum += temp[i * info->channels + k];
|
218
|
+
data[read] = mix_sum/info->channels;
|
219
|
+
read++;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
} else if(info->channels == 1) { // Upmix from mono by copying channel
|
223
|
+
while(read < frames) {
|
224
|
+
// Calculate # of frames to read
|
225
|
+
amount = frames - read;
|
226
|
+
if(amount > temp_len) amount = temp_len;
|
227
|
+
|
228
|
+
r = sf_readf_int(snd->snd, temp, amount);
|
229
|
+
if(r == 0) break;
|
230
|
+
|
231
|
+
// Write every frame channel times to the buffer
|
232
|
+
for(i = 0; i < r; i++) {
|
233
|
+
for(k = 0; k < buf->channels; k++) {
|
234
|
+
data[read * buf->channels + k] = temp[i];
|
235
|
+
}
|
236
|
+
read++;
|
237
|
+
}
|
238
|
+
}
|
239
|
+
} else {
|
240
|
+
rb_raise(eRubyAudioError, "unsupported mix from %d to %d", buf->channels, info->channels);
|
241
|
+
}
|
242
|
+
|
243
|
+
buf->real_size = read;
|
244
|
+
}
|
245
|
+
|
246
|
+
static void ra_sound_read_float(RA_SOUND *snd, RA_BUFFER *buf, sf_count_t frames) {
|
247
|
+
static float temp[1024];
|
248
|
+
int temp_len = 1024;
|
249
|
+
float *data = (float*)buf->data;
|
250
|
+
|
251
|
+
// Get info struct
|
252
|
+
SF_INFO *info;
|
253
|
+
Data_Get_Struct(snd->info, SF_INFO, info);
|
254
|
+
|
255
|
+
// Up/Downmix based on channel matching
|
256
|
+
sf_count_t read = 0, r, amount;
|
257
|
+
int i, k;
|
258
|
+
if(buf->channels == info->channels) { // Simply read data without mix
|
259
|
+
read = sf_readf_float(snd->snd, data, frames);
|
260
|
+
} else if(buf->channels == 1) { // Downmix to mono
|
261
|
+
sf_count_t max = temp_len / info->channels;
|
262
|
+
int channels, mix_sum;
|
263
|
+
|
264
|
+
while(read < frames) {
|
265
|
+
// Calculate # of frames to read
|
266
|
+
amount = frames - read;
|
267
|
+
if(amount > max) amount = max;
|
268
|
+
|
269
|
+
r = sf_readf_float(snd->snd, temp, amount);
|
270
|
+
if(r == 0) break;
|
271
|
+
|
272
|
+
// Mix channels together by averaging all channels and store to buffer
|
273
|
+
for(i = 0; i < r; i++) {
|
274
|
+
mix_sum = 0;
|
275
|
+
for(k = 0; k < info->channels; k++) mix_sum += temp[i * info->channels + k];
|
276
|
+
data[read] = mix_sum/info->channels;
|
277
|
+
read++;
|
278
|
+
}
|
279
|
+
}
|
280
|
+
} else if(info->channels == 1) { // Upmix from mono by copying channel
|
281
|
+
while(read < frames) {
|
282
|
+
// Calculate # of frames to read
|
283
|
+
amount = frames - read;
|
284
|
+
if(amount > temp_len) amount = temp_len;
|
285
|
+
|
286
|
+
r = sf_readf_float(snd->snd, temp, amount);
|
287
|
+
if(r == 0) break;
|
288
|
+
|
289
|
+
// Write every frame channel times to the buffer
|
290
|
+
for(i = 0; i < r; i++) {
|
291
|
+
for(k = 0; k < buf->channels; k++) {
|
292
|
+
data[read * buf->channels + k] = temp[i];
|
293
|
+
}
|
294
|
+
read++;
|
295
|
+
}
|
296
|
+
}
|
297
|
+
} else {
|
298
|
+
rb_raise(eRubyAudioError, "unsupported mix from %d to %d", buf->channels, info->channels);
|
299
|
+
}
|
300
|
+
|
301
|
+
buf->real_size = read;
|
302
|
+
}
|
303
|
+
|
304
|
+
static void ra_sound_read_double(RA_SOUND *snd, RA_BUFFER *buf, sf_count_t frames) {
|
305
|
+
static double temp[1024];
|
306
|
+
int temp_len = 1024;
|
307
|
+
double *data = (double*)buf->data;
|
308
|
+
|
309
|
+
// Get info struct
|
310
|
+
SF_INFO *info;
|
311
|
+
Data_Get_Struct(snd->info, SF_INFO, info);
|
312
|
+
|
313
|
+
// Up/Downmix based on channel matching
|
314
|
+
sf_count_t read = 0, r, amount;
|
315
|
+
int i, k;
|
316
|
+
if(buf->channels == info->channels) { // Simply read data without mix
|
317
|
+
read = sf_readf_double(snd->snd, data, frames);
|
318
|
+
} else if(buf->channels == 1) { // Downmix to mono
|
319
|
+
sf_count_t max = temp_len / info->channels;
|
320
|
+
int channels, mix_sum;
|
321
|
+
|
322
|
+
while(read < frames) {
|
323
|
+
// Calculate # of frames to read
|
324
|
+
amount = frames - read;
|
325
|
+
if(amount > max) amount = max;
|
326
|
+
|
327
|
+
r = sf_readf_double(snd->snd, temp, amount);
|
328
|
+
if(r == 0) break;
|
329
|
+
|
330
|
+
// Mix channels together by averaging all channels and store to buffer
|
331
|
+
for(i = 0; i < r; i++) {
|
332
|
+
mix_sum = 0;
|
333
|
+
for(k = 0; k < info->channels; k++) mix_sum += temp[i * info->channels + k];
|
334
|
+
data[read] = mix_sum/info->channels;
|
335
|
+
read++;
|
336
|
+
}
|
337
|
+
}
|
338
|
+
} else if(info->channels == 1) { // Upmix from mono by copying channel
|
339
|
+
while(read < frames) {
|
340
|
+
// Calculate # of frames to read
|
341
|
+
amount = frames - read;
|
342
|
+
if(amount > temp_len) amount = temp_len;
|
343
|
+
|
344
|
+
r = sf_readf_double(snd->snd, temp, amount);
|
345
|
+
if(r == 0) break;
|
346
|
+
|
347
|
+
// Write every frame channel times to the buffer
|
348
|
+
for(i = 0; i < r; i++) {
|
349
|
+
for(k = 0; k < buf->channels; k++) {
|
350
|
+
data[read * buf->channels + k] = temp[i];
|
351
|
+
}
|
352
|
+
read++;
|
353
|
+
}
|
354
|
+
}
|
355
|
+
} else {
|
356
|
+
rb_raise(eRubyAudioError, "unsupported mix from %d to %d", buf->channels, info->channels);
|
357
|
+
}
|
358
|
+
|
359
|
+
buf->real_size = read;
|
360
|
+
}
|
361
|
+
|
130
362
|
/*
|
131
363
|
* call-seq:
|
132
364
|
* snd.read(buf, frames) => integer
|
@@ -143,39 +375,35 @@ static VALUE ra_sound_read(VALUE self, VALUE buf, VALUE frames) {
|
|
143
375
|
RA_BUFFER *b;
|
144
376
|
Data_Get_Struct(buf, RA_BUFFER, b);
|
145
377
|
|
146
|
-
// Get info struct
|
147
|
-
SF_INFO *info;
|
148
|
-
Data_Get_Struct(snd->info, SF_INFO, info);
|
149
|
-
|
150
|
-
// Check buffer channels matches actual channels
|
151
|
-
if(b->channels != info->channels) {
|
152
|
-
rb_raise(eRubyAudioError, "channel count mismatch: %d vs %d", b->channels, info->channels);
|
153
|
-
}
|
154
|
-
|
155
378
|
// Double-check frame count against buffer size
|
156
379
|
sf_count_t f = (sf_count_t)NUM2OFFT(frames);
|
157
380
|
if(f < 0 || f > b->size) {
|
158
381
|
rb_raise(eRubyAudioError, "frame count invalid");
|
159
382
|
}
|
160
383
|
|
161
|
-
//
|
162
|
-
|
384
|
+
// Shortcut for 0 frame reads
|
385
|
+
if(f == 0) {
|
386
|
+
b->real_size = 0;
|
387
|
+
return INT2FIX(b->real_size);;
|
388
|
+
}
|
389
|
+
|
390
|
+
// Read based on type
|
163
391
|
switch(b->type) {
|
164
392
|
case RA_BUFFER_TYPE_SHORT:
|
165
|
-
|
393
|
+
ra_sound_read_short(snd, b, f);
|
166
394
|
break;
|
167
395
|
case RA_BUFFER_TYPE_INT:
|
168
|
-
|
396
|
+
ra_sound_read_int(snd, b, f);
|
169
397
|
break;
|
170
398
|
case RA_BUFFER_TYPE_FLOAT:
|
171
|
-
|
399
|
+
ra_sound_read_float(snd, b, f);
|
172
400
|
break;
|
173
401
|
case RA_BUFFER_TYPE_DOUBLE:
|
174
|
-
|
402
|
+
ra_sound_read_double(snd, b, f);
|
175
403
|
break;
|
176
404
|
}
|
177
|
-
b->real_size = read;
|
178
405
|
|
406
|
+
// Return read
|
179
407
|
return INT2FIX(b->real_size);
|
180
408
|
}
|
181
409
|
|
data/spec/buffer_spec.rb
CHANGED
@@ -47,4 +47,16 @@ describe RubyAudio::Buffer do
|
|
47
47
|
buf.real_size = 101
|
48
48
|
buf.real_size.should == 100
|
49
49
|
end
|
50
|
+
|
51
|
+
it "should support cloning/duping" do
|
52
|
+
buf = RubyAudio::Buffer.int(100)
|
53
|
+
buf[4] = 100
|
54
|
+
|
55
|
+
buf2 = buf.dup
|
56
|
+
buf2.size.should == buf.size
|
57
|
+
buf2[4].should == 100
|
58
|
+
|
59
|
+
buf[4] = 140
|
60
|
+
buf2[4].should == 100
|
61
|
+
end
|
50
62
|
end
|
data/spec/sound_spec.rb
CHANGED
@@ -100,13 +100,38 @@ describe RubyAudio::Sound do
|
|
100
100
|
buf[100].should == nil
|
101
101
|
end
|
102
102
|
|
103
|
-
it "should
|
104
|
-
buf = RubyAudio::Buffer.
|
103
|
+
it "should allow downmixing to mono on read" do
|
104
|
+
buf = RubyAudio::Buffer.int(100, 1)
|
105
|
+
buf2 = RubyAudio::Buffer.int(100, 2)
|
106
|
+
RubyAudio::Sound.open(STEREO_TEST_WAV, 'r') do |snd|
|
107
|
+
snd.read(buf)
|
108
|
+
snd.seek(0)
|
109
|
+
snd.read(buf2)
|
110
|
+
|
111
|
+
f = buf2[99]
|
112
|
+
buf[99].should == (f[0] + f[1]) / 2
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should allow upmixing from mono on read" do
|
117
|
+
buf = RubyAudio::Buffer.int(100, 1)
|
118
|
+
buf2 = RubyAudio::Buffer.int(100, 2)
|
119
|
+
RubyAudio::Sound.open(STEREO_TEST_WAV, 'r') do |snd|
|
120
|
+
snd.read(buf2)
|
121
|
+
snd.seek(0)
|
122
|
+
snd.read(buf)
|
123
|
+
|
124
|
+
buf2[99].should == [buf[99], buf[99]]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should fail read on unsupported up/downmixing" do
|
129
|
+
buf = RubyAudio::Buffer.float(100, 5)
|
105
130
|
lambda {
|
106
131
|
RubyAudio::Sound.open(STEREO_TEST_WAV) do |snd|
|
107
132
|
snd.read(buf)
|
108
133
|
end
|
109
|
-
}.should raise_error(RubyAudio::Error, "
|
134
|
+
}.should raise_error(RubyAudio::Error, "unsupported mix from 5 to 2")
|
110
135
|
end
|
111
136
|
|
112
137
|
it "should allow writing to a new sound" do
|
@@ -144,4 +169,14 @@ describe RubyAudio::Sound do
|
|
144
169
|
|
145
170
|
out_buf[50].should == in_buf[50]
|
146
171
|
end
|
172
|
+
|
173
|
+
it "should fail write on channel mismatch" do
|
174
|
+
buf = RubyAudio::Buffer.float(100, 5)
|
175
|
+
info = RubyAudio::SoundInfo.new :channels => 2, :samplerate => 48000, :format => RubyAudio::FORMAT_WAV|RubyAudio::FORMAT_PCM_16
|
176
|
+
lambda {
|
177
|
+
RubyAudio::Sound.open(OUT_WAV, 'w', info) do |snd|
|
178
|
+
snd.write(buf)
|
179
|
+
end
|
180
|
+
}.should raise_error(RubyAudio::Error, "channel count mismatch: 5 vs 2")
|
181
|
+
end
|
147
182
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-audio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Augenstein
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-03-
|
12
|
+
date: 2010-03-24 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|