ao 0.0.4 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ #ifndef THREAD_H
2
+ #define THREAD_H
3
+ void *thread_player(void *device);
4
+ ao_struct *create_thread(ao_struct *aos);
5
+ #endif
@@ -0,0 +1,3 @@
1
+ #-*- coding: utf-8 -*-
2
+
3
+ require 'audio/output'
@@ -9,7 +9,7 @@ class Audio::LiveOutput < Audio::LiveOutputC
9
9
  bits: 16, rate: 44100, channels: 2,
10
10
  byte_format:
11
11
  Audio::Info::FMT_NATIVE,
12
- matrix: nil, options: nil)
12
+ matrix: nil, options: nil, thread: nil)
13
13
  ao = super(driver_id, bits, rate, channels,
14
14
  byte_format, matrix, options)
15
15
  if block_given?
@@ -30,7 +30,7 @@ class Audio::FileOutput < Audio::FileOutputC
30
30
  bits: 16, rate: 44100, channels: 2,
31
31
  byte_format:
32
32
  Audio::Info::FMT_NATIVE,
33
- matrix: nil, options: nil)
33
+ matrix: nil, options: nil, thread: nil)
34
34
  ao = super(driver_id, filename, overwrite,
35
35
  bits, rate, channels, byte_format,
36
36
  matrix, options)
metadata CHANGED
@@ -1,47 +1,59 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ao
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akito Miura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-19 00:00:00.000000000 Z
11
+ date: 2018-01-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: simple & cross platform audio output library(libao binding http://http://xiph.org/ao/)
14
14
  email: phenomer@g.hachune.net
15
15
  executables: []
16
16
  extensions:
17
- - ext/extconf.rb
17
+ - ext/audio/extconf.rb
18
18
  extra_rdoc_files:
19
19
  - README.rdoc
20
20
  - CHANGELOG.rdoc
21
- - ext/cao.h
22
- - ext/output.c
23
- - ext/device.c
24
- - ext/info.c
25
- - ext/option.c
26
- - ext/exception.c
27
- - ext/constant.c
21
+ - ext/audio/cao.h
22
+ - ext/audio/output.c
23
+ - ext/audio/thread.c
24
+ - ext/audio/queue.c
25
+ - ext/audio/mixer.c
26
+ - ext/audio/device.c
27
+ - ext/audio/info.c
28
+ - ext/audio/option.c
29
+ - ext/audio/exception.c
30
+ - ext/audio/constant.c
28
31
  - lib/audio/output.rb
29
32
  files:
30
33
  - CHANGELOG.rdoc
31
34
  - LICENSE
32
35
  - README.rdoc
36
+ - Rakefile
33
37
  - example/beeplay.rb
34
38
  - example/drivers.rb
35
39
  - example/raw2wav.rb
36
40
  - example/rawplay.rb
37
- - ext/cao.h
38
- - ext/constant.c
39
- - ext/device.c
40
- - ext/exception.c
41
- - ext/extconf.rb
42
- - ext/info.c
43
- - ext/option.c
44
- - ext/output.c
41
+ - ext/audio/cao.h
42
+ - ext/audio/constant.c
43
+ - ext/audio/device.c
44
+ - ext/audio/exception.c
45
+ - ext/audio/extconf.rb
46
+ - ext/audio/file.c
47
+ - ext/audio/info.c
48
+ - ext/audio/live.c
49
+ - ext/audio/mixer.c
50
+ - ext/audio/option.c
51
+ - ext/audio/output.c
52
+ - ext/audio/queue.c
53
+ - ext/audio/queue.h
54
+ - ext/audio/thread.c
55
+ - ext/audio/thread.h
56
+ - lib/ao.rb
45
57
  - lib/audio/output.rb
46
58
  homepage: http://bitbucket.org/phenomer/ruby-ao
47
59
  licenses:
@@ -56,7 +68,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
68
  requirements:
57
69
  - - ">="
58
70
  - !ruby/object:Gem::Version
59
- version: 2.1.0
71
+ version: 2.4.0
60
72
  required_rubygems_version: !ruby/object:Gem::Requirement
61
73
  requirements:
62
74
  - - ">="
@@ -64,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
76
  version: '0'
65
77
  requirements: []
66
78
  rubyforge_project:
67
- rubygems_version: 2.4.5
79
+ rubygems_version: 2.7.3
68
80
  signing_key:
69
81
  specification_version: 4
70
82
  summary: simple & cross platform audio output library
data/ext/cao.h DELETED
@@ -1,61 +0,0 @@
1
- #ifndef CAO_H
2
- #define CAO_H
3
-
4
- #include <ruby.h>
5
- #include <ruby/thread.h>
6
- #include <ao/ao.h>
7
- #include <ao/os_types.h>
8
-
9
- extern VALUE cAudio;
10
- extern VALUE cAO_Live;
11
- extern VALUE cAO_File;
12
- extern VALUE cAO_Info;
13
- extern VALUE cAO_DeviceData;
14
- extern VALUE cAO_eAOError;
15
- extern VALUE cAO_eDeviceError;
16
- extern VALUE cAO_eUnknownError;
17
-
18
- extern VALUE cAO_eNoDriver;
19
- extern VALUE cAO_eNotFile;
20
- extern VALUE cAO_eNotLive;
21
- extern VALUE cAO_eBadOption;
22
- extern VALUE cAO_eDriverError;
23
-
24
- extern VALUE cAO_eFileError;
25
- extern VALUE cAO_eFileExists;
26
- extern VALUE cAO_eBadFormat;
27
-
28
- typedef struct sample_buffer {
29
- int bytes;
30
- char *samples;
31
- struct sample_buffer *next;
32
- } sample_buffer;
33
-
34
- typedef struct dev_data {
35
- ao_device *device;
36
- ao_sample_format *format;
37
- ao_option *option;
38
- sample_buffer *buffer;
39
- int playing;
40
- } dev_data;
41
-
42
- dev_data * append_device(ao_device *dev,
43
- ao_sample_format *format,
44
- ao_option *option);
45
- void close_device(dev_data *devdat);
46
- void remove_device(dev_data *devdat);
47
-
48
- void init_exception(void);
49
- void init_constant(void);
50
- ao_sample_format *
51
- set_format(VALUE bits, VALUE rate, VALUE channels,
52
- VALUE byte_format, VALUE matrix);
53
- void free_format(ao_sample_format *format);
54
- ao_option * set_option(VALUE a_options);
55
-
56
- VALUE
57
- raodev_play(VALUE obj, VALUE output_samples);
58
-
59
- VALUE raodev_close(VALUE obj);
60
- VALUE raodev_closed(VALUE obj);
61
- #endif
@@ -1,133 +0,0 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include <string.h>
4
- #include <unistd.h>
5
- #include "cao.h"
6
-
7
- typedef struct play_data {
8
- ao_device *device;
9
- char *samples;
10
- uint_32 bytes;
11
- int result;
12
- } play_data;
13
-
14
- void *nogvl_ao_play(void *playdata){
15
- play_data *pd = playdata;
16
- pd->result =
17
- ao_play(pd->device, pd->samples, pd->bytes);
18
- return NULL;
19
- }
20
-
21
- /*
22
- * デバイス一覧にデバイスを追加する。
23
- * 追加した構造体へのポインタを返す。
24
- * 割当に失敗した場合は-1を返す。
25
- */
26
- dev_data *
27
- append_device(ao_device *dev, ao_sample_format *format,
28
- ao_option *option)
29
- {
30
- dev_data *newdev;
31
- newdev = ALLOC(dev_data);
32
- newdev->device = dev;
33
- newdev->format = format;
34
- newdev->option = option;
35
- newdev->playing = 0;
36
- newdev->buffer = NULL;
37
- return newdev;
38
- }
39
-
40
- /*
41
- * devdata構造体の持つデバイスを全て閉じ、
42
- * またオプションとフォーマットの情報も削除する。
43
- * メンバ変数にはNULLを設定する。
44
- * devdata構造体自体は開放しない。
45
- * (rubyのGCによって実行されるremove_device関数に任せるため)
46
- */
47
- void
48
- close_device(dev_data *devdat){
49
- if (devdat->device != NULL){
50
- ao_close(devdat->device);
51
- }
52
- if (devdat->option != NULL){
53
- ao_free_options(devdat->option);
54
- }
55
- if (devdat->format != NULL){
56
- free_format(devdat->format);
57
- }
58
- devdat->device = NULL;
59
- devdat->option = NULL;
60
- devdat->format = NULL;
61
- devdat->buffer = NULL;
62
- return;
63
- }
64
-
65
- /*
66
- * GCが実行された時にデバイスを閉じ、構造体を開放する。
67
- * この関数はopen_live()とopen_file()にてdev_data構造体をWrapする時に
68
- * 構造体free用関数として渡す(rubyのGCにて呼ばれるよう設定する)
69
- * Data_Wrap_Struct(cAO_DeviceData, 0, remove_device, devdat);
70
- */
71
- void
72
- remove_device(dev_data *devdat)
73
- {
74
- close_device(devdat);
75
- free(devdat);
76
- return;
77
- }
78
-
79
- /*
80
- * call-seq: ao.play(output_samples)
81
- *
82
- * 受け取ったサンプルを再生する。
83
- * (デバイスがファイル出力の場合はファイルに書き出す)
84
- * 一度に渡せる量はunsigned int(32bit)の範囲まで。
85
- *
86
- * [arg1] buffer(String)
87
- * [return] Fixnum
88
- */
89
- VALUE
90
- raodev_play(VALUE obj, VALUE output_samples)
91
- {
92
- dev_data *devdata;
93
- play_data playdata;
94
-
95
- Check_Type(output_samples, T_STRING);
96
- Data_Get_Struct(rb_ivar_get(obj, rb_intern("@device")),
97
- dev_data, devdata);
98
- playdata.device = devdata->device;
99
- playdata.bytes = RSTRING_LENINT(output_samples);
100
- if ((playdata.samples = malloc(playdata.bytes)) == NULL){
101
- rb_raise(cAO_eAOError, "Memory allocation failure.");
102
- }
103
- memcpy(playdata.samples, StringValuePtr(output_samples), playdata.bytes);
104
- #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
105
- rb_thread_call_without_gvl2(nogvl_ao_play, &playdata, NULL, NULL);
106
- /*rb_thread_call_without_gvl2((rb_blocking_function_t *)nogvl_ao_play, &playdata, NULL, NULL);*/
107
- #else
108
- nogvl_ao_play(&playdata);
109
- #endif
110
- free(playdata.samples);
111
- if (playdata.result == 0){
112
- rb_raise(cAO_eDeviceError, "Device should be closed.");
113
- }
114
- return INT2FIX(playdata.result);
115
- }
116
-
117
- /*
118
- * call-seq: ao.closed?
119
- *
120
- * デバイスが既に閉じられているか確認する。
121
- * [return] true or false
122
- */
123
- VALUE
124
- raodev_closed(VALUE obj)
125
- {
126
- dev_data *devdata;
127
- Data_Get_Struct(rb_ivar_get(obj, rb_intern("@device")),
128
- dev_data, devdata);
129
- if (devdata->device == NULL){
130
- return Qtrue;
131
- }
132
- return Qfalse;
133
- }
@@ -1,309 +0,0 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include <string.h>
4
- #include <errno.h>
5
- #include "cao.h"
6
-
7
- VALUE cAudio;
8
- VALUE cAO_Live;
9
- VALUE cAO_File;
10
- VALUE cAO_DeviceData;
11
- VALUE cAO_eAOError;
12
- VALUE cAO_eDeviceError;
13
- VALUE cAO_eUnknownError;
14
-
15
- VALUE cAO_eNoDriver;
16
- VALUE cAO_eNotFile;
17
- VALUE cAO_eNotLive;
18
- VALUE cAO_eBadOption;
19
- VALUE cAO_eDriverError;
20
-
21
- VALUE cAO_eFileError;
22
- VALUE cAO_eFileExists;
23
- VALUE cAO_eBadFormat;
24
-
25
- /*
26
- * call-seq: Audio::LiveOutput.new(driver_id, bits, rate, channels, byte_format, matrix, options)
27
- *
28
- * オーディオ出力デバイスを開く。
29
- * 引数に指定するmatrixとoptionについては以下を参照。
30
- * [matrix] http://xiph.org/ao/doc/ao_sample_format.html
31
- * [option] http://xiph.org/ao/doc/drivers.html
32
- * optionはKey-Valueを要素に含む2次元配列を設定する。
33
- * 特に設定が必要なければnilで構わない。
34
- * ex) ALSAドライバのデバイスをhw:1に設定する場合は [["dev", "hw:1"]] を渡す。
35
- *
36
- * [arg1] DriverID
37
- * [arg2] bits(Fixnum)
38
- * [arg3] rate(Fixnum)
39
- * [arg4] channels(fixnum)
40
- * [arg5] byte_format(fixnum)
41
- * [arg6] matrix(String or nil)
42
- * [arg7] options(Array or nil)
43
- * [return] self
44
- */
45
- static VALUE
46
- rao_open_live(VALUE obj, VALUE driver_id,
47
- VALUE bits, VALUE rate, VALUE channels,
48
- VALUE byte_format, VALUE matrix,
49
- VALUE a_options)
50
- {
51
- ao_device *dev;
52
- ao_sample_format *format;
53
- ao_option *option;
54
- dev_data *devdat;
55
- VALUE rdev;
56
-
57
- if (rb_iv_get(obj, "@device") != Qnil){
58
- Data_Get_Struct(rb_iv_get(obj, "@device"),
59
- dev_data, devdat);
60
- rb_raise(cAO_eDeviceError,
61
- "Device is already open.\n");
62
- }
63
-
64
- Check_Type(driver_id, T_FIXNUM);
65
- format = set_format(bits, rate, channels, byte_format, matrix);
66
- option = set_option(a_options);
67
- dev = ao_open_live(FIX2INT(driver_id), format, option);
68
- if (dev == NULL){
69
- free_format(format);
70
- ao_free_options(option);
71
- switch(errno){
72
- case AO_ENODRIVER:
73
- rb_raise(cAO_eNoDriver,
74
- "No driver corresponds - %s",
75
- strerror(errno));
76
- break;
77
- case AO_ENOTLIVE:
78
- rb_raise(cAO_eNotLive,
79
- "This driver is not a live output device - %s",
80
- strerror(errno));
81
- break;
82
- case AO_EBADOPTION:
83
- rb_raise(cAO_eBadOption,
84
- "A valid option key has an invalid value - %s",
85
- strerror(errno));
86
- break;
87
- case AO_EOPENDEVICE:
88
- rb_raise(cAO_eDeviceError,
89
- "Cannot open the device - %s",
90
- strerror(errno));
91
- break;
92
- case AO_EFAIL:
93
- rb_raise(cAO_eUnknownError,
94
- "Any other cause of failure - %s",
95
- strerror(errno));
96
- break;
97
- default:
98
- rb_raise(cAO_eUnknownError,
99
- "Unknown error - %s",
100
- strerror(errno));
101
- }
102
- }
103
- if ((devdat = append_device(dev, format, option)) == NULL){
104
- rb_raise(cAO_eUnknownError,
105
- "memory allocation failure - %s",
106
- strerror(errno));
107
- }
108
-
109
- rdev = Data_Wrap_Struct(cAO_DeviceData, 0,
110
- remove_device, devdat);
111
- rb_iv_set(obj, "@device", rdev);
112
- rb_ary_push(rb_cv_get(cAO_Live, "@@devices"), rdev);
113
-
114
- return obj;
115
- }
116
-
117
- /*
118
- * call-seq: Audio::FileOutput.new(driver_id, filepath, overwrite, bits, rate, channels, byte_format, matrix, options)
119
- *
120
- * ファイルを開く。引数に指定するmatrixとoptionについては以下を参照。
121
- * [matrix] http://xiph.org/ao/doc/ao_sample_format.html
122
- * [option] http://xiph.org/ao/doc/drivers.html
123
- * optionはKey-Valueを要素に含む2次元配列を設定する。
124
- * 特に設定が必要なければnilで構わない。
125
- * ex) RAWドライバの出力エンディアンをビッグエンディアンに設定する場合は [["byteirder", "big"]] を渡す。
126
- *
127
- * [arg1] DriverID(Fixnum)
128
- * [arg2] filepath(String)
129
- * [arg3] overwrite?(true or false)
130
- * [arg4] bits(Fixnum)
131
- * [arg5] rate(Fixnum)
132
- * [arg6] channels(fixnum)
133
- * [arg7] byte_format(fixnum)
134
- * [arg8] matrix(String or nil)
135
- * [arg9] options(Array or nil)
136
- * [return] self
137
- */
138
- static VALUE
139
- rao_open_file(VALUE obj, VALUE driver_id,
140
- VALUE filename, VALUE overwrite,
141
- VALUE bits, VALUE rate, VALUE channels,
142
- VALUE byte_format, VALUE matrix,
143
- VALUE a_options)
144
- {
145
- dev_data *devdat;
146
- ao_device *dev;
147
- ao_sample_format *format;
148
- ao_option *option;
149
- int overwrite_int = 0;
150
- VALUE rdev;
151
-
152
-
153
- if (rb_iv_get(obj, "@device") != Qnil){
154
- Data_Get_Struct(rb_iv_get(obj, "@device"),
155
- dev_data, devdat);
156
- rb_raise(cAO_eDeviceError,
157
- "Device is already open.\n");
158
- }
159
-
160
- Check_Type(filename, T_STRING);
161
- Check_Type(driver_id, T_FIXNUM);
162
- if (TYPE(overwrite) == T_TRUE){
163
- overwrite_int = 1;
164
- }
165
- format = set_format(bits, rate, channels, byte_format, matrix);
166
- option = set_option(a_options);
167
- dev = ao_open_file(FIX2INT(driver_id), StringValuePtr(filename),
168
- overwrite_int, format, option);
169
- if (dev == NULL){
170
- free_format(format);
171
- ao_free_options(option);
172
- switch(errno){
173
- case AO_ENODRIVER:
174
- rb_raise(cAO_eNoDriver,
175
- "No driver corresponds - %s",
176
- strerror(errno));
177
- break;
178
- case AO_ENOTFILE:
179
- rb_raise(cAO_eNotFile,
180
- "This driver is not a file output device - %s",
181
- strerror(errno));
182
- break;
183
- case AO_EBADOPTION:
184
- rb_raise(cAO_eBadOption,
185
- "A valid option key has an invalid value - %s",
186
- strerror(errno));
187
- break;
188
- case AO_EOPENFILE:
189
- rb_raise(cAO_eFileError,
190
- "Cannot open the device - %s",
191
- strerror(errno));
192
- break;
193
- case AO_EFILEEXISTS:
194
- rb_raise(cAO_eFileExists,
195
- "The file already exists - %s",
196
- strerror(errno));
197
- case AO_EFAIL:
198
- rb_raise(cAO_eUnknownError,
199
- "Any other cause of failure - %s",
200
- strerror(errno));
201
- break;
202
- default:
203
- rb_raise(cAO_eUnknownError,
204
- "Unknown error - %s",
205
- strerror(errno));
206
- }
207
- }
208
- if ((devdat = append_device(dev, format, option)) == NULL){
209
- rb_raise(cAO_eUnknownError,
210
- "memory allocation failure - %s",
211
- strerror(errno));
212
- }
213
-
214
- rdev = Data_Wrap_Struct(cAO_DeviceData, 0,
215
- remove_device, devdat);
216
- rb_iv_set(obj, "@device", rdev);
217
- rb_ary_push(rb_cv_get(cAO_File, "@@devices"), rdev);
218
-
219
- return obj;
220
- }
221
-
222
- static VALUE
223
- rao_close(VALUE obj)
224
- {
225
- dev_data *devdata;
226
-
227
- if (rb_iv_get(obj, "@device") == Qnil){
228
- return Qfalse;
229
- }
230
-
231
- Data_Get_Struct(rb_iv_get(obj, "@device"),
232
- dev_data, devdata);
233
- close_device(devdata);
234
- rb_ary_delete(rb_cv_get(cAO_Live, "@@devices"), rb_intern("@device"));
235
- rb_iv_set(obj, "@device", Qnil);
236
- return Qtrue;
237
- }
238
-
239
- /*
240
- * libaoを終了する。shutdownの前に開いている全てのデバイスを
241
- * closeしておかなければならない。
242
- *
243
- * [return] nil
244
- */
245
- void
246
- rao_shutdown(VALUE obj){
247
- VALUE rdev;
248
- dev_data *devdata;
249
-
250
- rb_gc_start();
251
- while ((rdev = rb_ary_pop(rb_cv_get(cAO_Live, "@@devices"))) != Qnil){
252
- Data_Get_Struct(rdev, dev_data, devdata);
253
- close_device(devdata);
254
- }
255
- ao_shutdown();
256
- return;
257
- }
258
-
259
- void
260
- Init_outputc(void)
261
- {
262
- ao_initialize();
263
- /*
264
- * Document-class: Audio
265
- *
266
- * Ruby-AOの基礎となるクラス。
267
- */
268
- cAudio = rb_define_class("Audio", rb_cObject);
269
-
270
- /*
271
- * Document-class: Audio::LiveOutput
272
- *
273
- * オーディオデバイス出力機能をサポートするクラス。
274
- */
275
- cAO_Live = rb_define_class_under(cAudio, "LiveOutputC", rb_cObject);
276
- rb_cv_set(cAO_Live, "@@devices", rb_ary_new());
277
-
278
- /*
279
- * Document-class: Audio::BasicOutput::DeviceData
280
- *
281
- * 開いたデバイスに関する基本的な情報を保持するクラス。
282
- * ruby側から操作はしない。
283
- */
284
- cAO_DeviceData = rb_define_class_under(cAO_Live, "DeviceData", rb_cData);
285
-
286
- /* library initialize & shutdown */
287
- rb_define_private_method(cAO_Live, "initialize", rao_open_live, 7);
288
-
289
- /* device setup */
290
- rb_define_method(cAO_Live, "close", rao_close, 0);
291
- rb_define_method(cAO_Live, "play", raodev_play, 1);
292
- rb_define_method(cAO_Live, "closed?", raodev_closed, 0);
293
-
294
- /*
295
- * Document-class: Audio::FileOutput
296
- *
297
- * オーディオファイル出力機能をサポートするクラス。
298
- */
299
- cAO_File = rb_define_class_under(cAudio, "FileOutputC", cAO_Live);
300
- rb_define_private_method(cAO_File, "initialize", rao_open_file, 9);
301
-
302
- init_exception();
303
- init_info();
304
- init_constant();
305
- init_option();
306
-
307
- /* Shutdown */
308
- rb_set_end_proc(rao_shutdown, (VALUE)NULL);
309
- }