coreaudio 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,6 +2,7 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
+ gem "narray", "~> 0.6.0.0"
5
6
 
6
7
  # Add dependencies to develop your gem here.
7
8
  # Include everything needed to run rake, tests, features, etc.
@@ -6,6 +6,7 @@ GEM
6
6
  bundler (~> 1.0)
7
7
  git (>= 1.2.5)
8
8
  rake
9
+ narray (0.6.0.1)
9
10
  rake (0.9.2)
10
11
  rdoc (3.9.2)
11
12
 
@@ -15,5 +16,6 @@ PLATFORMS
15
16
  DEPENDENCIES
16
17
  bundler (~> 1.0.0)
17
18
  jeweler (~> 1.6.4)
19
+ narray (~> 0.6.0.0)
18
20
  rake (~> 0.9.2)
19
21
  rdoc
@@ -12,7 +12,6 @@ CoreAudio (Audio Framework of Mac OS X) wrapper library for ruby 1.9
12
12
  * Ream audio file (WAV/M4A)
13
13
 
14
14
  == ToDo
15
- * Switch input/output audio sample type (signed 16bit integer, packed String)
16
15
  * Wrapper for AudioUnit/AudioGraph
17
16
 
18
17
  == Contributing to coreaudio
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "coreaudio"
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["CHIKANAGA Tomoyuki"]
12
- s.date = "2011-10-16"
12
+ s.date = "2011-10-28"
13
13
  s.description = "Mac OS X CoreAudio wrapper library"
14
14
  s.email = "nagachika00@gmail.com"
15
15
  s.extensions = ["ext/extconf.rb"]
@@ -27,16 +27,20 @@ Gem::Specification.new do |s|
27
27
  "VERSION",
28
28
  "coreaudio.gemspec",
29
29
  "examples/convert_wav_to_m4a.rb",
30
+ "examples/fft_shift_pitch.rb",
31
+ "examples/loopback_delay.rb",
30
32
  "examples/outbuffer_sine.rb",
31
33
  "examples/outloop_sine.rb",
32
34
  "examples/record_to_wave.rb",
35
+ "examples/ring_modulator.rb",
33
36
  "ext/audiofile.m",
34
37
  "ext/coreaudio.h",
35
38
  "ext/coreaudio.m",
36
39
  "ext/coreaudio_missing.c",
37
40
  "ext/depend",
38
41
  "ext/extconf.rb",
39
- "lib/coreaudio.rb"
42
+ "lib/coreaudio.rb",
43
+ "lib/coreaudio/audiofile.rb"
40
44
  ]
41
45
  s.homepage = "https://github.com/nagachika/ruby-coreaudio"
42
46
  s.licenses = ["BSDL"]
@@ -48,17 +52,20 @@ Gem::Specification.new do |s|
48
52
  s.specification_version = 3
49
53
 
50
54
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
55
+ s.add_runtime_dependency(%q<narray>, ["~> 0.6.0.0"])
51
56
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
52
57
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
53
58
  s.add_development_dependency(%q<rake>, ["~> 0.9.2"])
54
59
  s.add_development_dependency(%q<rdoc>, [">= 0"])
55
60
  else
61
+ s.add_dependency(%q<narray>, ["~> 0.6.0.0"])
56
62
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
63
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
58
64
  s.add_dependency(%q<rake>, ["~> 0.9.2"])
59
65
  s.add_dependency(%q<rdoc>, [">= 0"])
60
66
  end
61
67
  else
68
+ s.add_dependency(%q<narray>, ["~> 0.6.0.0"])
62
69
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
63
70
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
64
71
  s.add_dependency(%q<rake>, ["~> 0.9.2"])
@@ -6,11 +6,11 @@ wav = CoreAudio::AudioFile.new("sample.wav", :read)
6
6
 
7
7
  m4a = CoreAudio::AudioFile.new("sample.m4a", :write, :format => :m4a,
8
8
  :rate => wav.rate,
9
- :channel => wav.channel)
9
+ :channels => wav.channels)
10
10
 
11
11
  loop do
12
12
  buf = wav.read(1024)
13
- break if buf.empty?
13
+ break if buf.nil?
14
14
  m4a.write(buf)
15
15
  end
16
16
 
@@ -0,0 +1,47 @@
1
+
2
+ require "thread"
3
+ require "fftw3"
4
+ require "coreaudio"
5
+
6
+ Thread.abort_on_exception = true
7
+
8
+ inbuf = CoreAudio.default_input_device.input_buffer(1024)
9
+ outbuf = CoreAudio.default_output_device.output_buffer(1024)
10
+
11
+ queue = Queue.new
12
+ pitch_shift_th = Thread.start do
13
+ while w = queue.pop
14
+ half = w.shape[1] / 2
15
+ f = FFTW3.fft(w, 1)
16
+ shift = 12
17
+ f.shape[0].times do |ch|
18
+ f[ch, shift...half] = f[ch, 0...(half-shift)]
19
+ f[ch, 0...shift] = 0
20
+ f[ch, half...(w.shape[1]-shift)] = f[ch, (half+shift)..-1]
21
+ f[ch, -shift..-1] = 0
22
+ end
23
+ outbuf << FFTW3.ifft(f, 1) / w.shape[1]
24
+ end
25
+ end
26
+
27
+ th = Thread.start do
28
+ loop do
29
+ wav = inbuf.read(1024)
30
+ queue.push(wav)
31
+ end
32
+ end
33
+
34
+ inbuf.start
35
+ outbuf.start
36
+ $stdout.print "loopback..."
37
+ $stdout.flush
38
+ sleep 10;
39
+ queue.push(nil)
40
+ inbuf.stop
41
+ outbuf.stop
42
+ $stdout.puts "done."
43
+ th.kill.join
44
+ pitch_shift_th.kill.join
45
+
46
+ puts "#{inbuf.dropped_frame} frame dropped at input buffer."
47
+ puts "#{outbuf.dropped_frame} frame dropped at output buffer."
@@ -0,0 +1,30 @@
1
+
2
+ require "coreaudio"
3
+
4
+ inbuf = CoreAudio.default_input_device.input_buffer(1024)
5
+ outbuf = CoreAudio.default_output_device.output_buffer(1024)
6
+
7
+ th = Thread.start do
8
+ ary = []
9
+ loop do
10
+ wav = inbuf.read(1024)
11
+ ary.push(wav)
12
+ # 1024*43 frames delayed. about 1 sec when sample rate = 44100Hz
13
+ if ary.size > 43
14
+ outbuf << ary.shift
15
+ end
16
+ end
17
+ end
18
+
19
+ inbuf.start
20
+ outbuf.start
21
+ $stdout.print "loopback..."
22
+ $stdout.flush
23
+ sleep 10;
24
+ inbuf.stop
25
+ outbuf.stop
26
+ $stdout.puts "done."
27
+ th.kill.join
28
+
29
+ puts "#{inbuf.dropped_frame} frame dropped at input buffer."
30
+ puts "#{outbuf.dropped_frame} frame dropped at output buffer."
@@ -6,8 +6,9 @@ buf = dev.output_buffer(1024)
6
6
  phase = Math::PI * 2.0 * 440.0 / dev.nominal_rate
7
7
  th = Thread.start do
8
8
  i = 0
9
+ wav = NArray.sint(1024)
9
10
  loop do
10
- wav = Array.new(1024){|j| (0.4 * Math.sin(phase*(i+j)) * 0x7FFF).round }
11
+ 1024.times {|j| wav[j] = (0.4 * Math.sin(phase*(i+j)) * 0x7FFF).round }
11
12
  i += 1024
12
13
  buf << wav
13
14
  end
@@ -19,4 +20,4 @@ buf.stop
19
20
 
20
21
  puts "#{buf.dropped_frame} frame dropped."
21
22
 
22
- th.kill
23
+ th.kill.join
@@ -6,7 +6,7 @@ buf = dev.input_buffer(1024)
6
6
 
7
7
  wav = CoreAudio::AudioFile.new("sample.wav", :write, :format => :wav,
8
8
  :rate => dev.nominal_rate,
9
- :channel => dev.input_stream.channels)
9
+ :channels => dev.input_stream.channels)
10
10
 
11
11
  samples = 0
12
12
  th = Thread.start do
@@ -0,0 +1,42 @@
1
+
2
+ require "thread"
3
+ require "coreaudio"
4
+
5
+ Thread.abort_on_exception = true
6
+
7
+ inbuf = CoreAudio.default_input_device.input_buffer(1024)
8
+ outbuf = CoreAudio.default_output_device.output_buffer(1024)
9
+
10
+ queue = Queue.new
11
+ output_th = Thread.start do
12
+ filter = NArray.float(2, 1024)
13
+ filter.shape[1].times do |i|
14
+ filter[true, i] = (i % 256 - 128) / 128.0
15
+ end
16
+
17
+ while w = queue.pop
18
+ outbuf << w * filter
19
+ end
20
+ end
21
+
22
+ input_th = Thread.start do
23
+ loop do
24
+ wav = inbuf.read(1024)
25
+ queue.push(wav)
26
+ end
27
+ end
28
+
29
+ inbuf.start
30
+ outbuf.start
31
+ $stdout.print "loopback..."
32
+ $stdout.flush
33
+ sleep 10;
34
+ queue.push(nil)
35
+ inbuf.stop
36
+ outbuf.stop
37
+ $stdout.puts "done."
38
+ input_th.kill.join
39
+ output_th.kill.join
40
+
41
+ puts "#{inbuf.dropped_frame} frame dropped at input buffer."
42
+ puts "#{outbuf.dropped_frame} frame dropped at output buffer."
@@ -14,7 +14,7 @@
14
14
  VALUE rb_cAudioFile;
15
15
 
16
16
  static VALUE sym_read, sym_write, sym_format;
17
- static VALUE sym_rate, sym_file_rate, sym_channel, sym_file_channel;
17
+ static VALUE sym_rate, sym_file_rate, sym_channels, sym_file_channels;
18
18
  static VALUE sym_wav, sym_m4a;
19
19
 
20
20
  static void
@@ -22,7 +22,7 @@ setASBD(AudioStreamBasicDescription *asbd,
22
22
  Float64 rate,
23
23
  UInt32 format,
24
24
  UInt32 flags,
25
- UInt32 channel,
25
+ UInt32 channels,
26
26
  UInt32 bitsPerChannel,
27
27
  UInt32 framePerPacket)
28
28
  {
@@ -30,10 +30,10 @@ setASBD(AudioStreamBasicDescription *asbd,
30
30
  asbd->mFormatID = format;
31
31
  asbd->mFormatFlags = flags;
32
32
  asbd->mBitsPerChannel = bitsPerChannel;
33
- asbd->mChannelsPerFrame = channel;
33
+ asbd->mChannelsPerFrame = channels;
34
34
  asbd->mFramesPerPacket = framePerPacket;
35
- asbd->mBytesPerFrame = bitsPerChannel/8*channel;
36
- asbd->mBytesPerPacket = bitsPerChannel/8*channel*framePerPacket;
35
+ asbd->mBytesPerFrame = bitsPerChannel/8*channels;
36
+ asbd->mBytesPerPacket = bitsPerChannel/8*channels*framePerPacket;
37
37
  }
38
38
 
39
39
  typedef struct {
@@ -80,7 +80,7 @@ ca_audio_file_alloc(VALUE klass)
80
80
  static void
81
81
  parse_audio_file_options(VALUE opt, Boolean for_write,
82
82
  Float64 *rate, Float64 *file_rate,
83
- UInt32 *channel, UInt32 *file_channel)
83
+ UInt32 *channels, UInt32 *file_channels)
84
84
  {
85
85
  if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_rate))) {
86
86
  if (for_write)
@@ -90,13 +90,13 @@ parse_audio_file_options(VALUE opt, Boolean for_write,
90
90
  } else {
91
91
  *rate = NUM2DBL(rb_hash_aref(opt, sym_rate));
92
92
  }
93
- if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_channel))) {
93
+ if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_channels))) {
94
94
  if (for_write)
95
- *channel = 2;
95
+ *channels = 2;
96
96
  else
97
- *channel = *file_channel;
97
+ *channels = *file_channels;
98
98
  } else {
99
- *channel = NUM2UINT(rb_hash_aref(opt, sym_channel));
99
+ *channels = NUM2UINT(rb_hash_aref(opt, sym_channels));
100
100
  }
101
101
 
102
102
  if (for_write) {
@@ -105,10 +105,10 @@ parse_audio_file_options(VALUE opt, Boolean for_write,
105
105
  } else {
106
106
  *file_rate = NUM2DBL(rb_hash_aref(opt, sym_file_rate));
107
107
  }
108
- if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_file_channel))) {
109
- *file_channel = *channel;
108
+ if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_file_channels))) {
109
+ *file_channels = *channels;
110
110
  } else {
111
- *file_channel = NUM2UINT(rb_hash_aref(opt, sym_file_channel));
111
+ *file_channels = NUM2UINT(rb_hash_aref(opt, sym_file_channels));
112
112
  }
113
113
  }
114
114
  }
@@ -128,9 +128,9 @@ parse_audio_file_options(VALUE opt, Boolean for_write,
128
128
  * codec type is hardcoded. (:wav, :m4a)
129
129
  * :rate :: sample rate of data pass from AudioFile#read or to AudioFile#write
130
130
  * If not specified, :file_rate value is used. (Float)
131
- * :channel :: number of channels
131
+ * :channels :: number of channels
132
132
  * :file_rate :: file data sample rate. only work when open for output. (Float)
133
- * :file_channel :: file data number of channels. only work when open for
133
+ * :file_channels :: file data number of channels. only work when open for
134
134
  * output.
135
135
  */
136
136
  static VALUE
@@ -139,7 +139,7 @@ ca_audio_file_initialize(int argc, VALUE *argv, VALUE self)
139
139
  ca_audio_file_t *data;
140
140
  VALUE path, mode, opt, format;
141
141
  Float64 rate, file_rate;
142
- UInt32 channel, file_channel;
142
+ UInt32 channels, file_channels;
143
143
  CFURLRef url = NULL;
144
144
  AudioFileTypeID filetype = 0;
145
145
  OSStatus err = noErr;
@@ -159,7 +159,7 @@ ca_audio_file_initialize(int argc, VALUE *argv, VALUE self)
159
159
  if (data->for_write) {
160
160
  /* when open for write, parse options before open ExtAudioFile */
161
161
  parse_audio_file_options(opt, data->for_write, &rate, &file_rate,
162
- &channel, &file_channel);
162
+ &channels, &file_channels);
163
163
 
164
164
  format = rb_hash_aref(opt, sym_format);
165
165
  if (NIL_P(format))
@@ -170,11 +170,11 @@ ca_audio_file_initialize(int argc, VALUE *argv, VALUE self)
170
170
  setASBD(&data->file_desc, file_rate, kAudioFormatLinearPCM,
171
171
  kLinearPCMFormatFlagIsSignedInteger |
172
172
  kAudioFormatFlagIsPacked,
173
- file_channel, 16, 1);
173
+ file_channels, 16, 1);
174
174
  } else if (format == sym_m4a) {
175
175
  filetype = kAudioFileM4AType;
176
176
  setASBD(&data->file_desc, file_rate, kAudioFormatMPEG4AAC,
177
- 0, file_channel, 0, 0);
177
+ 0, file_channels, 0, 0);
178
178
  } else {
179
179
  volatile VALUE str = rb_inspect(format);
180
180
  RB_GC_GUARD(str);
@@ -213,14 +213,14 @@ ca_audio_file_initialize(int argc, VALUE *argv, VALUE self)
213
213
 
214
214
  /* parse options */
215
215
  file_rate = data->file_desc.mSampleRate;
216
- file_channel = data->file_desc.mChannelsPerFrame;
216
+ file_channels = data->file_desc.mChannelsPerFrame;
217
217
  parse_audio_file_options(opt, data->for_write, &rate, &file_rate,
218
- &channel, &file_channel);
218
+ &channels, &file_channels);
219
219
  }
220
220
 
221
221
  setASBD(&data->inner_desc, rate, kAudioFormatLinearPCM,
222
222
  kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked,
223
- channel, 16, 1);
223
+ channels, 16, 1);
224
224
 
225
225
  err = ExtAudioFileSetProperty(
226
226
  data->file, kExtAudioFileProperty_ClientDataFormat,
@@ -253,16 +253,20 @@ static VALUE
253
253
  ca_audio_file_write(VALUE self, VALUE data)
254
254
  {
255
255
  ca_audio_file_t *file;
256
- short *buf;
256
+ UInt32 n_ch;
257
+ int rank;
258
+ short *buf = NULL;
257
259
  AudioBufferList buf_list;
258
260
  UInt32 frames;
259
261
  size_t alloc_size;
260
- volatile VALUE tmpstr;
262
+ volatile VALUE tmpstr = Qundef;
261
263
  OSStatus err = noErr;
262
- int i;
263
264
 
264
- if (!RB_TYPE_P(data, T_ARRAY))
265
- rb_raise(rb_eArgError, "coreaudio: audio buffer must be an array");
265
+ /* cast to NArray of SINT and check rank of NArray */
266
+ data = na_cast_object(data, NA_SINT);
267
+ rank = NA_RANK(data);
268
+ if (rank > 3)
269
+ rb_raise(rb_eArgError, "coreaudio: audio buffer rank must be 1 or 2.");
266
270
 
267
271
  TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, file);
268
272
 
@@ -272,23 +276,42 @@ ca_audio_file_write(VALUE self, VALUE data)
272
276
  if (!file->for_write)
273
277
  rb_raise(rb_eRuntimeError, "coreaudio: audio file opened for reading");
274
278
 
275
- frames = RARRAY_LENINT(data) / file->inner_desc.mChannelsPerFrame;
276
- alloc_size = (file->inner_desc.mBitsPerChannel/8) * RARRAY_LEN(data);
279
+ n_ch = file->inner_desc.mChannelsPerFrame;
280
+
281
+ if (rank == 2 && NA_SHAPE0(data) != (int)n_ch)
282
+ rb_raise(rb_eArgError,
283
+ "coreaudio: audio buffer size of first dimension must be "
284
+ "equal to number of channels");
285
+
286
+ frames = rank == 1 ? NA_SHAPE0(data) : NA_SHAPE1(data);
287
+ alloc_size = (file->inner_desc.mBitsPerChannel/8) * frames * n_ch;
277
288
 
278
289
  /* prepare interleaved audio buffer */
279
290
  buf_list.mNumberBuffers = 1;
280
- buf_list.mBuffers[0].mNumberChannels = file->inner_desc.mChannelsPerFrame;
291
+ buf_list.mBuffers[0].mNumberChannels = n_ch;
281
292
  buf_list.mBuffers[0].mDataByteSize = (UInt32)alloc_size;
282
- buf_list.mBuffers[0].mData = rb_alloc_tmp_buffer(&tmpstr, alloc_size);
283
- buf = buf_list.mBuffers[0].mData;
284
293
 
285
- for (i = 0; i < RARRAY_LEN(data); i++) {
286
- buf[i] = (short)NUM2INT(RARRAY_PTR(data)[i]);
294
+ if ((rank == 1 && n_ch == 1) || rank == 2) {
295
+ /* no need to allocate buffer. NArray buffer can be used as mData */
296
+ buf_list.mBuffers[0].mData = NA_PTR_TYPE(data, void *);
297
+ } else {
298
+ UInt32 i, j;
299
+ short *na_buf = NA_PTR_TYPE(data, short *);
300
+
301
+ buf_list.mBuffers[0].mData = rb_alloc_tmp_buffer(&tmpstr, alloc_size);
302
+ buf = buf_list.mBuffers[0].mData;
303
+
304
+ for (i = 0; i < frames; i++) {
305
+ for (j = 0; j < n_ch; j++) {
306
+ buf[i*n_ch+j] = na_buf[i];
307
+ }
308
+ }
287
309
  }
288
310
 
289
311
  err = ExtAudioFileWrite(file->file, frames, &buf_list);
290
312
 
291
- rb_free_tmp_buffer(&tmpstr);
313
+ if (tmpstr != Qundef)
314
+ rb_free_tmp_buffer(&tmpstr);
292
315
 
293
316
  if (err != noErr) {
294
317
  rb_raise(rb_eRuntimeError,
@@ -299,19 +322,18 @@ ca_audio_file_write(VALUE self, VALUE data)
299
322
  }
300
323
 
301
324
  static VALUE
302
- ca_audio_file_read(int argc, VALUE *argv, VALUE self)
325
+ ca_audio_file_read_frames(VALUE self, VALUE frame_val)
303
326
  {
304
327
  ca_audio_file_t *file;
305
- VALUE frame_val;
306
- UInt32 frames, chunk, total, read_frames;
328
+ UInt32 channels, frames, read_frames;
307
329
  AudioBufferList buf_list;
308
- short *buf;
309
330
  size_t alloc_size;
310
- volatile VALUE tmpstr;
311
- VALUE ary;
312
- UInt32 i;
331
+ VALUE nary;
332
+ int shape[2];
313
333
  OSStatus err = noErr;
314
334
 
335
+ frames = NUM2UINT(frame_val);
336
+
315
337
  TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, file);
316
338
 
317
339
  if (file->file == NULL)
@@ -320,48 +342,34 @@ ca_audio_file_read(int argc, VALUE *argv, VALUE self)
320
342
  if (file->for_write)
321
343
  rb_raise(rb_eRuntimeError, "coreaudio: audio file open for writing");
322
344
 
323
- rb_scan_args(argc, argv, "01", &frame_val);
345
+ channels = file->inner_desc.mChannelsPerFrame;
324
346
 
325
- if (NIL_P(frame_val)) {
326
- frames = 0;
327
- chunk = 1024;
328
- } else {
329
- frames = chunk = NUM2UINT(frame_val);
330
- }
347
+ shape[0] = channels;
348
+ shape[1] = frames;
349
+ nary = na_make_object(NA_SINT, 2, shape, cNArray);
331
350
 
332
- alloc_size = (file->inner_desc.mBitsPerChannel/8) *
333
- file->inner_desc.mChannelsPerFrame * chunk;
351
+ alloc_size = (file->inner_desc.mBitsPerChannel/8) * channels * frames;
334
352
 
335
353
  /* prepare interleaved audio buffer */
336
354
  buf_list.mNumberBuffers = 1;
337
- buf_list.mBuffers[0].mNumberChannels = file->inner_desc.mChannelsPerFrame;
355
+ buf_list.mBuffers[0].mNumberChannels = channels;
338
356
  buf_list.mBuffers[0].mDataByteSize = (UInt32)alloc_size;
339
- buf_list.mBuffers[0].mData = rb_alloc_tmp_buffer(&tmpstr, alloc_size);
340
- buf = buf_list.mBuffers[0].mData;
357
+ buf_list.mBuffers[0].mData = NA_PTR_TYPE(nary, void *);
341
358
 
342
- ary = rb_ary_new2(chunk*file->inner_desc.mChannelsPerFrame);
359
+ read_frames = frames;
360
+ err = ExtAudioFileRead(file->file, &read_frames, &buf_list);
343
361
 
344
- for (total = 0; total < frames || frames == 0; total += read_frames) {
345
- read_frames = chunk;
346
- err = ExtAudioFileRead(file->file, &read_frames, &buf_list);
347
-
348
- if (err != noErr) {
349
- rb_free_tmp_buffer(&tmpstr);
350
- rb_raise(rb_eRuntimeError,
351
- "coreaudio: ExtAudioFileRead() fails: %d", (int)err);
352
- }
353
-
354
- if (read_frames == 0)
355
- break;
356
-
357
- for (i = 0; i < read_frames * file->inner_desc.mChannelsPerFrame; i++) {
358
- rb_ary_push(ary, INT2NUM((int)buf[i]));
359
- }
362
+ if (err != noErr) {
363
+ rb_raise(rb_eRuntimeError,
364
+ "coreaudio: ExtAudioFileRead() fails: %d", (int)err);
360
365
  }
361
366
 
362
- rb_free_tmp_buffer(&tmpstr);
367
+ if (read_frames == 0)
368
+ return Qnil;
369
+
370
+ NA_SHAPE1(nary) = read_frames;
363
371
 
364
- return ary;
372
+ return nary;
365
373
  }
366
374
 
367
375
  static VALUE
@@ -375,7 +383,7 @@ ca_audio_file_rate(VALUE self)
375
383
  }
376
384
 
377
385
  static VALUE
378
- ca_audio_file_channel(VALUE self)
386
+ ca_audio_file_channels(VALUE self)
379
387
  {
380
388
  ca_audio_file_t *data;
381
389
 
@@ -395,7 +403,7 @@ ca_audio_file_inner_rate(VALUE self)
395
403
  }
396
404
 
397
405
  static VALUE
398
- ca_audio_file_inner_channel(VALUE self)
406
+ ca_audio_file_inner_channels(VALUE self)
399
407
  {
400
408
  ca_audio_file_t *data;
401
409
 
@@ -412,8 +420,8 @@ Init_coreaudio_audiofile(void)
412
420
  sym_format = ID2SYM(rb_intern("format"));
413
421
  sym_rate = ID2SYM(rb_intern("rate"));
414
422
  sym_file_rate = ID2SYM(rb_intern("file_rate"));
415
- sym_channel = ID2SYM(rb_intern("channel"));
416
- sym_file_channel = ID2SYM(rb_intern("file_channel"));
423
+ sym_channels = ID2SYM(rb_intern("channels"));
424
+ sym_file_channels = ID2SYM(rb_intern("file_channels"));
417
425
  sym_wav = ID2SYM(rb_intern("wav"));
418
426
  sym_m4a = ID2SYM(rb_intern("m4a"));
419
427
 
@@ -424,9 +432,9 @@ Init_coreaudio_audiofile(void)
424
432
  rb_define_method(rb_cAudioFile, "initialize", ca_audio_file_initialize, -1);
425
433
  rb_define_method(rb_cAudioFile, "close", ca_audio_file_close, 0);
426
434
  rb_define_method(rb_cAudioFile, "write", ca_audio_file_write, 1);
427
- rb_define_method(rb_cAudioFile, "read", ca_audio_file_read, -1);
435
+ rb_define_method(rb_cAudioFile, "read_frames", ca_audio_file_read_frames, 1);
428
436
  rb_define_method(rb_cAudioFile, "rate", ca_audio_file_rate, 0);
429
- rb_define_method(rb_cAudioFile, "channel", ca_audio_file_channel, 0);
437
+ rb_define_method(rb_cAudioFile, "channels", ca_audio_file_channels, 0);
430
438
  rb_define_method(rb_cAudioFile, "inner_rate", ca_audio_file_inner_rate, 0);
431
- rb_define_method(rb_cAudioFile, "inner_channel", ca_audio_file_inner_channel, 0);
439
+ rb_define_method(rb_cAudioFile, "inner_channels", ca_audio_file_inner_channels, 0);
432
440
  }
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include <ruby.h>
5
5
 
6
+ #include "narray.h"
6
7
  #include "extconf.h"
7
8
 
8
9
  extern VALUE rb_mCoreAudio;
@@ -374,7 +374,7 @@ typedef struct {
374
374
  AudioDeviceID devID;
375
375
  AudioDeviceIOProcID procID;
376
376
  UInt32 frame;
377
- UInt32 channel;
377
+ UInt32 channels;
378
378
  short *buf;
379
379
  } ca_out_loop_data;
380
380
 
@@ -395,7 +395,7 @@ static size_t
395
395
  ca_out_loop_data_memsize(const void *ptr)
396
396
  {
397
397
  const ca_out_loop_data *data = ptr;
398
- return sizeof(ca_out_loop_data) + data->channel * data->frame * sizeof(short);
398
+ return sizeof(ca_out_loop_data) + data->channels * data->frame * sizeof(short);
399
399
  }
400
400
 
401
401
  static const rb_data_type_t ca_out_loop_data_type = {
@@ -416,16 +416,16 @@ ca_out_loop_proc(
416
416
  NSUInteger i;
417
417
  UInt32 buffers = outOutputData->mNumberBuffers;
418
418
  ca_out_loop_data *loop_data = inClientData;
419
- UInt32 channel = loop_data->channel;
419
+ UInt32 channels = loop_data->channels;
420
420
 
421
421
  for (i = 0; i < buffers; i++) {
422
422
  float *ptr = outOutputData->mBuffers[i].mData;
423
- UInt32 size = outOutputData->mBuffers[i].mDataByteSize / (UInt32)sizeof(float) / channel;
423
+ UInt32 size = outOutputData->mBuffers[i].mDataByteSize / (UInt32)sizeof(float) / channels;
424
424
  UInt32 offset = (UInt32)inOutputTime->mSampleTime % loop_data->frame;
425
425
  UInt32 copied = 0;
426
426
 
427
- if (outOutputData->mBuffers[i].mNumberChannels != channel) {
428
- memset(ptr, 0, size * channel * sizeof(float));
427
+ if (outOutputData->mBuffers[i].mNumberChannels != channels) {
428
+ memset(ptr, 0, size * channels * sizeof(float));
429
429
  continue;
430
430
  }
431
431
 
@@ -434,8 +434,8 @@ ca_out_loop_proc(
434
434
  UInt32 j;
435
435
  if ( len > size - copied )
436
436
  len = size - copied;
437
- for (j = 0; j < len*channel; j++) {
438
- ptr[copied*channel+j] = SHORT2FLOAT(loop_data->buf[offset*channel+j]);
437
+ for (j = 0; j < len*channels; j++) {
438
+ ptr[copied*channels+j] = SHORT2FLOAT(loop_data->buf[offset*channels+j]);
439
439
  }
440
440
  offset = (offset + len) % loop_data->frame;
441
441
  copied += len;
@@ -456,7 +456,7 @@ ca_out_loop_data_alloc(VALUE klass)
456
456
  }
457
457
 
458
458
  static VALUE
459
- ca_out_loop_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channel)
459
+ ca_out_loop_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channels)
460
460
  {
461
461
  ca_out_loop_data *data;
462
462
  OSStatus status;
@@ -469,8 +469,8 @@ ca_out_loop_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channel)
469
469
  rb_raise(rb_eRuntimeError, "coreaudio: create proc ID fail: %d", status);
470
470
  }
471
471
  data->frame = NUM2UINT(frame);
472
- data->channel = NUM2UINT(channel);
473
- data->buf = malloc(sizeof(short)*data->frame*data->channel);
472
+ data->channels = NUM2UINT(channels);
473
+ data->buf = malloc(sizeof(short)*data->frame*data->channels);
474
474
  if (data->buf == NULL)
475
475
  rb_raise(rb_eNoMemError, "coreaudio: fail to alloc out loop data buffer");
476
476
  return self;
@@ -550,7 +550,7 @@ ca_out_loop_data_stop(VALUE self)
550
550
  *
551
551
  * Assign audio loop buffer frame value.
552
552
  * If assigned value is an Fixnum (-32767..32767, signed 16bit),
553
- * the value is stored to all channel.
553
+ * the value is stored to all channels.
554
554
  * The +sample+ should be normalize to -32767 <= sample <= 32767 range.
555
555
  * If assigned value is an Array of Fixnum, each value is stored to each
556
556
  * correponding channel. If size of array is not equal to the AudioDevice's
@@ -567,15 +567,15 @@ ca_out_loop_data_assign(VALUE self, VALUE index, VALUE val)
567
567
 
568
568
  idx = NUM2UINT(index) % data->frame;
569
569
  if (TYPE(val) == T_ARRAY) {
570
- if (RARRAY_LEN(val) != data->channel) {
570
+ if (RARRAY_LEN(val) != data->channels) {
571
571
  rb_raise(rb_eArgError, "size of array and channel size mismatch");
572
572
  }
573
- for (i = 0; i < data->channel; i++) {
574
- data->buf[idx*data->channel+i] = (short)NUM2INT(RARRAY_PTR(val)[i]);
573
+ for (i = 0; i < data->channels; i++) {
574
+ data->buf[idx*data->channels+i] = (short)NUM2INT(RARRAY_PTR(val)[i]);
575
575
  }
576
576
  } else {
577
- for (i = 0; i < data->channel; i++) {
578
- data->buf[idx*data->channel+i] = (short)NUM2INT(val);
577
+ for (i = 0; i < data->channels; i++) {
578
+ data->buf[idx*data->channels+i] = (short)NUM2INT(val);
579
579
  }
580
580
  }
581
581
  return val;
@@ -585,7 +585,7 @@ typedef struct {
585
585
  AudioDeviceID devID;
586
586
  AudioDeviceIOProcID procID;
587
587
  UInt32 frame;
588
- UInt32 channel;
588
+ UInt32 channels;
589
589
  short *buf;
590
590
  UInt32 start;
591
591
  UInt32 end;
@@ -613,7 +613,7 @@ static size_t
613
613
  ca_buffer_data_memsize(const void *ptr)
614
614
  {
615
615
  const ca_buffer_data *data = ptr;
616
- return sizeof(ca_buffer_data) + data->channel * data->frame * sizeof(short);
616
+ return sizeof(ca_buffer_data) + data->channels * data->frame * sizeof(short);
617
617
  }
618
618
 
619
619
  static const rb_data_type_t ca_buffer_data_type = {
@@ -754,31 +754,31 @@ ca_out_buffer_proc(
754
754
  NSUInteger n_buf;
755
755
  UInt32 buffers = outOutputData->mNumberBuffers;
756
756
  ca_buffer_data *buffer_data = inClientData;
757
- UInt32 channel = buffer_data->channel;
757
+ UInt32 channels = buffer_data->channels;
758
758
 
759
759
  for (n_buf = 0; n_buf < buffers; n_buf++) {
760
760
  float *ptr = outOutputData->mBuffers[n_buf].mData;
761
- UInt32 size = outOutputData->mBuffers[n_buf].mDataByteSize / (UInt32)sizeof(float) / channel;
761
+ UInt32 size = outOutputData->mBuffers[n_buf].mDataByteSize / (UInt32)sizeof(float) / channels;
762
762
  UInt32 copied = 0;
763
763
  UInt32 i;
764
764
 
765
- if (outOutputData->mBuffers[n_buf].mNumberChannels != channel) {
766
- memset(ptr, 0, size * channel * sizeof(float));
765
+ if (outOutputData->mBuffers[n_buf].mNumberChannels != channels) {
766
+ memset(ptr, 0, size * channels * sizeof(float));
767
767
  continue;
768
768
  }
769
769
 
770
770
  pthread_mutex_lock(&buffer_data->mutex);
771
771
  for ( copied = 0, i = buffer_data->start; copied < size && i != buffer_data->end; copied++, i = (i+1) % buffer_data->frame ) {
772
772
  UInt32 ch;
773
- for (ch = 0; ch < channel; ch++) {
774
- ptr[copied*channel+ch] = SHORT2FLOAT(buffer_data->buf[i*channel+ch]);
773
+ for (ch = 0; ch < channels; ch++) {
774
+ ptr[copied*channels+ch] = SHORT2FLOAT(buffer_data->buf[i*channels+ch]);
775
775
  }
776
776
  }
777
777
  buffer_data->start = i;
778
778
  pthread_cond_broadcast(&buffer_data->cond);
779
779
  pthread_mutex_unlock(&buffer_data->mutex);
780
780
  if ( copied < size ) {
781
- memset(ptr+(copied*channel), 0, sizeof(float)*channel*(size-copied));
781
+ memset(ptr+(copied*channels), 0, sizeof(float)*channels*(size-copied));
782
782
  buffer_data->dropped_frame += size - copied;
783
783
  }
784
784
  }
@@ -787,7 +787,7 @@ ca_out_buffer_proc(
787
787
  }
788
788
 
789
789
  static VALUE
790
- ca_out_buffer_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channel)
790
+ ca_out_buffer_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channels)
791
791
  {
792
792
  ca_buffer_data *data;
793
793
  OSStatus status;
@@ -800,8 +800,8 @@ ca_out_buffer_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channe
800
800
  rb_raise(rb_eRuntimeError, "coreaudio: create proc ID fail: %d", status);
801
801
  }
802
802
  data->frame = NUM2UINT(frame);
803
- data->channel = NUM2UINT(channel);
804
- data->buf = malloc(sizeof(short)*data->frame*data->channel);
803
+ data->channels = NUM2UINT(channels);
804
+ data->buf = malloc(sizeof(short)*data->frame*data->channels);
805
805
  if (data->buf == NULL)
806
806
  rb_raise(rb_eNoMemError, "coreaudio: fail to alloc out buffer data buffer");
807
807
  return self;
@@ -820,19 +820,37 @@ ca_device_create_out_buffer_proc(VALUE self, VALUE frame)
820
820
  }
821
821
 
822
822
  static VALUE
823
- ca_out_buffer_data_append(VALUE self, VALUE ary)
823
+ ca_out_buffer_data_append(VALUE self, VALUE nary)
824
824
  {
825
825
  ca_buffer_data *data;
826
+ int rank;
827
+ short *buf;
828
+ UInt32 frames;
826
829
  UInt32 idx;
827
- VALUE val;
828
830
  long i;
829
831
  UInt32 j;
830
832
 
831
833
  TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
832
834
 
835
+ nary = na_cast_object(nary, NA_SINT);
836
+ rank = NA_RANK(nary);
837
+ if (rank == 1) {
838
+ frames = NA_SHAPE0(nary);
839
+ } else if (rank == 2) {
840
+ frames = NA_SHAPE1(nary);
841
+ if (NA_SHAPE0(nary) != (int)data->channels)
842
+ rb_raise(rb_eArgError,
843
+ "coreaudio: audio buffer NArray size of first dim. must be "
844
+ "number of channels");
845
+ } else {
846
+ rb_raise(rb_eArgError,
847
+ "coreaudio: audio buffer NArray rank must be 1 or 2");
848
+ }
849
+ buf = NA_PTR_TYPE(nary, short *);
850
+
833
851
  pthread_mutex_lock(&data->mutex);
834
852
  idx = data->end;
835
- for ( i = 0; i < RARRAY_LEN(ary); i++, idx = (idx+1)%data->frame) {
853
+ for ( i = 0; i < frames; i++, idx = (idx+1)%data->frame) {
836
854
  while ( (idx+1) % data->frame == data->start ) {
837
855
  int ret, state;
838
856
  data->end = idx;
@@ -852,19 +870,14 @@ ca_out_buffer_data_append(VALUE self, VALUE ary)
852
870
  break;
853
871
  }
854
872
  }
855
- val = RARRAY_PTR(ary)[i];
856
873
 
857
- if (TYPE(val) == T_ARRAY) {
858
- if (RARRAY_LEN(val) != data->channel) {
859
- pthread_mutex_unlock(&data->mutex);
860
- rb_raise(rb_eArgError, "size of array and channel size mismatch");
861
- }
862
- for (j = 0; j < data->channel; j++) {
863
- data->buf[idx*data->channel+j] = (short)NUM2INT(RARRAY_PTR(val)[j]);
864
- }
874
+ if (rank == 2) {
875
+ memcpy(data->buf + idx * data->channels,
876
+ buf + i * data->channels,
877
+ sizeof(short) * data->channels);
865
878
  } else {
866
- for (j = 0; j < data->channel; j++) {
867
- data->buf[idx*data->channel+j] = (short)NUM2INT(val);
879
+ for (j = 0; j < data->channels; j++) {
880
+ data->buf[idx*data->channels+j] = buf[i];
868
881
  }
869
882
  }
870
883
  data->end = idx;
@@ -891,14 +904,14 @@ ca_in_buffer_proc(
891
904
  NSUInteger n_buf;
892
905
  UInt32 buffers = inInputData->mNumberBuffers;
893
906
  ca_buffer_data *buffer_data = inClientData;
894
- UInt32 channel = buffer_data->channel;
907
+ UInt32 channels = buffer_data->channels;
895
908
 
896
909
  for (n_buf = 0; n_buf < buffers; n_buf++) {
897
910
  float *ptr = inInputData->mBuffers[n_buf].mData;
898
- UInt32 size = inInputData->mBuffers[n_buf].mDataByteSize / (UInt32)sizeof(float) / channel;
911
+ UInt32 size = inInputData->mBuffers[n_buf].mDataByteSize / (UInt32)sizeof(float) / channels;
899
912
  UInt32 copied, idx;
900
913
 
901
- if (inInputData->mBuffers[n_buf].mNumberChannels != channel) {
914
+ if (inInputData->mBuffers[n_buf].mNumberChannels != channels) {
902
915
  continue;
903
916
  }
904
917
 
@@ -909,8 +922,8 @@ ca_in_buffer_proc(
909
922
  copied < size && (idx+1) % buffer_data->frame != buffer_data->start;
910
923
  copied++, idx = (idx+1) % buffer_data->frame) {
911
924
  UInt32 ch;
912
- for (ch = 0; ch < channel; ch++) {
913
- buffer_data->buf[idx*channel+ch] = FLOAT2SHORT(ptr[copied*channel+ch]);
925
+ for (ch = 0; ch < channels; ch++) {
926
+ buffer_data->buf[idx*channels+ch] = FLOAT2SHORT(ptr[copied*channels+ch]);
914
927
  }
915
928
  }
916
929
  buffer_data->end = idx;
@@ -924,7 +937,7 @@ ca_in_buffer_proc(
924
937
  }
925
938
 
926
939
  static VALUE
927
- ca_in_buffer_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channel)
940
+ ca_in_buffer_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channels)
928
941
  {
929
942
  ca_buffer_data *data;
930
943
  OSStatus status;
@@ -937,8 +950,8 @@ ca_in_buffer_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channel
937
950
  rb_raise(rb_eRuntimeError, "coreaudio: create proc ID fail: %d", status);
938
951
  }
939
952
  data->frame = NUM2UINT(frame);
940
- data->channel = NUM2UINT(channel);
941
- data->buf = malloc(sizeof(short)*data->frame*data->channel);
953
+ data->channels = NUM2UINT(channels);
954
+ data->buf = malloc(sizeof(short)*data->frame*data->channels);
942
955
  if (data->buf == NULL)
943
956
  rb_raise(rb_eNoMemError, "coreaudio: fail to alloc input buffer data buffer");
944
957
  return self;
@@ -961,13 +974,17 @@ ca_in_buffer_data_read(VALUE self, VALUE num)
961
974
  {
962
975
  ca_buffer_data *data;
963
976
  UInt32 frame = NUM2UINT(num);
964
- VALUE val;
977
+ VALUE nary;
978
+ int shape[2];
979
+ short *buf;
965
980
  UInt32 i;
966
- UInt32 j;
967
981
 
968
982
  TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
969
983
 
970
- val = rb_ary_new2(frame * data->channel);
984
+ shape[0] = data->channels;
985
+ shape[1] = frame;
986
+ nary = na_make_object(NA_SINT, 2, shape, cNArray);
987
+ buf = NA_PTR_TYPE(nary, short *);
971
988
 
972
989
  pthread_mutex_lock(&data->mutex);
973
990
  for ( i = 0; i < frame; i++, data->start = (data->start+1)%data->frame) {
@@ -989,12 +1006,11 @@ ca_in_buffer_data_read(VALUE self, VALUE num)
989
1006
  break;
990
1007
  }
991
1008
  }
992
- for ( j = 0; j < data->channel; j++ ) {
993
- rb_ary_push(val, INT2NUM((double)data->buf[data->start*data->channel+j]));
994
- }
1009
+ memcpy(buf + i * data->channels, data->buf + data->start*data->channels,
1010
+ sizeof(short) * data->channels);
995
1011
  }
996
1012
  pthread_mutex_unlock(&data->mutex);
997
- return val;
1013
+ return nary;
998
1014
  }
999
1015
 
1000
1016
  void
@@ -17,7 +17,33 @@ unless defined?(have_framework)
17
17
  end
18
18
  end
19
19
 
20
- dir_config("coreaudio")
20
+ begin
21
+ files = Gem.find_files("narray.h")
22
+ if files.empty?
23
+ narray_dir = $sitearchdir
24
+ else
25
+ narray_dir = File.dirname(files.first)
26
+ end
27
+ rescue
28
+ narray_dir = $sitearchdir
29
+ end
30
+ dir_config("narray", narray_dir, narray_dir)
31
+
32
+ if not(have_header("narray.h") and have_header("narray_config.h"))
33
+ print <<-EOS
34
+ ** configure error **
35
+ narray.h or narray_config.h is not found.
36
+ If you have installed narray to /path/to/narray, try the following:
37
+
38
+ % ruby extconf.rb --with-narray-dir=/path/to/narray
39
+
40
+ or
41
+ % gem install coreaudio -- --with-narray-dir=/path/to/narray
42
+
43
+ EOS
44
+ exit false
45
+ end
46
+
21
47
  if have_framework("CoreAudio") and
22
48
  have_framework("AudioToolBox") and
23
49
  have_framework("CoreFoundation") and
@@ -1,2 +1,4 @@
1
+ require "narray"
1
2
  require "coreaudio/coreaudio_ext"
3
+ require "coreaudio/audiofile"
2
4
 
@@ -0,0 +1,38 @@
1
+
2
+ module CoreAudio
3
+ class AudioFile
4
+ def read(frames=nil)
5
+ if frames
6
+ frames = Integer(frames)
7
+ if frames and frames > 0
8
+ return read_frames(frames)
9
+ elsif frames == 0
10
+ return NArray.sint(0)
11
+ else
12
+ raise ArgumentError,
13
+ "coreaudio: read frame number must be zero or positive"
14
+ end
15
+ end
16
+
17
+ # read all frames
18
+ chunk = self.inner_rate.to_i * 10
19
+ total = nil
20
+ loop do
21
+ tmp = read_frames(chunk)
22
+ if tmp.nil?
23
+ break
24
+ end
25
+ if total.nil?
26
+ total = tmp
27
+ else
28
+ new_na = NArray.sint(total.shape[0], tmp.shape[1] + total.shape[1])
29
+ new_na[false, 0...total.shape[1]] = total
30
+ new_na[false, total.shape[1]..-1] = tmp
31
+ total = new_na
32
+ end
33
+ end
34
+
35
+ total
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coreaudio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-16 00:00:00.000000000 Z
12
+ date: 2011-10-28 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: narray
16
+ requirement: &2156227560 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.6.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2156227560
14
25
  - !ruby/object:Gem::Dependency
15
26
  name: bundler
16
- requirement: &2152377300 !ruby/object:Gem::Requirement
27
+ requirement: &2156239180 !ruby/object:Gem::Requirement
17
28
  none: false
18
29
  requirements:
19
30
  - - ~>
@@ -21,10 +32,10 @@ dependencies:
21
32
  version: 1.0.0
22
33
  type: :development
23
34
  prerelease: false
24
- version_requirements: *2152377300
35
+ version_requirements: *2156239180
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: jeweler
27
- requirement: &2152375220 !ruby/object:Gem::Requirement
38
+ requirement: &2156238240 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ~>
@@ -32,10 +43,10 @@ dependencies:
32
43
  version: 1.6.4
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *2152375220
46
+ version_requirements: *2156238240
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: rake
38
- requirement: &2152373440 !ruby/object:Gem::Requirement
49
+ requirement: &2156237000 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ~>
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: 0.9.2
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *2152373440
57
+ version_requirements: *2156237000
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: rdoc
49
- requirement: &2152387460 !ruby/object:Gem::Requirement
60
+ requirement: &2156235680 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,7 +65,7 @@ dependencies:
54
65
  version: '0'
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *2152387460
68
+ version_requirements: *2156235680
58
69
  description: Mac OS X CoreAudio wrapper library
59
70
  email: nagachika00@gmail.com
60
71
  executables: []
@@ -73,9 +84,12 @@ files:
73
84
  - VERSION
74
85
  - coreaudio.gemspec
75
86
  - examples/convert_wav_to_m4a.rb
87
+ - examples/fft_shift_pitch.rb
88
+ - examples/loopback_delay.rb
76
89
  - examples/outbuffer_sine.rb
77
90
  - examples/outloop_sine.rb
78
91
  - examples/record_to_wave.rb
92
+ - examples/ring_modulator.rb
79
93
  - ext/audiofile.m
80
94
  - ext/coreaudio.h
81
95
  - ext/coreaudio.m
@@ -83,6 +97,7 @@ files:
83
97
  - ext/depend
84
98
  - ext/extconf.rb
85
99
  - lib/coreaudio.rb
100
+ - lib/coreaudio/audiofile.rb
86
101
  homepage: https://github.com/nagachika/ruby-coreaudio
87
102
  licenses:
88
103
  - BSDL
@@ -98,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
113
  version: '0'
99
114
  segments:
100
115
  - 0
101
- hash: -1259507067134800519
116
+ hash: -1205790832167491304
102
117
  required_rubygems_version: !ruby/object:Gem::Requirement
103
118
  none: false
104
119
  requirements: