coreaudio 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -8,4 +8,6 @@ source "http://rubygems.org"
8
8
  group :development do
9
9
  gem "bundler", "~> 1.0.0"
10
10
  gem "jeweler", "~> 1.6.4"
11
+ gem "rake", "~> 0.9.2"
12
+ gem "rdoc"
11
13
  end
@@ -6,7 +6,8 @@ GEM
6
6
  bundler (~> 1.0)
7
7
  git (>= 1.2.5)
8
8
  rake
9
- rake (0.9.2.2)
9
+ rake (0.9.2)
10
+ rdoc (3.9.2)
10
11
 
11
12
  PLATFORMS
12
13
  ruby
@@ -14,3 +15,5 @@ PLATFORMS
14
15
  DEPENDENCIES
15
16
  bundler (~> 1.0.0)
16
17
  jeweler (~> 1.6.4)
18
+ rake (~> 0.9.2)
19
+ rdoc
@@ -9,10 +9,10 @@ CoreAudio (Audio Framework of Mac OS X) wrapper library for ruby 1.9
9
9
  * Output audio data (Loop buffer, Stream buffer)
10
10
  * Input audio data (Stream buffer)
11
11
  * Save audio data to WAV/M4A file (wrapper for ExtAudioFile)
12
+ * Ream audio file (WAV/M4A)
12
13
 
13
14
  == ToDo
14
- * Switch input/output audio sample type (signed 16bit integer, Float)
15
- * Read audio file (wrapper for ExtAudioFile)
15
+ * Switch input/output audio sample type (signed 16bit integer, packed String)
16
16
  * Wrapper for AudioUnit/AudioGraph
17
17
 
18
18
  == Contributing to coreaudio
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ require 'jeweler'
15
15
  Jeweler::Tasks.new do |gem|
16
16
  # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
17
  gem.name = "coreaudio"
18
- gem.homepage = "http://github.com/nagachika/coreaudio"
18
+ gem.homepage = "https://github.com/nagachika/ruby-coreaudio"
19
19
  gem.license = "BSDL"
20
20
  gem.summary = %Q{Mac OS X CoreAudio wrapper library}
21
21
  gem.description = %Q{Mac OS X CoreAudio wrapper library}
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "coreaudio"
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
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-10"
12
+ s.date = "2011-10-16"
13
13
  s.description = "Mac OS X CoreAudio wrapper library"
14
14
  s.email = "nagachika00@gmail.com"
15
15
  s.extensions = ["ext/extconf.rb"]
@@ -26,17 +26,19 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "coreaudio.gemspec",
29
+ "examples/convert_wav_to_m4a.rb",
29
30
  "examples/outbuffer_sine.rb",
30
31
  "examples/outloop_sine.rb",
31
32
  "examples/record_to_wave.rb",
32
33
  "ext/audiofile.m",
33
34
  "ext/coreaudio.h",
34
35
  "ext/coreaudio.m",
36
+ "ext/coreaudio_missing.c",
35
37
  "ext/depend",
36
38
  "ext/extconf.rb",
37
39
  "lib/coreaudio.rb"
38
40
  ]
39
- s.homepage = "http://github.com/nagachika/coreaudio"
41
+ s.homepage = "https://github.com/nagachika/ruby-coreaudio"
40
42
  s.licenses = ["BSDL"]
41
43
  s.require_paths = ["lib"]
42
44
  s.rubygems_version = "1.8.11"
@@ -48,13 +50,19 @@ Gem::Specification.new do |s|
48
50
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
51
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
50
52
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
53
+ s.add_development_dependency(%q<rake>, ["~> 0.9.2"])
54
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
51
55
  else
52
56
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
53
57
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
58
+ s.add_dependency(%q<rake>, ["~> 0.9.2"])
59
+ s.add_dependency(%q<rdoc>, [">= 0"])
54
60
  end
55
61
  else
56
62
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
63
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
64
+ s.add_dependency(%q<rake>, ["~> 0.9.2"])
65
+ s.add_dependency(%q<rdoc>, [">= 0"])
58
66
  end
59
67
  end
60
68
 
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "coreaudio"
4
+
5
+ wav = CoreAudio::AudioFile.new("sample.wav", :read)
6
+
7
+ m4a = CoreAudio::AudioFile.new("sample.m4a", :write, :format => :m4a,
8
+ :rate => wav.rate,
9
+ :channel => wav.channel)
10
+
11
+ loop do
12
+ buf = wav.read(1024)
13
+ break if buf.empty?
14
+ m4a.write(buf)
15
+ end
16
+
17
+ wav.close
18
+ m4a.close
19
+
@@ -49,7 +49,7 @@ ca_audio_file_free(void *ptr)
49
49
  ca_audio_file_t *data = ptr;
50
50
 
51
51
  if ( data->file ) {
52
- CFRelease(data->file);
52
+ ExtAudioFileDispose(data->file);
53
53
  data->file = NULL;
54
54
  }
55
55
  }
@@ -77,6 +77,42 @@ ca_audio_file_alloc(VALUE klass)
77
77
  return obj;
78
78
  }
79
79
 
80
+ static void
81
+ parse_audio_file_options(VALUE opt, Boolean for_write,
82
+ Float64 *rate, Float64 *file_rate,
83
+ UInt32 *channel, UInt32 *file_channel)
84
+ {
85
+ if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_rate))) {
86
+ if (for_write)
87
+ *rate = 44100.0;
88
+ else
89
+ *rate = *file_rate;
90
+ } else {
91
+ *rate = NUM2DBL(rb_hash_aref(opt, sym_rate));
92
+ }
93
+ if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_channel))) {
94
+ if (for_write)
95
+ *channel = 2;
96
+ else
97
+ *channel = *file_channel;
98
+ } else {
99
+ *channel = NUM2UINT(rb_hash_aref(opt, sym_channel));
100
+ }
101
+
102
+ if (for_write) {
103
+ if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_file_rate))) {
104
+ *file_rate = *rate;
105
+ } else {
106
+ *file_rate = NUM2DBL(rb_hash_aref(opt, sym_file_rate));
107
+ }
108
+ if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_file_channel))) {
109
+ *file_channel = *channel;
110
+ } else {
111
+ *file_channel = NUM2UINT(rb_hash_aref(opt, sym_file_channel));
112
+ }
113
+ }
114
+ }
115
+
80
116
  /*
81
117
  * call-seq:
82
118
  * AudioFile.new(filepath, mode, opt)
@@ -88,11 +124,11 @@ ca_audio_file_alloc(VALUE klass)
88
124
  * 'client data' means audio data pass to AudioFile#write or from
89
125
  * AudioFile#read method.
90
126
  *
91
- * :format :: audio file format. currently audio file format and
127
+ * :format :: audio file format. currently audio file format and
92
128
  * codec type is hardcoded. (:wav, :m4a)
93
129
  * :rate :: sample rate of data pass from AudioFile#read or to AudioFile#write
94
130
  * If not specified, :file_rate value is used. (Float)
95
- * :channel :: number of channels
131
+ * :channel :: number of channels
96
132
  * :file_rate :: file data sample rate. only work when open for output. (Float)
97
133
  * :file_channel :: file data number of channels. only work when open for
98
134
  * output.
@@ -104,9 +140,8 @@ ca_audio_file_initialize(int argc, VALUE *argv, VALUE self)
104
140
  VALUE path, mode, opt, format;
105
141
  Float64 rate, file_rate;
106
142
  UInt32 channel, file_channel;
107
- CFURLRef outUrl = NULL;
108
- AudioFileTypeID filetype;
109
- UInt32 flags = kAudioFileFlags_EraseFile;
143
+ CFURLRef url = NULL;
144
+ AudioFileTypeID filetype = 0;
110
145
  OSStatus err = noErr;
111
146
 
112
147
  TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
@@ -117,65 +152,70 @@ ca_audio_file_initialize(int argc, VALUE *argv, VALUE self)
117
152
  if (NIL_P(mode) || mode == sym_read)
118
153
  data->for_write = FALSE;
119
154
  else if (mode == sym_write)
120
- data->for_write = TRUE;
155
+ data->for_write = TRUE;
121
156
  else
122
157
  rb_raise(rb_eArgError, "coreaudio: mode should be :read or :write");
123
158
 
124
- /* parse options */
125
- if (NIL_P(rb_hash_aref(opt, sym_rate))) {
126
- rate = 44100.0;
127
- } else {
128
- rate = NUM2DBL(rb_hash_aref(opt, sym_rate));
129
- }
130
- if (NIL_P(rb_hash_aref(opt, sym_file_rate))) {
131
- file_rate = rate;
132
- } else {
133
- file_rate = NUM2DBL(rb_hash_aref(opt, sym_file_rate));
134
- }
135
- if (NIL_P(rb_hash_aref(opt, sym_channel))) {
136
- channel = 2;
137
- } else {
138
- channel = NUM2UINT(rb_hash_aref(opt, sym_channel));
139
- }
140
- if (NIL_P(rb_hash_aref(opt, sym_file_channel))) {
141
- file_channel = channel;
142
- } else {
143
- file_channel = NUM2UINT(rb_hash_aref(opt, sym_file_channel));
144
- }
145
-
146
- format = rb_hash_aref(opt, sym_format);
147
- if (NIL_P(format))
148
- rb_raise(rb_eArgError, "coreaudio: :format option must be specified");
149
-
150
- if (format == sym_wav) {
151
- filetype = kAudioFileWAVEType;
152
- setASBD(&data->file_desc, file_rate, kAudioFormatLinearPCM,
153
- kLinearPCMFormatFlagIsSignedInteger |
154
- kAudioFormatFlagIsPacked,
155
- file_channel, 16, 1);
156
- } else if (format == sym_m4a) {
157
- filetype = kAudioFileM4AType;
158
- setASBD(&data->file_desc, file_rate, kAudioFormatMPEG4AAC,
159
- 0, file_channel, 0, 0);
160
- } else {
161
- volatile VALUE str = rb_inspect(format);
162
- RB_GC_GUARD(str);
163
- rb_raise(rb_eArgError, "coreaudio: unsupported format (%s)",
164
- RSTRING_PTR(str));
159
+ if (data->for_write) {
160
+ /* when open for write, parse options before open ExtAudioFile */
161
+ parse_audio_file_options(opt, data->for_write, &rate, &file_rate,
162
+ &channel, &file_channel);
163
+
164
+ format = rb_hash_aref(opt, sym_format);
165
+ if (NIL_P(format))
166
+ rb_raise(rb_eArgError, "coreaudio: :format option must be specified");
167
+
168
+ if (format == sym_wav) {
169
+ filetype = kAudioFileWAVEType;
170
+ setASBD(&data->file_desc, file_rate, kAudioFormatLinearPCM,
171
+ kLinearPCMFormatFlagIsSignedInteger |
172
+ kAudioFormatFlagIsPacked,
173
+ file_channel, 16, 1);
174
+ } else if (format == sym_m4a) {
175
+ filetype = kAudioFileM4AType;
176
+ setASBD(&data->file_desc, file_rate, kAudioFormatMPEG4AAC,
177
+ 0, file_channel, 0, 0);
178
+ } else {
179
+ volatile VALUE str = rb_inspect(format);
180
+ RB_GC_GUARD(str);
181
+ rb_raise(rb_eArgError, "coreaudio: unsupported format (%s)",
182
+ RSTRING_PTR(str));
183
+ }
165
184
  }
166
185
 
167
186
  /* create URL represent the target filepath */
168
- outUrl = CFURLCreateFromFileSystemRepresentation(
187
+ url = CFURLCreateFromFileSystemRepresentation(
169
188
  NULL, StringValueCStr(path), (CFIndex)RSTRING_LEN(path), FALSE);
170
189
 
171
190
  /* open ExtAudioFile */
172
- err = ExtAudioFileCreateWithURL(outUrl, filetype, &data->file_desc,
173
- NULL, flags, &data->file);
174
- CFRelease(outUrl);
175
- outUrl = NULL;
191
+ if (data->for_write)
192
+ err = ExtAudioFileCreateWithURL(url, filetype, &data->file_desc,
193
+ NULL, kAudioFileFlags_EraseFile,
194
+ &data->file);
195
+ else
196
+ err = ExtAudioFileOpenURL(url, &data->file);
197
+ CFRelease(url);
198
+ url = NULL;
176
199
  if (err != noErr) {
177
200
  rb_raise(rb_eArgError,
178
- "coreaudio: file to open ExtAudioFile: %d", (int)err);
201
+ "coreaudio: fail to open ExtAudioFile: %d", (int)err);
202
+ }
203
+
204
+ /* get Audio Stream Basic Description (ASBD) from input file */
205
+ if (!data->for_write) {
206
+ UInt32 size = sizeof(data->file_desc);
207
+ err = ExtAudioFileGetProperty(data->file,
208
+ kExtAudioFileProperty_FileDataFormat,
209
+ &size, &data->file_desc);
210
+ if (err != noErr)
211
+ rb_raise(rb_eRuntimeError,
212
+ "coreaudio: fail to Get ExtAudioFile Property %d", err);
213
+
214
+ /* parse options */
215
+ file_rate = data->file_desc.mSampleRate;
216
+ file_channel = data->file_desc.mChannelsPerFrame;
217
+ parse_audio_file_options(opt, data->for_write, &rate, &file_rate,
218
+ &channel, &file_channel);
179
219
  }
180
220
 
181
221
  setASBD(&data->inner_desc, rate, kAudioFormatLinearPCM,
@@ -217,6 +257,7 @@ ca_audio_file_write(VALUE self, VALUE data)
217
257
  AudioBufferList buf_list;
218
258
  UInt32 frames;
219
259
  size_t alloc_size;
260
+ volatile VALUE tmpstr;
220
261
  OSStatus err = noErr;
221
262
  int i;
222
263
 
@@ -225,6 +266,12 @@ ca_audio_file_write(VALUE self, VALUE data)
225
266
 
226
267
  TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, file);
227
268
 
269
+ if (file->file == NULL)
270
+ rb_raise(rb_eIOError, "coreaudio: already closend file");
271
+
272
+ if (!file->for_write)
273
+ rb_raise(rb_eRuntimeError, "coreaudio: audio file opened for reading");
274
+
228
275
  frames = RARRAY_LENINT(data) / file->inner_desc.mChannelsPerFrame;
229
276
  alloc_size = (file->inner_desc.mBitsPerChannel/8) * RARRAY_LEN(data);
230
277
 
@@ -232,7 +279,7 @@ ca_audio_file_write(VALUE self, VALUE data)
232
279
  buf_list.mNumberBuffers = 1;
233
280
  buf_list.mBuffers[0].mNumberChannels = file->inner_desc.mChannelsPerFrame;
234
281
  buf_list.mBuffers[0].mDataByteSize = (UInt32)alloc_size;
235
- buf_list.mBuffers[0].mData = xmalloc(alloc_size);
282
+ buf_list.mBuffers[0].mData = rb_alloc_tmp_buffer(&tmpstr, alloc_size);
236
283
  buf = buf_list.mBuffers[0].mData;
237
284
 
238
285
  for (i = 0; i < RARRAY_LEN(data); i++) {
@@ -241,7 +288,7 @@ ca_audio_file_write(VALUE self, VALUE data)
241
288
 
242
289
  err = ExtAudioFileWrite(file->file, frames, &buf_list);
243
290
 
244
- xfree(buf);
291
+ rb_free_tmp_buffer(&tmpstr);
245
292
 
246
293
  if (err != noErr) {
247
294
  rb_raise(rb_eRuntimeError,
@@ -251,6 +298,112 @@ ca_audio_file_write(VALUE self, VALUE data)
251
298
  return self;
252
299
  }
253
300
 
301
+ static VALUE
302
+ ca_audio_file_read(int argc, VALUE *argv, VALUE self)
303
+ {
304
+ ca_audio_file_t *file;
305
+ VALUE frame_val;
306
+ UInt32 frames, chunk, total, read_frames;
307
+ AudioBufferList buf_list;
308
+ short *buf;
309
+ size_t alloc_size;
310
+ volatile VALUE tmpstr;
311
+ VALUE ary;
312
+ UInt32 i;
313
+ OSStatus err = noErr;
314
+
315
+ TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, file);
316
+
317
+ if (file->file == NULL)
318
+ rb_raise(rb_eIOError, "coreaudio: already closend file");
319
+
320
+ if (file->for_write)
321
+ rb_raise(rb_eRuntimeError, "coreaudio: audio file open for writing");
322
+
323
+ rb_scan_args(argc, argv, "01", &frame_val);
324
+
325
+ if (NIL_P(frame_val)) {
326
+ frames = 0;
327
+ chunk = 1024;
328
+ } else {
329
+ frames = chunk = NUM2UINT(frame_val);
330
+ }
331
+
332
+ alloc_size = (file->inner_desc.mBitsPerChannel/8) *
333
+ file->inner_desc.mChannelsPerFrame * chunk;
334
+
335
+ /* prepare interleaved audio buffer */
336
+ buf_list.mNumberBuffers = 1;
337
+ buf_list.mBuffers[0].mNumberChannels = file->inner_desc.mChannelsPerFrame;
338
+ 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;
341
+
342
+ ary = rb_ary_new2(chunk*file->inner_desc.mChannelsPerFrame);
343
+
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
+ }
360
+ }
361
+
362
+ rb_free_tmp_buffer(&tmpstr);
363
+
364
+ return ary;
365
+ }
366
+
367
+ static VALUE
368
+ ca_audio_file_rate(VALUE self)
369
+ {
370
+ ca_audio_file_t *data;
371
+
372
+ TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
373
+
374
+ return DBL2NUM(data->file_desc.mSampleRate);
375
+ }
376
+
377
+ static VALUE
378
+ ca_audio_file_channel(VALUE self)
379
+ {
380
+ ca_audio_file_t *data;
381
+
382
+ TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
383
+
384
+ return UINT2NUM((unsigned int)data->file_desc.mChannelsPerFrame);
385
+ }
386
+
387
+ static VALUE
388
+ ca_audio_file_inner_rate(VALUE self)
389
+ {
390
+ ca_audio_file_t *data;
391
+
392
+ TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
393
+
394
+ return DBL2NUM(data->inner_desc.mSampleRate);
395
+ }
396
+
397
+ static VALUE
398
+ ca_audio_file_inner_channel(VALUE self)
399
+ {
400
+ ca_audio_file_t *data;
401
+
402
+ TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
403
+
404
+ return UINT2NUM((unsigned int)data->inner_desc.mChannelsPerFrame);
405
+ }
406
+
254
407
  void
255
408
  Init_coreaudio_audiofile(void)
256
409
  {
@@ -266,10 +419,14 @@ Init_coreaudio_audiofile(void)
266
419
 
267
420
  rb_cAudioFile = rb_define_class_under(rb_mCoreAudio, "AudioFile",
268
421
  rb_cObject);
269
- rb_global_variable(&rb_cAudioFile);
270
422
 
271
423
  rb_define_alloc_func(rb_cAudioFile, ca_audio_file_alloc);
272
424
  rb_define_method(rb_cAudioFile, "initialize", ca_audio_file_initialize, -1);
273
425
  rb_define_method(rb_cAudioFile, "close", ca_audio_file_close, 0);
274
426
  rb_define_method(rb_cAudioFile, "write", ca_audio_file_write, 1);
427
+ rb_define_method(rb_cAudioFile, "read", ca_audio_file_read, -1);
428
+ rb_define_method(rb_cAudioFile, "rate", ca_audio_file_rate, 0);
429
+ rb_define_method(rb_cAudioFile, "channel", ca_audio_file_channel, 0);
430
+ 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);
275
432
  }
@@ -1,6 +1,10 @@
1
1
  #ifndef COREAUDIO_H
2
2
  #define COREAUDIO_H 1
3
3
 
4
+ #include <ruby.h>
5
+
6
+ #include "extconf.h"
7
+
4
8
  extern VALUE rb_mCoreAudio;
5
9
  extern VALUE rb_mAudioFile;
6
10
 
@@ -9,6 +13,17 @@ extern void Init_coreaudio_audiofile(void);
9
13
  /*-- Utility Macros --*/
10
14
  #define CROPF(F) ((F) > 1.0 ? 1.0 : (((F) < -1.0) ? -1.0 : (F)))
11
15
  #define FLOAT2SHORT(F) ((short)(CROPF(F)*0x7FFF))
12
- #define SHORT2FLOAT(S) ((double)(S) / 32767.0)
16
+ #define SHORT2FLOAT(S) ((float)(S) / (float)32767.0)
17
+
18
+ /*-- prototypes for missing functions --*/
19
+
20
+ #ifndef HAVE_RB_ALLOC_TMP_BUFFER
21
+ extern void *rb_alloc_tmp_buffer(volatile VALUE *store, long len);
22
+ #endif
23
+
24
+ #ifndef HAVE_RB_FREE_TMP_BUFFER
25
+ extern void rb_free_tmp_buffer(volatile VALUE *store);
26
+ #endif
27
+
13
28
 
14
29
  #endif
@@ -422,7 +422,7 @@ ca_out_loop_proc(
422
422
  float *ptr = outOutputData->mBuffers[i].mData;
423
423
  UInt32 size = outOutputData->mBuffers[i].mDataByteSize / (UInt32)sizeof(float) / channel;
424
424
  UInt32 offset = (UInt32)inOutputTime->mSampleTime % loop_data->frame;
425
- unsigned long copied = 0;
425
+ UInt32 copied = 0;
426
426
 
427
427
  if (outOutputData->mBuffers[i].mNumberChannels != channel) {
428
428
  memset(ptr, 0, size * channel * sizeof(float));
@@ -0,0 +1,24 @@
1
+
2
+ #include "ruby.h"
3
+ #include "coreaudio.h"
4
+
5
+ #ifndef HAVE_RB_ALLOC_TMP_BUFFER
6
+ void *
7
+ rb_alloc_tmp_buffer(volatile VALUE *store, long len)
8
+ {
9
+ VALUE s = rb_str_tmp_new(len);
10
+ *store = s;
11
+ return RSTRING_PTR(s);
12
+ }
13
+ #endif
14
+
15
+ #ifndef HAVE_RB_FREE_TMP_BUFFER
16
+ void
17
+ rb_free_tmp_buffer(volatile VALUE *store)
18
+ {
19
+ VALUE s = *store;
20
+ *store = 0;
21
+ if (s) rb_str_clear(s);
22
+ }
23
+ #endif
24
+
@@ -22,7 +22,16 @@ if have_framework("CoreAudio") and
22
22
  have_framework("AudioToolBox") and
23
23
  have_framework("CoreFoundation") and
24
24
  have_framework("Cocoa")
25
+
26
+ # check ruby API
27
+ have_func("rb_alloc_tmp_buffer", "ruby.h")
28
+ have_func("rb_free_tmp_buffer", "ruby.h")
29
+
30
+ create_header
31
+
32
+ # create Makefile
25
33
  create_makefile("coreaudio/coreaudio_ext")
34
+
26
35
  # workaround for mkmf.rb in 1.9.2
27
36
  if RUBY_VERSION < "1.9.3"
28
37
  open("Makefile", "a") do |f|
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.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-10 00:00:00.000000000 Z
12
+ date: 2011-10-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
- requirement: &2157890960 !ruby/object:Gem::Requirement
16
+ requirement: &2152377300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.0.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2157890960
24
+ version_requirements: *2152377300
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: jeweler
27
- requirement: &2157890240 !ruby/object:Gem::Requirement
27
+ requirement: &2152375220 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,7 +32,29 @@ dependencies:
32
32
  version: 1.6.4
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2157890240
35
+ version_requirements: *2152375220
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &2152373440 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.2
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2152373440
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdoc
49
+ requirement: &2152387460 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2152387460
36
58
  description: Mac OS X CoreAudio wrapper library
37
59
  email: nagachika00@gmail.com
38
60
  executables: []
@@ -50,16 +72,18 @@ files:
50
72
  - Rakefile
51
73
  - VERSION
52
74
  - coreaudio.gemspec
75
+ - examples/convert_wav_to_m4a.rb
53
76
  - examples/outbuffer_sine.rb
54
77
  - examples/outloop_sine.rb
55
78
  - examples/record_to_wave.rb
56
79
  - ext/audiofile.m
57
80
  - ext/coreaudio.h
58
81
  - ext/coreaudio.m
82
+ - ext/coreaudio_missing.c
59
83
  - ext/depend
60
84
  - ext/extconf.rb
61
85
  - lib/coreaudio.rb
62
- homepage: http://github.com/nagachika/coreaudio
86
+ homepage: https://github.com/nagachika/ruby-coreaudio
63
87
  licenses:
64
88
  - BSDL
65
89
  post_install_message:
@@ -74,7 +98,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
74
98
  version: '0'
75
99
  segments:
76
100
  - 0
77
- hash: 487073156904496213
101
+ hash: -1259507067134800519
78
102
  required_rubygems_version: !ruby/object:Gem::Requirement
79
103
  none: false
80
104
  requirements: