alsactl 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 867a15dbe3727200b48ae90e35ad96c010bb19395b94f70629e2564979b2c76a
4
+ data.tar.gz: b19233f1ee8a13d44fef4daaf58eab05077c50418299ff590966b8b35ae0aa18
5
+ SHA512:
6
+ metadata.gz: 6a5945c2b798ddee40b49fcff6fd35de7cc00063210464743eee7195022c4ac7c56c250df6fe3bc921f8cac9e381f005d856d956f53345cf44f379ab89d964fd
7
+ data.tar.gz: b5832781e76557308f42a34253ad9978f5c90812cce6e96cb286793592c99d392f44ef407a43a780d93cbb308fc2fab776718529301ef78a2fad7d3b69264e53
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ ### CHANGELOG -- (Ruby AlsaCtl) ###
2
+ 1) 0.1.0, unreleased: 2021-May-04 -- Changed the API to use Ruby as the complex implementation interface, because faster to get it done, less code, and way simpler than doing all the higher-order calculations (as well as string and symbol comparisons) in the C wrapper. [t. Edelweiss]
3
+ 1) 0.1.0, unreleased: 2021-May-04 -- In so doing above, turned entire C wrapper into an abstract class and module, so it can only be implemented by inheritance. Added such an implementation class, ``Mixers::DefMixer``. [t. Edelweiss]
4
+ 1) 0.1.0, immediate pre-release: 2021-May-09 -- Realized that this gem was named too generic and changed the name to AlsaCtl, as there is a reasonable chance I might need to also handle PulseAudio or other APIs, at some point. Please also note the difference in the GitHub repo URL.
data/LICENSE.txt ADDED
@@ -0,0 +1,165 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+
9
+ This version of the GNU Lesser General Public License incorporates
10
+ the terms and conditions of version 3 of the GNU General Public
11
+ License, supplemented by the additional permissions listed below.
12
+
13
+ 0. Additional Definitions.
14
+
15
+ As used herein, "this License" refers to version 3 of the GNU Lesser
16
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
+ General Public License.
18
+
19
+ "The Library" refers to a covered work governed by this License,
20
+ other than an Application or a Combined Work as defined below.
21
+
22
+ An "Application" is any work that makes use of an interface provided
23
+ by the Library, but which is not otherwise based on the Library.
24
+ Defining a subclass of a class defined by the Library is deemed a mode
25
+ of using an interface provided by the Library.
26
+
27
+ A "Combined Work" is a work produced by combining or linking an
28
+ Application with the Library. The particular version of the Library
29
+ with which the Combined Work was made is also called the "Linked
30
+ Version".
31
+
32
+ The "Minimal Corresponding Source" for a Combined Work means the
33
+ Corresponding Source for the Combined Work, excluding any source code
34
+ for portions of the Combined Work that, considered in isolation, are
35
+ based on the Application, and not on the Linked Version.
36
+
37
+ The "Corresponding Application Code" for a Combined Work means the
38
+ object code and/or source code for the Application, including any data
39
+ and utility programs needed for reproducing the Combined Work from the
40
+ Application, but excluding the System Libraries of the Combined Work.
41
+
42
+ 1. Exception to Section 3 of the GNU GPL.
43
+
44
+ You may convey a covered work under sections 3 and 4 of this License
45
+ without being bound by section 3 of the GNU GPL.
46
+
47
+ 2. Conveying Modified Versions.
48
+
49
+ If you modify a copy of the Library, and, in your modifications, a
50
+ facility refers to a function or data to be supplied by an Application
51
+ that uses the facility (other than as an argument passed when the
52
+ facility is invoked), then you may convey a copy of the modified
53
+ version:
54
+
55
+ a) under this License, provided that you make a good faith effort to
56
+ ensure that, in the event an Application does not supply the
57
+ function or data, the facility still operates, and performs
58
+ whatever part of its purpose remains meaningful, or
59
+
60
+ b) under the GNU GPL, with none of the additional permissions of
61
+ this License applicable to that copy.
62
+
63
+ 3. Object Code Incorporating Material from Library Header Files.
64
+
65
+ The object code form of an Application may incorporate material from
66
+ a header file that is part of the Library. You may convey such object
67
+ code under terms of your choice, provided that, if the incorporated
68
+ material is not limited to numerical parameters, data structure
69
+ layouts and accessors, or small macros, inline functions and templates
70
+ (ten or fewer lines in length), you do both of the following:
71
+
72
+ a) Give prominent notice with each copy of the object code that the
73
+ Library is used in it and that the Library and its use are
74
+ covered by this License.
75
+
76
+ b) Accompany the object code with a copy of the GNU GPL and this license
77
+ document.
78
+
79
+ 4. Combined Works.
80
+
81
+ You may convey a Combined Work under terms of your choice that,
82
+ taken together, effectively do not restrict modification of the
83
+ portions of the Library contained in the Combined Work and reverse
84
+ engineering for debugging such modifications, if you also do each of
85
+ the following:
86
+
87
+ a) Give prominent notice with each copy of the Combined Work that
88
+ the Library is used in it and that the Library and its use are
89
+ covered by this License.
90
+
91
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
+ document.
93
+
94
+ c) For a Combined Work that displays copyright notices during
95
+ execution, include the copyright notice for the Library among
96
+ these notices, as well as a reference directing the user to the
97
+ copies of the GNU GPL and this license document.
98
+
99
+ d) Do one of the following:
100
+
101
+ 0) Convey the Minimal Corresponding Source under the terms of this
102
+ License, and the Corresponding Application Code in a form
103
+ suitable for, and under terms that permit, the user to
104
+ recombine or relink the Application with a modified version of
105
+ the Linked Version to produce a modified Combined Work, in the
106
+ manner specified by section 6 of the GNU GPL for conveying
107
+ Corresponding Source.
108
+
109
+ 1) Use a suitable shared library mechanism for linking with the
110
+ Library. A suitable mechanism is one that (a) uses at run time
111
+ a copy of the Library already present on the user's computer
112
+ system, and (b) will operate properly with a modified version
113
+ of the Library that is interface-compatible with the Linked
114
+ Version.
115
+
116
+ e) Provide Installation Information, but only if you would otherwise
117
+ be required to provide such information under section 6 of the
118
+ GNU GPL, and only to the extent that such information is
119
+ necessary to install and execute a modified version of the
120
+ Combined Work produced by recombining or relinking the
121
+ Application with a modified version of the Linked Version. (If
122
+ you use option 4d0, the Installation Information must accompany
123
+ the Minimal Corresponding Source and Corresponding Application
124
+ Code. If you use option 4d1, you must provide the Installation
125
+ Information in the manner specified by section 6 of the GNU GPL
126
+ for conveying Corresponding Source.)
127
+
128
+ 5. Combined Libraries.
129
+
130
+ You may place library facilities that are a work based on the
131
+ Library side by side in a single library together with other library
132
+ facilities that are not Applications and are not covered by this
133
+ License, and convey such a combined library under terms of your
134
+ choice, if you do both of the following:
135
+
136
+ a) Accompany the combined library with a copy of the same work based
137
+ on the Library, uncombined with any other library facilities,
138
+ conveyed under the terms of this License.
139
+
140
+ b) Give prominent notice with the combined library that part of it
141
+ is a work based on the Library, and explaining where to find the
142
+ accompanying uncombined form of the same work.
143
+
144
+ 6. Revised Versions of the GNU Lesser General Public License.
145
+
146
+ The Free Software Foundation may publish revised and/or new versions
147
+ of the GNU Lesser General Public License from time to time. Such new
148
+ versions will be similar in spirit to the present version, but may
149
+ differ in detail to address new problems or concerns.
150
+
151
+ Each version is given a distinguishing version number. If the
152
+ Library as you received it specifies that a certain numbered version
153
+ of the GNU Lesser General Public License "or any later version"
154
+ applies to it, you have the option of following the terms and
155
+ conditions either of that published version or of any later version
156
+ published by the Free Software Foundation. If the Library as you
157
+ received it does not specify a version number of the GNU Lesser
158
+ General Public License, you may choose any version of the GNU Lesser
159
+ General Public License ever published by the Free Software Foundation.
160
+
161
+ If the Library as you received it specifies that a proxy can decide
162
+ whether future versions of the GNU Lesser General Public License shall
163
+ apply, that proxy's public statement of acceptance of any version is
164
+ permanent authorization for you to choose that version for the
165
+ Library.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ ### OVERVIEW ###
2
+ AlsaCtl is a C-Ruby API wrapper with a pure Ruby middleware, for the ALSA library on Linux. By default, it handles the ``default/Master`` mixer object (current default volume controller). The base class, ``AlsaCore::BaseMixer`` cannot be instantiated, and all methods outside of allocation are protected, so it acts as an abstract-only class. However, you may derive from it, such as the ``AlsaCtl::DefMixer`` object ``(class DefMixer < AlsaCore::BaseMixer)``.
3
+
4
+ ### USAGE ###
5
+ ```ruby
6
+ m = AlsaCtl::DefMixer.new # Creates a new default mixer object
7
+ m.connect # By default, calls BaseMixer.connect("default", "Master")
8
+ m.disconnect # Disconnects from the ALSA server -- do NOT use after, will cause crash (until I update)
9
+ m.close # Same as above
10
+
11
+ m.enum # List off all the valid channels for the device
12
+
13
+ m.volume # Returns the volumes by channel
14
+ m.vget # Same as above
15
+ m.c_vget :channel_id # Get the volume of a specific channel
16
+ # ex 1: m.c_vget 3 <- gets the volume of the 4th channel (indices start at 0)
17
+ # ex 2: m.c_vget 300000 <- will return FALSE, b/c this channel isn't valid
18
+ # ex 3: m.c_vget "pizza" <- will return NIL, b/c this TYPE isn't valid
19
+
20
+ m.set_volume :percent, :change_type # Sets the volume of all channels
21
+ m.vset :percent, :change_type # Same as above
22
+ # ex 1: m.set_volume 15, -1 <- Turns the volume down by 15%
23
+ # ex 2: m.set_volume 15, 1 <- Turns the volume up by 15%
24
+ # ex 3: m.set_volume 15, 0 <- Turns the volume to 15%
25
+ m.c_vset :channel, :percent, :change_type # Set single channel's volume
26
+ # ex 1: m.c_vset 1, 15, :lower (or :down, :decrease) <- Turns the volume down by 15%
27
+ # ex 2: m.c_vset 1, 15, :up (or :raise, :increase) <- Turns the volume up by 15%
28
+ # ex 3: m.c_vset 1, 15, nil (or anything else) <- Turns the volume to 15%
29
+
30
+ m.mute # Mutes the volume, storing the current volume or else a 50% default
31
+ m.unmute # Unmutes the volume
32
+ ```
33
+
34
+ ### TO-DO ###
35
+ 1) Start the next version, 0.2.0 _WITH_
36
+ 1) Create derived class from ``DefMixer`` with non-flat volume modulation (such as for use in spatially-oriented physical speaker configurations)
37
+ 1) Derive other desirable classes for other common controllers
38
+ 1) EVENTUALLY, add PCM and capture classes
39
+
40
+ ### INSTALLATION ###
41
+ ```
42
+ gem install alsactl
43
+ ```
@@ -0,0 +1,10 @@
1
+ # ext/alsacore/extconf.rb
2
+ require 'mkmf'
3
+
4
+ # Build MixCore
5
+ $LFLAGS = '-lasound'
6
+ have_library("asound")
7
+ have_header("alsa/asoundlib.h")
8
+ have_func("snd_mixer_open")
9
+ have_func("snd_mixer_close")
10
+ create_makefile("alsacore/alsacore")
Binary file
data/lib/alsactl.rb ADDED
@@ -0,0 +1,7 @@
1
+ # lib/alsactl.rb
2
+
3
+ # This module include a C wrapper for
4
+ # controlling basic Linux ALSA volume
5
+ # settings on the system
6
+ require_relative("./alsactl/mixers")
7
+ require_relative("./alsactl/version")
@@ -0,0 +1,259 @@
1
+ # lib/alsactl/mixer.rb
2
+
3
+ require_relative "../alsacore/alsacore"
4
+
5
+ ##
6
+ # This extends the regular AlsaCore module and
7
+ # includes classes abstracted from the C code
8
+ # in the extension.
9
+ #
10
+ # I realized that the vast majority of the actual
11
+ # operations should be performed in an abstracted
12
+ # class; and only core, concrete operations needed
13
+ # to be included in the C code portion.
14
+ module AlsaCtl
15
+ ##
16
+ # Finalized computation for a volume setting.
17
+ #
18
+ # This is not intended to be used directly, but
19
+ # it helps separate functionality.
20
+ #
21
+ # Returns the volume limit as a +FixedNum+, used
22
+ # as a +long+ in the C code portion of the extension.
23
+ def self.compute_final(min, max, adjustment)
24
+ case
25
+ when adjustment > max
26
+ max
27
+ when adjustment < min
28
+ min
29
+ else
30
+ adjustment
31
+ end
32
+ end # End finalized computation
33
+
34
+ ##
35
+ # Compute the volume to set a channel.
36
+ #
37
+ # Makes use of +compute_final+, as well as a type for
38
+ # the change. The type will be a symbol of any of the
39
+ # following values:
40
+ #
41
+ # 1. +:raise+, +:up+, or +:increase+ to raise the volume.
42
+ # 2. +:lower+, +:down+, or +:decrease+ to lower the volume.
43
+ # 3. Any other value (use +nil+) to set the volume to a number.
44
+ def self.compute(min, max, current, perc_change, type_change)
45
+ change = ((max * perc_change) / 100).round
46
+ case type_change
47
+ when :raise, :up, :increase
48
+ self.compute_final(min, max, (current + change))
49
+ when :lower, :down, :decrease
50
+ self.compute_final(min, max, (current - change))
51
+ else
52
+ self.compute_final(min, max, change)
53
+ end
54
+ end # End abstracted compute method
55
+
56
+ ##
57
+ # This is a default mixer type that will handle normal
58
+ # mixer capabilities. It will make use of the +BaseMixer+
59
+ # setters and getters for the volume, handle general
60
+ # muting operations, and store data that was previously
61
+ # loaded into the original +VolumeCtl::Mixer+
62
+ # (now +AlsaCore::BaseMixer+) class.
63
+ class DefMixer < AlsaCore::BaseMixer
64
+ ##
65
+ # 1. List of channels for the mixer object
66
+ # 2. List of volume states, used for muting and unmuting
67
+ attr_reader :channels, :mute_state
68
+
69
+ ##
70
+ # The +DefMixer+ constructor takes no arguments.
71
+ #
72
+ # It gets the pointers to the +mixer->handle+ and
73
+ # +mixer->element+ objects in the wrapped +BaseMixer+
74
+ # class in the C code, utilizing the protected init method.
75
+ #
76
+ # It then clears up the instance variables.
77
+ def initialize
78
+ pro_initialize # Call the hidden, protected constructor
79
+ reset # Reset/initialize instance variables
80
+ end # end constructor
81
+
82
+ ##
83
+ # Reset the variables (in case reloading mixer).
84
+ #
85
+ # +reload+ sets the +@mute_state+ and +@channels+
86
+ # to +nil+, so the mixer does not try to access
87
+ # invalid data.
88
+ def reset() @mute_state = @channels = nil end
89
+
90
+ ##
91
+ # Connect to the current mixer and enumerate
92
+ # the channels. See: +enum+ for more information.
93
+ def connect
94
+ pro_connect("default", "Master")
95
+ enum
96
+ end # End connect/enum
97
+
98
+ ##
99
+ # Disconnect from the mixer. You should call this,
100
+ # when you are done using it, so that there's less of a
101
+ # chance of errors with GC.
102
+ def disconnect()
103
+ pro_disconnect # Disconnect the mixer
104
+ reset # Reset the instance variables
105
+ end
106
+ alias :close :disconnect # End disconnect method and aliases
107
+
108
+ ##
109
+ # Enumerate the channels.
110
+ #
111
+ # Will return the channels from the underlying +BaseMixer+,
112
+ # but it is unlikely that they need to be processed,
113
+ # so the return value can usually be disregarded,
114
+ # unless it is +nil+, which means it failed.
115
+ def enum() @channels = pro_enum end
116
+
117
+ ##
118
+ # Get the volumes from a channel.
119
+ #
120
+ # +c_vget+ takes as an argument a single number,
121
+ # used to identify the channel the mixer should find
122
+ # the volume for.
123
+ #
124
+ # = Example
125
+ #
126
+ # [mixer].c_vget 0 ->
127
+ # {:name=>"Front Left", :max=>65536, :min=>0, :volume=>32768, :percent=>50}
128
+ def c_vget(channel) pro_cvolume_get(channel) end
129
+ alias :c_volume :c_vget
130
+
131
+ ##
132
+ # Get all the volumes and return them as
133
+ # a clean hash.
134
+ #
135
+ # +vget+, alias +volume+, returns a has with ALL the
136
+ # volumes by channel number/ID, listed with the following fields:
137
+ #
138
+ # 1. +:name+ -- the name of the channel, such as "Front Left"
139
+ # 2. +:max+ -- the maximum volume allowed for the channel (probably 65_536)
140
+ # 3. +:min+ -- the minimum volumes allowed for the channel (usually 0)
141
+ # 4. +:volume+ -- the current volume as a C +long+
142
+ # 5. +:percent+ -- the current volume as a percent of max
143
+ #
144
+ # This method takes no arguments and returns a hash.
145
+ def vget
146
+ volumes = Hash.new
147
+ if @channels then # @channels is nil, if not enumerated and will raise errors
148
+ @channels.each do |k,v|
149
+ cv = c_vget(k) # Get volume for each channel
150
+ volumes[k] = cv
151
+ end # If no channels, print an error to STDERR
152
+ else $stderr.puts "ERROR: No channels detected. Is mixer connected ('.connect')?" end
153
+ volumes # Return volumes, unless
154
+ end
155
+ alias :volume :vget # End getter of volumes
156
+
157
+ ##
158
+ # Set a single channel's volume.
159
+ #
160
+ # Takes as args, +channel (Int)+, +perc_change (Int)+
161
+ # (percent to change), and +type_change+ (the direction of the
162
+ # volume adjustment). +type_change+ is optional and defaults to +nil+.
163
+ #
164
+ # Returns the value of +c_vget+ for the same channel.
165
+ #
166
+ # = Example
167
+ #
168
+ # [mixer].c_vget 0, 10, :up ->
169
+ # {:name=>"Front Left", :max=>65536, :min=>0, :volume=>32768, :percent=>50}
170
+ #
171
+ # = Example
172
+ #
173
+ # [mixer].c_vget 0, 10 ->
174
+ # {:name=>"Front Left", :max=>65536, :min=>0, :volume=>32768, :percent=>50}
175
+ def c_vset(channel, perc_change, type_change=nil)
176
+ curr = c_vget(channel) # curr must not be nil to continue
177
+ if curr and (Integer === channel) and (Integer === perc_change) then
178
+ adjustment = AlsaCtl.compute(curr[:min], curr[:max],
179
+ curr[:volume], perc_change, type_change)
180
+ pro_cvolume_set(channel, adjustment)
181
+ else false end
182
+ end # End individual channel volume setter
183
+
184
+ ##
185
+ # Set all the volumes.
186
+ #
187
+ # This is a bypass method. ALSA offers the function,
188
+ # +snd_mixer_selem_set_playback_volume_all+, which allows us to
189
+ # shorthand +c_vset+ for every single channel in an iteration loop.
190
+ #
191
+ # Takes only 2 arguments, +perc_change+, and +type_change+, of which
192
+ # +type_change+ is also optional and defaults to +nil+.
193
+ #
194
+ # Returns the same values as +volume+ / +vget+.
195
+ #
196
+ # This method uses the 0, default channel, usually "Front Left", as
197
+ # the basis from which to set the volume.
198
+ #
199
+ # Aliased to +set_volume+, as well.
200
+ #
201
+ # = Example
202
+ #
203
+ # [mixer].vset 100 -> Sets all channels to volume 100%
204
+ #
205
+ # = Example
206
+ #
207
+ # [mixer].vset 40, :up -> Increases all channels by 40% (up to +:max+)
208
+ def vset(perc_change, type_change=nil)
209
+ curr = c_vget(0) # Get the default/lowest channel
210
+ if curr and (Integer === perc_change) then
211
+ adjustment = AlsaCtl.compute(curr[:min], curr[:max],
212
+ curr[:volume], perc_change, type_change)
213
+ pro_volume_set(adjustment)
214
+ else false end
215
+ end
216
+ alias :set_volume :vset # End setter for all volumes
217
+
218
+ ##
219
+ # Mute the mixer.
220
+ #
221
+ # Stores the current values of each channel as a hash in
222
+ # +@mute_state+. Then uses +vset+ to set all channels to 0%.
223
+ #
224
+ # Returns true on success, or an error message from inside the C code.
225
+ #
226
+ # = Example
227
+ #
228
+ # [mixer].mute -> true
229
+ def mute
230
+ @mute_state = {}
231
+ volume.each do |idx, v|
232
+ @mute_state[idx] = v[:percent]
233
+ end
234
+ vset(0, nil)
235
+ end # End mute
236
+
237
+ ##
238
+ # Unmute the mixer.
239
+ #
240
+ # Checks if +@mute_states+ is empty. If not, uses +c_vset+ to
241
+ # return all channels to their previous state. Only works, if the
242
+ # mixer was not closed, beforehand.
243
+ #
244
+ # ALWAYS returns an empty hash, +{}+, so the result can be
245
+ # ignored. It is just the output of +@mute_state.clear+.
246
+ #
247
+ # = Example
248
+ #
249
+ # [mixer].unmute -> {}
250
+ def unmute
251
+ if !@mute_state.empty? then
252
+ @mute_state.each do |idx, v|
253
+ c_vset(idx, v, nil)
254
+ end
255
+ end
256
+ @mute_state.clear
257
+ end # End unmute
258
+ end # End DefMixer class
259
+ end # End AlsaCtl module
@@ -0,0 +1,10 @@
1
+ # lib/alsactl/version.rb
2
+
3
+ ##
4
+ # Current version of AlsaCtl
5
+ module AlsaCtl
6
+ ##
7
+ # Current version -- I'm only documenting this, so
8
+ # +rdoc+ doesn't complain.
9
+ VERSION = "0.1.0"
10
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alsactl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Edelweiss
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-05-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |
14
+ ALSA wrapper in Ruby, utilizing a purely-abstract C-Ruby API backend
15
+ and a pure Ruby middleware with extensibility.
16
+ email:
17
+ executables: []
18
+ extensions:
19
+ - ext/alsacore/extconf.rb
20
+ extra_rdoc_files:
21
+ - README.md
22
+ - CHANGELOG.md
23
+ - LICENSE.txt
24
+ files:
25
+ - CHANGELOG.md
26
+ - LICENSE.txt
27
+ - README.md
28
+ - ext/alsacore/extconf.rb
29
+ - lib/alsacore/alsacore.so
30
+ - lib/alsactl.rb
31
+ - lib/alsactl/mixers.rb
32
+ - lib/alsactl/version.rb
33
+ homepage: https://github.com/KleineEdelweiss/alsactl_rb
34
+ licenses:
35
+ - LGPL-3.0
36
+ metadata:
37
+ homepage_uri: https://github.com/KleineEdelweiss/alsactl_rb
38
+ source_code_uri: https://github.com/KleineEdelweiss/alsactl_rb
39
+ changelog_uri: https://github.com/KleineEdelweiss/alsactl_rb/blob/master/CHANGELOG.md
40
+ bug_tracker_uri: https://github.com/KleineEdelweiss/alsactl_rb/issues
41
+ post_install_message:
42
+ rdoc_options:
43
+ - "--title"
44
+ - AlsaCtl -- ALSA wrapper in the C-Ruby API
45
+ - "--main"
46
+ - README.md
47
+ - "--exclude"
48
+ - Makefile
49
+ - "--exclude"
50
+ - Rakefile
51
+ - "--exclude"
52
+ - Gemfile
53
+ - "--exclude"
54
+ - alsactl.gemspec
55
+ - "--exclude"
56
+ - rdoc.sh
57
+ - "--line-numbers"
58
+ - "--inline-source"
59
+ - "--quiet"
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 2.7.0
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.2.5
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: ALSA wrapper in the C-Ruby API
77
+ test_files: []