ruby-audio 1.5.0-x86-mingw32

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,37 @@
1
+ #ifndef RA_SOUND_H
2
+ #define RA_SOUND_H
3
+
4
+ #include <ruby.h>
5
+ #include <sndfile.h>
6
+ #include "ra_soundinfo.h"
7
+ #include "ra_buffer.h"
8
+
9
+ typedef struct {
10
+ SNDFILE *snd;
11
+ VALUE info;
12
+ int mode;
13
+ int closed;
14
+ } RA_SOUND;
15
+
16
+ void Init_ra_sound();
17
+
18
+ /*** Initialization and Memory Manangement ***/
19
+ static VALUE ra_sound_allocate(VALUE klass);
20
+ static void ra_sound_mark(RA_SOUND *snd);
21
+ static void ra_sound_free(RA_SOUND *snd);
22
+
23
+ /*** Singleton Methods ***/
24
+ static VALUE ra_sound_s_open(int argc, VALUE *argv, VALUE klass);
25
+
26
+ /*** Instance Methods ***/
27
+ static VALUE ra_sound_init(VALUE self, VALUE path, VALUE mode, VALUE info);
28
+ static VALUE ra_sound_info(VALUE self);
29
+ static VALUE ra_sound_seek(VALUE self, VALUE frames, VALUE whence);
30
+ static VALUE ra_sound_read(VALUE self, VALUE buf, VALUE frames);
31
+ static VALUE ra_sound_write(VALUE self, VALUE buf);
32
+ static VALUE ra_sound_addbuf(VALUE self, VALUE buf);
33
+ static VALUE ra_sound_close(VALUE self);
34
+ static VALUE ra_sound_close_safe(VALUE self);
35
+ static VALUE ra_sound_closed(VALUE self);
36
+
37
+ #endif // #ifndef RA_SOUND_H
@@ -0,0 +1,165 @@
1
+ #include "ra_soundinfo.h"
2
+
3
+ extern VALUE eRubyAudioError;
4
+
5
+ /*
6
+ * Class <code>CSoundInfo</code> is a very light wrapper around the
7
+ * <code>SF_INFO</code> struct exposed by libsndfile. It provides information
8
+ * about open sound files like format, length, samplerate, channels, and other
9
+ * things. In addition it can be used to specify the format of new sound files.
10
+ */
11
+ void Init_ra_soundinfo() {
12
+ VALUE mRubyAudio = rb_define_module("RubyAudio");
13
+ VALUE cRASoundInfo = rb_define_class_under(mRubyAudio, "CSoundInfo", rb_cObject);
14
+ rb_define_alloc_func(cRASoundInfo, ra_soundinfo_allocate);
15
+ rb_define_method(cRASoundInfo, "valid?", ra_soundinfo_valid, 0);
16
+ rb_define_method(cRASoundInfo, "frames", ra_soundinfo_frames, 0);
17
+ rb_define_method(cRASoundInfo, "samplerate", ra_soundinfo_samplerate, 0);
18
+ rb_define_method(cRASoundInfo, "samplerate=", ra_soundinfo_samplerate_set, 1);
19
+ rb_define_method(cRASoundInfo, "channels", ra_soundinfo_channels, 0);
20
+ rb_define_method(cRASoundInfo, "channels=", ra_soundinfo_channels_set, 1);
21
+ rb_define_method(cRASoundInfo, "format", ra_soundinfo_format, 0);
22
+ rb_define_method(cRASoundInfo, "format=", ra_soundinfo_format_set, 1);
23
+ rb_define_method(cRASoundInfo, "sections", ra_soundinfo_sections, 0);
24
+ rb_define_method(cRASoundInfo, "seekable", ra_soundinfo_seekable, 0);
25
+ }
26
+
27
+ static VALUE ra_soundinfo_allocate(VALUE klass) {
28
+ SF_INFO *info = ALLOC(SF_INFO);
29
+ memset(info, 0, sizeof(SF_INFO));
30
+ VALUE self = Data_Wrap_Struct(klass, NULL, ra_soundinfo_free, info);
31
+ return self;
32
+ }
33
+
34
+ static void ra_soundinfo_free(SF_INFO *info) {
35
+ xfree(info);
36
+ }
37
+
38
+ /*
39
+ * call-seq:
40
+ * info.valid? => true or false
41
+ *
42
+ * Calls <code>sf_format_check</code> on the underlying <code>SF_INFO</code>
43
+ * struct and returns true or false based on validity. Used when creating a new
44
+ * sound file to check that the format has enough information to properly create
45
+ * a new sound.
46
+ */
47
+ static VALUE ra_soundinfo_valid(VALUE self) {
48
+ SF_INFO *info;
49
+ Data_Get_Struct(self, SF_INFO, info);
50
+ return sf_format_check(info) ? Qtrue : Qfalse;
51
+ }
52
+
53
+ /*
54
+ * call-seq:
55
+ * info.frames => integer
56
+ *
57
+ * Returns the number of frames in the associated sound file.
58
+ */
59
+ static VALUE ra_soundinfo_frames(VALUE self) {
60
+ SF_INFO *info;
61
+ Data_Get_Struct(self, SF_INFO, info);
62
+ return OFFT2NUM(info->frames);
63
+ }
64
+
65
+ /*
66
+ * call-seq:
67
+ * info.samplerate => integer
68
+ *
69
+ * Returns the samplerate of the associated sound file.
70
+ */
71
+ static VALUE ra_soundinfo_samplerate(VALUE self) {
72
+ SF_INFO *info;
73
+ Data_Get_Struct(self, SF_INFO, info);
74
+ return INT2FIX(info->samplerate);
75
+ }
76
+
77
+ /*
78
+ * call-seq:
79
+ * info.samplerate = integer => integer
80
+ *
81
+ * Set the samplerate for a new sound created with the given info object.
82
+ */
83
+ static VALUE ra_soundinfo_samplerate_set(VALUE self, VALUE new_samplerate) {
84
+ SF_INFO *info;
85
+ Data_Get_Struct(self, SF_INFO, info);
86
+ info->samplerate = FIX2INT(new_samplerate);
87
+ return new_samplerate;
88
+ }
89
+
90
+ /*
91
+ * call-seq:
92
+ * info.channels => integer
93
+ *
94
+ * Returns the number of channels in the associated sound file.
95
+ */
96
+ static VALUE ra_soundinfo_channels(VALUE self) {
97
+ SF_INFO *info;
98
+ Data_Get_Struct(self, SF_INFO, info);
99
+ return INT2FIX(info->channels);
100
+ }
101
+
102
+ /*
103
+ * call-seq:
104
+ * info.channels = integer => integer
105
+ *
106
+ * Set the number of channels for a new sound created with the given info object.
107
+ */
108
+ static VALUE ra_soundinfo_channels_set(VALUE self, VALUE new_channels) {
109
+ SF_INFO *info;
110
+ Data_Get_Struct(self, SF_INFO, info);
111
+ info->channels = FIX2INT(new_channels);
112
+ return new_channels;
113
+ }
114
+
115
+ /*
116
+ * call-seq:
117
+ * info.format => integer
118
+ *
119
+ * Returns the format as a combination of binary flags of the associated sound file.
120
+ */
121
+ static VALUE ra_soundinfo_format(VALUE self) {
122
+ SF_INFO *info;
123
+ Data_Get_Struct(self, SF_INFO, info);
124
+ return INT2FIX(info->format);
125
+ }
126
+
127
+ /*
128
+ * call-seq:
129
+ * info.format = integer => integer
130
+ *
131
+ * Set the format for a new sound created with the given info object.
132
+ *
133
+ * info = RubyAudio::CSoundInfo.new
134
+ * info.format = RubyAudio::FORMAT_WAV|RubyAudio::FORMAT_PCM_16
135
+ */
136
+ static VALUE ra_soundinfo_format_set(VALUE self, VALUE new_format) {
137
+ SF_INFO *info;
138
+ Data_Get_Struct(self, SF_INFO, info);
139
+ info->format = FIX2INT(new_format);
140
+ return new_format;
141
+ }
142
+
143
+ /*
144
+ * call-seq:
145
+ * info.sections => integer
146
+ *
147
+ * Returns the number of sections in the associated sound file.
148
+ */
149
+ static VALUE ra_soundinfo_sections(VALUE self) {
150
+ SF_INFO *info;
151
+ Data_Get_Struct(self, SF_INFO, info);
152
+ return INT2FIX(info->sections);
153
+ }
154
+
155
+ /*
156
+ * call-seq:
157
+ * info.seekable => true or false
158
+ *
159
+ * Whether seeking is supported for the associated sound file.
160
+ */
161
+ static VALUE ra_soundinfo_seekable(VALUE self) {
162
+ SF_INFO *info;
163
+ Data_Get_Struct(self, SF_INFO, info);
164
+ return info->seekable ? Qtrue : Qfalse;
165
+ }
@@ -0,0 +1,25 @@
1
+ #ifndef RA_SOUNDINFO_H
2
+ #define RA_SOUNDINFO_H
3
+
4
+ #include <ruby.h>
5
+ #include <sndfile.h>
6
+
7
+ void Init_ra_soundinfo();
8
+
9
+ /*** Initialization and Memory Manangement ***/
10
+ static VALUE ra_soundinfo_allocate(VALUE klass);
11
+ static void ra_soundinfo_free(SF_INFO *info);
12
+
13
+ /*** Instance Methods ***/
14
+ static VALUE ra_soundinfo_valid(VALUE self);
15
+ static VALUE ra_soundinfo_frames(VALUE self);
16
+ static VALUE ra_soundinfo_samplerate(VALUE self);
17
+ static VALUE ra_soundinfo_samplerate_set(VALUE self, VALUE new_samplerate);
18
+ static VALUE ra_soundinfo_channels(VALUE self);
19
+ static VALUE ra_soundinfo_channels_set(VALUE self, VALUE new_channels);
20
+ static VALUE ra_soundinfo_format(VALUE self);
21
+ static VALUE ra_soundinfo_format_set(VALUE self, VALUE new_format);
22
+ static VALUE ra_soundinfo_sections(VALUE self);
23
+ static VALUE ra_soundinfo_seekable(VALUE self);
24
+
25
+ #endif // #ifndef RA_SOUNDINFO_H
@@ -0,0 +1,92 @@
1
+ #include <ruby.h>
2
+ #include <sndfile.h>
3
+
4
+ void Init_ra_buffer();
5
+ void Init_ra_soundinfo();
6
+ void Init_ra_sound();
7
+
8
+ VALUE eRubyAudioError;
9
+
10
+ /*
11
+ * Document-module: RubyAudio
12
+ */
13
+ /*
14
+ * Document-class: RubyAudio::Error
15
+ *
16
+ * Error class for RubyAudio
17
+ */
18
+ void Init_rubyaudio_ext() {
19
+ // Create RubyAudio module and other setup
20
+ VALUE mRubyAudio = rb_define_module("RubyAudio");
21
+ eRubyAudioError = rb_define_class_under(mRubyAudio, "Error", rb_eStandardError);
22
+
23
+ // Set up classes
24
+ Init_ra_buffer();
25
+ Init_ra_soundinfo();
26
+ Init_ra_sound();
27
+
28
+ // Export libsndfile constants
29
+ // Major formats
30
+ rb_define_const(mRubyAudio, "FORMAT_WAV", /* 0x010000 */ INT2FIX(SF_FORMAT_WAV));
31
+ rb_define_const(mRubyAudio, "FORMAT_AIFF", /* 0x020000 */ INT2FIX(SF_FORMAT_AIFF));
32
+ rb_define_const(mRubyAudio, "FORMAT_AU", /* 0x030000 */ INT2FIX(SF_FORMAT_AU));
33
+ rb_define_const(mRubyAudio, "FORMAT_RAW", /* 0x040000 */ INT2FIX(SF_FORMAT_RAW));
34
+ rb_define_const(mRubyAudio, "FORMAT_PAF", /* 0x050000 */ INT2FIX(SF_FORMAT_PAF));
35
+ rb_define_const(mRubyAudio, "FORMAT_SVX", /* 0x060000 */ INT2FIX(SF_FORMAT_SVX));
36
+ rb_define_const(mRubyAudio, "FORMAT_NIST", /* 0x070000 */ INT2FIX(SF_FORMAT_NIST));
37
+ rb_define_const(mRubyAudio, "FORMAT_VOC", /* 0x080000 */ INT2FIX(SF_FORMAT_VOC));
38
+ rb_define_const(mRubyAudio, "FORMAT_IRCAM", /* 0x0A0000 */ INT2FIX(SF_FORMAT_IRCAM));
39
+ rb_define_const(mRubyAudio, "FORMAT_W64", /* 0x0B0000 */ INT2FIX(SF_FORMAT_W64));
40
+ rb_define_const(mRubyAudio, "FORMAT_MAT4", /* 0x0C0000 */ INT2FIX(SF_FORMAT_MAT4));
41
+ rb_define_const(mRubyAudio, "FORMAT_MAT5", /* 0x0D0000 */ INT2FIX(SF_FORMAT_MAT5));
42
+ rb_define_const(mRubyAudio, "FORMAT_PVF", /* 0x0E0000 */ INT2FIX(SF_FORMAT_PVF));
43
+ rb_define_const(mRubyAudio, "FORMAT_XI", /* 0x0F0000 */ INT2FIX(SF_FORMAT_XI));
44
+ rb_define_const(mRubyAudio, "FORMAT_HTK", /* 0x100000 */ INT2FIX(SF_FORMAT_HTK));
45
+ rb_define_const(mRubyAudio, "FORMAT_SDS", /* 0x110000 */ INT2FIX(SF_FORMAT_SDS));
46
+ rb_define_const(mRubyAudio, "FORMAT_AVR", /* 0x120000 */ INT2FIX(SF_FORMAT_AVR));
47
+ rb_define_const(mRubyAudio, "FORMAT_WAVEX", /* 0x130000 */ INT2FIX(SF_FORMAT_WAVEX));
48
+ rb_define_const(mRubyAudio, "FORMAT_SD2", /* 0x160000 */ INT2FIX(SF_FORMAT_SD2));
49
+ rb_define_const(mRubyAudio, "FORMAT_FLAC", /* 0x170000 */ INT2FIX(SF_FORMAT_FLAC));
50
+ rb_define_const(mRubyAudio, "FORMAT_CAF", /* 0x180000 */ INT2FIX(SF_FORMAT_CAF));
51
+ #ifdef HAVE_CONST_SF_FORMAT_OGG
52
+ rb_define_const(mRubyAudio, "FORMAT_OGG", /* 0x200000 */ INT2FIX(SF_FORMAT_OGG));
53
+ #endif
54
+
55
+ // Subtypes from here on
56
+ rb_define_const(mRubyAudio, "FORMAT_PCM_S8", /* 0x0001 */ INT2FIX(SF_FORMAT_PCM_S8));
57
+ rb_define_const(mRubyAudio, "FORMAT_PCM_16", /* 0x0002 */ INT2FIX(SF_FORMAT_PCM_16));
58
+ rb_define_const(mRubyAudio, "FORMAT_PCM_24", /* 0x0003 */ INT2FIX(SF_FORMAT_PCM_24));
59
+ rb_define_const(mRubyAudio, "FORMAT_PCM_32", /* 0x0004 */ INT2FIX(SF_FORMAT_PCM_32));
60
+ rb_define_const(mRubyAudio, "FORMAT_PCM_U8", /* 0x0005 */ INT2FIX(SF_FORMAT_PCM_U8));
61
+ rb_define_const(mRubyAudio, "FORMAT_FLOAT", /* 0x0006 */ INT2FIX(SF_FORMAT_FLOAT));
62
+ rb_define_const(mRubyAudio, "FORMAT_DOUBLE", /* 0x0007 */ INT2FIX(SF_FORMAT_DOUBLE));
63
+ rb_define_const(mRubyAudio, "FORMAT_ULAW", /* 0x0010 */ INT2FIX(SF_FORMAT_ULAW));
64
+ rb_define_const(mRubyAudio, "FORMAT_ALAW", /* 0x0011 */ INT2FIX(SF_FORMAT_ALAW));
65
+ rb_define_const(mRubyAudio, "FORMAT_IMA_ADPCM", /* 0x0012 */ INT2FIX(SF_FORMAT_IMA_ADPCM));
66
+ rb_define_const(mRubyAudio, "FORMAT_MS_ADPCM", /* 0x0013 */ INT2FIX(SF_FORMAT_MS_ADPCM));
67
+ rb_define_const(mRubyAudio, "FORMAT_GSM610", /* 0x0020 */ INT2FIX(SF_FORMAT_GSM610));
68
+ rb_define_const(mRubyAudio, "FORMAT_VOX_ADPCM", /* 0x0021 */ INT2FIX(SF_FORMAT_VOX_ADPCM));
69
+ rb_define_const(mRubyAudio, "FORMAT_G721_32", /* 0x0030 */ INT2FIX(SF_FORMAT_G721_32));
70
+ rb_define_const(mRubyAudio, "FORMAT_G723_24", /* 0x0031 */ INT2FIX(SF_FORMAT_G723_24));
71
+ rb_define_const(mRubyAudio, "FORMAT_G723_40", /* 0x0032 */ INT2FIX(SF_FORMAT_G723_40));
72
+ rb_define_const(mRubyAudio, "FORMAT_DWVW_12", /* 0x0040 */ INT2FIX(SF_FORMAT_DWVW_12));
73
+ rb_define_const(mRubyAudio, "FORMAT_DWVW_16", /* 0x0041 */ INT2FIX(SF_FORMAT_DWVW_16));
74
+ rb_define_const(mRubyAudio, "FORMAT_DWVW_24", /* 0x0042 */ INT2FIX(SF_FORMAT_DWVW_24));
75
+ rb_define_const(mRubyAudio, "FORMAT_DWVW_N", /* 0x0043 */ INT2FIX(SF_FORMAT_DWVW_N));
76
+ rb_define_const(mRubyAudio, "FORMAT_DPCM_8", /* 0x0050 */ INT2FIX(SF_FORMAT_DPCM_8));
77
+ rb_define_const(mRubyAudio, "FORMAT_DPCM_16", /* 0x0051 */ INT2FIX(SF_FORMAT_DPCM_16));
78
+ #ifdef HAVE_CONST_SF_FORMAT_OGG
79
+ rb_define_const(mRubyAudio, "FORMAT_VORBIS", /* 0x0060 */ INT2FIX(SF_FORMAT_VORBIS));
80
+ #endif
81
+
82
+ // Endian-ness options
83
+ rb_define_const(mRubyAudio, "ENDIAN_FILE", /* 0x00000000 */ INT2FIX(SF_ENDIAN_FILE));
84
+ rb_define_const(mRubyAudio, "ENDIAN_LITTLE", /* 0x10000000 */ INT2FIX(SF_ENDIAN_LITTLE));
85
+ rb_define_const(mRubyAudio, "ENDIAN_BIG", /* 0x20000000 */ INT2FIX(SF_ENDIAN_BIG));
86
+ rb_define_const(mRubyAudio, "ENDIAN_CPU", /* 0x30000000 */ INT2FIX(SF_ENDIAN_CPU));
87
+
88
+ // Format masks
89
+ rb_define_const(mRubyAudio, "FORMAT_SUBMASK", /* 0x0000FFFF */ INT2FIX(SF_FORMAT_SUBMASK));
90
+ rb_define_const(mRubyAudio, "FORMAT_TYPEMASK", /* 0x0FFF0000 */ INT2FIX(SF_FORMAT_TYPEMASK));
91
+ rb_define_const(mRubyAudio, "FORMAT_ENDMASK", /* 0x30000000 */ INT2FIX(SF_FORMAT_ENDMASK));
92
+ }
Binary file
Binary file
@@ -0,0 +1,10 @@
1
+ begin
2
+ # Fat binaries for Windows
3
+ RUBY_VERSION =~ /(\d+.\d+)/
4
+ require "#{$1}/rubyaudio_ext"
5
+ rescue LoadError
6
+ require "rubyaudio_ext"
7
+ end
8
+ require 'ruby-audio/buffer'
9
+ require 'ruby-audio/sound_info'
10
+ require 'ruby-audio/sound'
@@ -0,0 +1,25 @@
1
+ module RubyAudio
2
+ # The <code>Buffer</code> class contains sound data read out of the sound. It
3
+ # can store a fixed maximum number of multi-channel audio frames of a specifi
4
+ # data type. Valid types are <code>short</code>, <code>int</code>,
5
+ # <code>float</code>, and <code>double</code>. The channel count must match up
6
+ # to the channel count of the sounds being read and written to. Trying to read
7
+ # into a buffer with the wrong number of channels will result in an error.
8
+ #
9
+ # Example:
10
+ # buf = RubyAudio::Buffer.float(1000)
11
+ # buf = RubyAudio::Buffer.new("float", 1000, 1)
12
+ class Buffer < CBuffer
13
+ include Enumerable
14
+
15
+ def each
16
+ self.size.times do |i|
17
+ yield self[i]
18
+ end
19
+ end
20
+
21
+ [:short, :int, :float, :double].each do |type|
22
+ eval "def self.#{type}(frames, channels=1); self.new(:#{type}, frames, channels); end"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,85 @@
1
+ module RubyAudio
2
+ # Class <code>Sound</code> wraps libsndfile to provide simple reading and
3
+ # writing for a wide variety of file formats
4
+ #
5
+ # Reading Example:
6
+ # RubyAudio::Sound.open('sound.wav') do |snd|
7
+ # buf = snd.read(:float, 100)
8
+ # puts buf.real_size #=> 100
9
+ # end
10
+ #
11
+ # Writing Example:
12
+ # buf = RubyAudio::Buffer.float(1000)
13
+ # out = nil
14
+ # ['snd1.wav', 'snd2.wav', 'snd3.wav'].each do |file|
15
+ # RubyAudio::Sound.open(file) do |snd|
16
+ # out = RubyAudio::Sound.open('out.wav', 'w', snd.info.clone) if out.nil?
17
+ #
18
+ # while snd.read(buf) != 0
19
+ # out.write(buf)
20
+ # end
21
+ # end
22
+ # end
23
+ # out.close if out
24
+ class Sound < CSound
25
+ # Creates a new <code>Sound</code> object for the audio file at the given path.
26
+ # Mode defaults to <code>"r"</code>, but valid modes are <code>"r"</code>,
27
+ # <code>"w"</code>, and <code>"rw"</code>.
28
+ #
29
+ # When creating a new sound, a valid <code>SoundInfo</code> object must be
30
+ # passed in, as libsndfile uses it to determine the output format.
31
+ # info = RubyAudio::SoundInfo.new :channels => 1, :samplerate => 48000, :format => RubyAudio::FORMAT_WAV|RubyAudio::FORMAT_PCM_16
32
+ # snd = RubyAudio::Sound.new "new.wav", 'r', info
33
+ def initialize(path, mode='r', info=nil)
34
+ info ||= SoundInfo.new
35
+ super(path, mode, info)
36
+ end
37
+
38
+ # Seeks to a given offset <i>anInteger</i> in the sound according to the value
39
+ # of <i>whence</i>:
40
+ #
41
+ # IO::SEEK_CUR | Seeks to _frames_ plus current position
42
+ # --------------+----------------------------------------------------
43
+ # IO::SEEK_END | Seeks to _frames_ plus end of stream (you probably
44
+ # | want a negative value for _frames_)
45
+ # --------------+----------------------------------------------------
46
+ # IO::SEEK_SET | Seeks to the absolute location given by _frames_
47
+ def seek(frames, whence=IO::SEEK_SET)
48
+ super(frames, whence)
49
+ end
50
+
51
+ # Reads a given number of frames from the sound into a buffer
52
+ #
53
+ # When given a buffer as the first argument, it reads data into that buffer
54
+ # reading an optional number of frames as the second argument. It returns
55
+ # the number of frames read.
56
+ #
57
+ # Example:
58
+ # buf = RubyAudio::Buffer.float(1000)
59
+ # snd.read(buf) #=> 1000
60
+ # snd.read(buf, 50) #=> 50
61
+ #
62
+ # When given a string or symbol as the first argument, it interprets this as
63
+ # the data type and creates a new buffer of the given size to read the data
64
+ # into. The buffer is correctly initialized with the proper number of channels
65
+ # to hold data from that sound.
66
+ #
67
+ # Example:
68
+ # buf = snd.read("int", 1000)
69
+ def read(*args)
70
+ case args[0]
71
+ when Buffer
72
+ buf = args[0]
73
+ size = args[1] || buf.size
74
+ return super(buf, size)
75
+ when Symbol, String
76
+ type = args[0]
77
+ buf = Buffer.new(type, args[1], info.channels)
78
+ super(buf, buf.size)
79
+ return buf
80
+ else
81
+ raise ArgumentError, "invalid arguments"
82
+ end
83
+ end
84
+ end
85
+ end