ao 0.0.3
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.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +0 -0
- data/LICENSE +340 -0
- data/README.rdoc +44 -0
- data/example/beeplay.rb +36 -0
- data/example/drivers.rb +31 -0
- data/example/raw2wav.rb +28 -0
- data/example/rawplay.rb +24 -0
- data/ext/cao.h +61 -0
- data/ext/constant.c +25 -0
- data/ext/device.c +133 -0
- data/ext/exception.c +110 -0
- data/ext/extconf.rb +12 -0
- data/ext/info.c +187 -0
- data/ext/option.c +133 -0
- data/ext/output.c +309 -0
- data/lib/audio/output.rb +45 -0
- metadata +71 -0
data/example/raw2wav.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#-*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
#
|
5
|
+
# RAW to WAV converter
|
6
|
+
# (bit: 16bit, rate: 44100Hz, channel: 2ch,
|
7
|
+
# endian: native, matrix: default, option: default)
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'audio/output'
|
11
|
+
|
12
|
+
unless ARGV[1]
|
13
|
+
puts('ex) ./raw2wav.rb input.raw output.wav')
|
14
|
+
exit(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
input = ARGV[0]
|
18
|
+
output = ARGV[1]
|
19
|
+
ao =
|
20
|
+
raise unless File.file?(input)
|
21
|
+
Audio::FileOutput.new(driver_id: Audio::Info.driver_id('wav'),
|
22
|
+
filename: output){|ao|
|
23
|
+
File.open(input){|f|
|
24
|
+
while buffer = f.read(4096)
|
25
|
+
ao.play(buffer)
|
26
|
+
end
|
27
|
+
}
|
28
|
+
}
|
data/example/rawplay.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#-*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
#
|
5
|
+
# Simple RAW Audio Player
|
6
|
+
# (bits: 16bit, rate: 44100Hz, channels: 2ch,
|
7
|
+
# byte_format: Little endian,
|
8
|
+
# matrix: default, option: default)
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'audio/output'
|
12
|
+
|
13
|
+
ARGV.each{|file|
|
14
|
+
if File.file?(file)
|
15
|
+
Audio::LiveOutput.new(bits: 16, rate: 44100, channels: 2,
|
16
|
+
byte_format: Audio::Info::FMT_LITTLE){|ao|
|
17
|
+
File.open(file){|f|
|
18
|
+
while buffer = f.read(4096)
|
19
|
+
ao.play(buffer)
|
20
|
+
end
|
21
|
+
}
|
22
|
+
}
|
23
|
+
end
|
24
|
+
}
|
data/ext/cao.h
ADDED
@@ -0,0 +1,61 @@
|
|
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
|
data/ext/constant.c
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#include "cao.h"
|
2
|
+
|
3
|
+
VALUE cAudio;
|
4
|
+
VALUE cAO_Info;
|
5
|
+
|
6
|
+
/* constants */
|
7
|
+
void
|
8
|
+
init_constant(void)
|
9
|
+
{
|
10
|
+
/* ドライバがLive出力用であることを示す。 */
|
11
|
+
rb_define_const(cAO_Info, "TYPE_LIVE", INT2FIX(AO_TYPE_LIVE));
|
12
|
+
|
13
|
+
/* ドライバがファイル出力用であることを示す。 */
|
14
|
+
rb_define_const(cAO_Info, "TYPE_FILE", INT2FIX(AO_TYPE_FILE));
|
15
|
+
|
16
|
+
/* データのエンディアンがリトルエンディアンであることを示す。 */
|
17
|
+
rb_define_const(cAO_Info, "FMT_LITTLE", INT2FIX(AO_FMT_LITTLE));
|
18
|
+
|
19
|
+
/* データのエンディアンがビッグエンディアンであることを示す。 */
|
20
|
+
rb_define_const(cAO_Info, "FMT_BIG", INT2FIX(AO_FMT_BIG));
|
21
|
+
|
22
|
+
/* データのエンディアンがホストのネイティブ形式であることを示す。 */
|
23
|
+
rb_define_const(cAO_Info, "FMT_NATIVE", INT2FIX(AO_FMT_NATIVE));
|
24
|
+
return;
|
25
|
+
}
|
data/ext/device.c
ADDED
@@ -0,0 +1,133 @@
|
|
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
|
+
}
|
data/ext/exception.c
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
#include "cao.h"
|
2
|
+
|
3
|
+
VALUE cAudio;
|
4
|
+
VALUE cAO_Live;
|
5
|
+
VALUE cAO_File;
|
6
|
+
VALUE cAO_eAOError;
|
7
|
+
VALUE cAO_eNoDriver;
|
8
|
+
VALUE cAO_eNotFile;
|
9
|
+
VALUE cAO_eNotLive;
|
10
|
+
VALUE cAO_eBadOption;
|
11
|
+
VALUE cAO_eDeviceError;
|
12
|
+
VALUE cAO_eDriverError;
|
13
|
+
VALUE cAO_eFileError;
|
14
|
+
VALUE cAO_eFileExists;
|
15
|
+
VALUE cAO_eBadFormat;
|
16
|
+
VALUE cAO_eUnknownError;
|
17
|
+
|
18
|
+
void init_exception(void)
|
19
|
+
{
|
20
|
+
/*
|
21
|
+
* Document-class: Audio::LiveOutput::Error
|
22
|
+
*
|
23
|
+
* Audio::BasicOutputに関するエラーは
|
24
|
+
* Audio::BasicOutput::Errorを継承する。
|
25
|
+
*/
|
26
|
+
cAO_eAOError =
|
27
|
+
rb_define_class_under(cAO_Live, "Error", rb_eStandardError);
|
28
|
+
|
29
|
+
/*
|
30
|
+
* Document-class: Audio::LiveOutput::NoDriver
|
31
|
+
*
|
32
|
+
* ドライバが見つからない時に発生する。
|
33
|
+
*/
|
34
|
+
cAO_eNoDriver =
|
35
|
+
rb_define_class_under(cAO_Live, "NoDriver", cAO_eAOError);
|
36
|
+
|
37
|
+
/*
|
38
|
+
* Document-class: Audio::LiveOutput::NotFile
|
39
|
+
*
|
40
|
+
* ドライバがファイル出力用のものではない時に発生する。
|
41
|
+
*/
|
42
|
+
cAO_eNotFile =
|
43
|
+
rb_define_class_under(cAO_Live, "NotFile", cAO_eAOError);
|
44
|
+
|
45
|
+
/*
|
46
|
+
* Document-class: Audio::LiveOutput::NotLive
|
47
|
+
*
|
48
|
+
* ドライバがデバイス出力用のものではない時に発生する。
|
49
|
+
*/
|
50
|
+
cAO_eNotLive =
|
51
|
+
rb_define_class_under(cAO_Live, "NotLive", cAO_eAOError);
|
52
|
+
|
53
|
+
/*
|
54
|
+
* Document-class: Audio::LiveOutput::BadOption
|
55
|
+
*
|
56
|
+
* ドライバに設定したオプションの値が不正である時に発生する。
|
57
|
+
*/
|
58
|
+
cAO_eBadOption =
|
59
|
+
rb_define_class_under(cAO_Live, "BadOption", cAO_eAOError);
|
60
|
+
|
61
|
+
/*
|
62
|
+
* Document-class: Audio::LiveOutput::DriverError
|
63
|
+
*
|
64
|
+
* ドライバに関するエラー。
|
65
|
+
*/
|
66
|
+
cAO_eDriverError =
|
67
|
+
rb_define_class_under(cAO_Live, "DriverError", cAO_eAOError);
|
68
|
+
|
69
|
+
/*
|
70
|
+
* Document-class: Audio::LiveOutput::DeviceError
|
71
|
+
*
|
72
|
+
* デバイスに関するエラー。
|
73
|
+
*/
|
74
|
+
cAO_eDeviceError =
|
75
|
+
rb_define_class_under(cAO_Live, "DeviceError", cAO_eAOError);
|
76
|
+
|
77
|
+
/*
|
78
|
+
* Document-class: Audio::FileOutput::FileError
|
79
|
+
*
|
80
|
+
* ファイル出力に関するエラー。
|
81
|
+
*/
|
82
|
+
cAO_eFileError =
|
83
|
+
rb_define_class_under(cAO_File, "FileError", cAO_eAOError);
|
84
|
+
|
85
|
+
/*
|
86
|
+
* Document-class: Audio::FileOutput::FileExists
|
87
|
+
*
|
88
|
+
* ファイル出力時の上書き禁止が設定されている時に
|
89
|
+
* 既にファイルが存在する場合に発生する。
|
90
|
+
*/
|
91
|
+
cAO_eFileExists =
|
92
|
+
rb_define_class_under(cAO_File, "FileExists", cAO_eAOError);
|
93
|
+
|
94
|
+
/*
|
95
|
+
* Document-class: Audio::FileOutput::Badformat
|
96
|
+
*
|
97
|
+
* オーディオ出力フォーマットが不正である場合発生する。
|
98
|
+
*/
|
99
|
+
cAO_eBadFormat =
|
100
|
+
rb_define_class_under(cAO_File, "BadFormat", cAO_eAOError);
|
101
|
+
|
102
|
+
/*
|
103
|
+
* Document-class: Audio::LiveOutput::UnknownError
|
104
|
+
*
|
105
|
+
* 不明なエラー。
|
106
|
+
*/
|
107
|
+
cAO_eUnknownError =
|
108
|
+
rb_define_class_under(cAO_Live, "UnknownError", cAO_eAOError);
|
109
|
+
return;
|
110
|
+
}
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#-*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'mkmf'
|
5
|
+
|
6
|
+
dir_config('audio')
|
7
|
+
have_header('ao/ao.h')
|
8
|
+
have_header('ao/os_types.h')
|
9
|
+
have_header('ao/plugin.h')
|
10
|
+
have_library('ao')
|
11
|
+
have_func('rb_thread_call_without_gvl')
|
12
|
+
create_makefile('audio/outputc')
|
data/ext/info.c
ADDED
@@ -0,0 +1,187 @@
|
|
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_Info;
|
10
|
+
VALUE cAO_eDriverError;
|
11
|
+
VALUE cAO_eBadFormat;
|
12
|
+
|
13
|
+
/*
|
14
|
+
ao_info構造体をRubyのHashに変換し返す。
|
15
|
+
*/
|
16
|
+
static VALUE
|
17
|
+
ao_info2hash(ao_info *info)
|
18
|
+
{
|
19
|
+
int opt_count;
|
20
|
+
VALUE ihash, optary;
|
21
|
+
|
22
|
+
ihash = rb_hash_new();
|
23
|
+
optary = rb_ary_new();
|
24
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("type")), INT2FIX(info->type));
|
25
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("name")), rb_str_new2(info->name));
|
26
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("short_name")), rb_str_new2(info->short_name));
|
27
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("author")), rb_str_new2(info->author));
|
28
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("comment")), rb_str_new2(info->comment));
|
29
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("byte_format")), INT2FIX(info->preferred_byte_format));
|
30
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("priority")), INT2FIX(info->priority));
|
31
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("opt_count")), INT2FIX(info->option_count));
|
32
|
+
for(opt_count=0; opt_count<info->option_count; opt_count++){
|
33
|
+
rb_ary_push(optary, rb_str_new2(info->options[opt_count]));
|
34
|
+
}
|
35
|
+
rb_hash_aset(ihash, ID2SYM(rb_intern("options")), optary);
|
36
|
+
return ihash;
|
37
|
+
}
|
38
|
+
|
39
|
+
/* driver information */
|
40
|
+
/*
|
41
|
+
* call-seq: Audio::Info.driver_id(short_name)
|
42
|
+
*
|
43
|
+
* short_nameを元にDriverIDを検索する。
|
44
|
+
* 見つからなかった場合はnilを返す。
|
45
|
+
*
|
46
|
+
* [arg1] short_name(String)
|
47
|
+
* [return] DriverID or nil
|
48
|
+
*/
|
49
|
+
static VALUE
|
50
|
+
rao_driver_id(VALUE obj, VALUE short_name)
|
51
|
+
{
|
52
|
+
int driver_id;
|
53
|
+
|
54
|
+
Check_Type(short_name, T_STRING);
|
55
|
+
driver_id = ao_driver_id(StringValuePtr(short_name));
|
56
|
+
if (driver_id < 0){
|
57
|
+
return Qnil;
|
58
|
+
}
|
59
|
+
return INT2FIX(driver_id);
|
60
|
+
}
|
61
|
+
|
62
|
+
/*
|
63
|
+
* call-seq: Audio::Info.default_driver_id
|
64
|
+
*
|
65
|
+
* デフォルトのDriverIDを返す。
|
66
|
+
* [return] DriverID
|
67
|
+
*/
|
68
|
+
static VALUE
|
69
|
+
rao_default_driver_id(VALUE obj)
|
70
|
+
{
|
71
|
+
int id;
|
72
|
+
|
73
|
+
id = ao_default_driver_id();
|
74
|
+
if (id < 0){
|
75
|
+
rb_raise(cAO_eNoDriver,
|
76
|
+
"Failure to find a usable audio output device.");
|
77
|
+
}
|
78
|
+
return INT2FIX(id);
|
79
|
+
}
|
80
|
+
|
81
|
+
/*
|
82
|
+
* call-seq: Audio::Info.driver_info(driver_id)
|
83
|
+
*
|
84
|
+
* ドライバの情報を確認する。
|
85
|
+
* ドライバ情報の要素順は以下の通り。
|
86
|
+
* [name(String), short_name(String), author(String),
|
87
|
+
* comment(String), preferred_byte_format(Fixnum),
|
88
|
+
* priority(Fixnum), option_count(Fixnum), options(Array)]
|
89
|
+
*
|
90
|
+
* [arg1] DriverID
|
91
|
+
* [return] Driver Information(Array)
|
92
|
+
*/
|
93
|
+
static VALUE
|
94
|
+
rao_driver_info(VALUE obj, VALUE driver_id)
|
95
|
+
{
|
96
|
+
ao_info *info;
|
97
|
+
|
98
|
+
Check_Type(driver_id, T_FIXNUM);
|
99
|
+
info = ao_driver_info(FIX2INT(driver_id));
|
100
|
+
if (info == NULL){
|
101
|
+
rb_raise(cAO_eNoDriver,
|
102
|
+
"Does not correspond to an actual driver.");
|
103
|
+
}
|
104
|
+
return ao_info2hash(info);;
|
105
|
+
}
|
106
|
+
|
107
|
+
/*
|
108
|
+
* call-seq: Audio::Info.driver_info_list
|
109
|
+
*
|
110
|
+
* システムのlibaoがサポートしているドライバ一覧を配列で返す。
|
111
|
+
* [return] ドライバ一覧の配列
|
112
|
+
*/
|
113
|
+
static VALUE
|
114
|
+
rao_driver_info_list(VALUE obj)
|
115
|
+
{
|
116
|
+
ao_info **info;
|
117
|
+
int info_count, driver_count;
|
118
|
+
VALUE iary;
|
119
|
+
|
120
|
+
iary = rb_ary_new();
|
121
|
+
info = ao_driver_info_list(&driver_count);
|
122
|
+
for (info_count=0; info_count<driver_count;
|
123
|
+
info_count++){
|
124
|
+
rb_ary_push(iary, ao_info2hash(info[info_count]));
|
125
|
+
}
|
126
|
+
return iary;
|
127
|
+
}
|
128
|
+
|
129
|
+
/*
|
130
|
+
* call-seq: Audio::Info.file_extension(driver_id)
|
131
|
+
*
|
132
|
+
* ファイル出力時の拡張子の標準を確認する。
|
133
|
+
*
|
134
|
+
* [arg1] DriverID
|
135
|
+
* [return] ext name(String)
|
136
|
+
*/
|
137
|
+
static VALUE
|
138
|
+
rao_file_extension(VALUE obj, VALUE driver_id)
|
139
|
+
{
|
140
|
+
char *ext;
|
141
|
+
|
142
|
+
Check_Type(driver_id, T_FIXNUM);
|
143
|
+
ext = (char *)ao_file_extension(FIX2INT(driver_id));
|
144
|
+
if (ext == NULL){
|
145
|
+
rb_raise(cAO_eDriverError,
|
146
|
+
"This driver has no file extension associated with it or if this driver does not exist.");
|
147
|
+
}
|
148
|
+
return rb_str_new2(ext);
|
149
|
+
}
|
150
|
+
|
151
|
+
/* miscellaneous */
|
152
|
+
/*
|
153
|
+
* call-seq: Audio::Info.bigendian?
|
154
|
+
*
|
155
|
+
* ホストの環境がビッグエンディアンであるか否かを調査する。
|
156
|
+
* [return] ビッグエンディアンであればtrue、リトルエンディアンであればfalse
|
157
|
+
*/
|
158
|
+
static VALUE
|
159
|
+
rao_is_big_endian(VALUE obj)
|
160
|
+
{
|
161
|
+
if (ao_is_big_endian() == 1){
|
162
|
+
return Qtrue;
|
163
|
+
} else {
|
164
|
+
return Qfalse;
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
void
|
169
|
+
init_info(void)
|
170
|
+
{
|
171
|
+
/*
|
172
|
+
* Document-class: Audio::Info
|
173
|
+
*
|
174
|
+
* オーディオ出力デバイスに関する情報を取り扱うモジュール。
|
175
|
+
*/
|
176
|
+
cAO_Info = rb_define_module_under(cAudio, "Info");
|
177
|
+
|
178
|
+
/* driver information */
|
179
|
+
rb_define_module_function(cAO_Info, "driver_id", rao_driver_id, 1);
|
180
|
+
rb_define_module_function(cAO_Info, "default_driver_id", rao_default_driver_id, 0);
|
181
|
+
rb_define_module_function(cAO_Info, "driver_info", rao_driver_info, 1);
|
182
|
+
rb_define_module_function(cAO_Info, "driver_info_list", rao_driver_info_list, 0);
|
183
|
+
rb_define_module_function(cAO_Info, "file_extension", rao_file_extension, 1);
|
184
|
+
|
185
|
+
/* miscellaneous */
|
186
|
+
rb_define_module_function(cAO_Info, "bigendian?", rao_is_big_endian, 0);
|
187
|
+
}
|