coreaudio 0.0.3 → 0.0.4

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/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: