volay 1.2.0 → 2.0.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 +4 -4
- data/.rubocop.yml +8 -1
- data/.travis.yml +2 -2
- data/MANIFEST +3 -3
- data/README.md +1 -1
- data/glade/volay.glade +1 -1
- data/lib/volay.rb +1 -1
- data/lib/volay/config.rb +2 -3
- data/lib/volay/mixer/pulse.rb +197 -0
- data/lib/volay/version.rb +1 -3
- data/lib/volay/widget/events.rb +3 -1
- data/lib/volay/widget/system_tray.rb +28 -0
- data/spec/volay/app_spec.rb +3 -3
- data/spec/volay/config_spec.rb +9 -7
- data/spec/volay/mixer/pulse_spec.rb +78 -0
- metadata +4 -4
- data/lib/volay/mixer/alsa.rb +0 -50
- data/spec/volay/mixer/alsa_spec.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 688ccbdc75ceb9062fb138563fa72504509a2afaffbc2b1aae9e8f9f24a3dd32
|
4
|
+
data.tar.gz: 2e2c26689b143f3011d04a3d522eb9bbae829254d36618b5e853b9ecc8d64006
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a13b3fb7690cf4bf04bbc210deaf6317d18fbb13743877dc330b345a084aeaae1242865bf72e2cbfe8319525fbbba09eeae4be0d66e1c05609f4f270a4a81dd7
|
7
|
+
data.tar.gz: 6cd5dcc83ccd294308644e5b45c9871a02447ec28c13fa14bc60c2fe44403996a58490128155ef4b523fb58998f89e117f87c7874b1bc3b98a71245f05164e7f
|
data/.rubocop.yml
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3
|
3
|
+
|
4
|
+
Naming:
|
2
5
|
Enabled: false
|
3
6
|
Metrics/AbcSize:
|
4
7
|
Enabled: false
|
@@ -18,3 +21,7 @@ Metrics/BlockLength:
|
|
18
21
|
Style/FrozenStringLiteralComment:
|
19
22
|
Exclude:
|
20
23
|
- lib/volay/cli.rb
|
24
|
+
- lib/volay/version.rb
|
25
|
+
|
26
|
+
Performance/RegexpMatch:
|
27
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/MANIFEST
CHANGED
@@ -17,8 +17,8 @@ lib/volay/app.rb
|
|
17
17
|
lib/volay/cli.rb
|
18
18
|
lib/volay/config.rb
|
19
19
|
lib/volay/exceptions.rb
|
20
|
-
lib/volay/mixer/alsa.rb
|
21
20
|
lib/volay/mixer/default.rb
|
21
|
+
lib/volay/mixer/pulse.rb
|
22
22
|
lib/volay/utils.rb
|
23
23
|
lib/volay/version.rb
|
24
24
|
lib/volay/volay.rb
|
@@ -28,11 +28,11 @@ lib/volay/widget/volume_control.rb
|
|
28
28
|
spec/spec_helper.rb
|
29
29
|
spec/volay/app_spec.rb
|
30
30
|
spec/volay/config_spec.rb
|
31
|
-
spec/volay/mixer/alsa_spec.rb
|
32
31
|
spec/volay/mixer/default_spec.rb
|
32
|
+
spec/volay/mixer/pulse_spec.rb
|
33
33
|
spec/volay/utils_spec.rb
|
34
34
|
spec/volay/widget/volume_control_spec.rb
|
35
35
|
task/manifest.rake
|
36
36
|
task/rubocop.rake
|
37
37
|
task/spec.rake
|
38
|
-
volay.gemspec
|
38
|
+
volay.gemspec
|
data/README.md
CHANGED
data/glade/volay.glade
CHANGED
data/lib/volay.rb
CHANGED
data/lib/volay/config.rb
CHANGED
@@ -59,9 +59,8 @@ module Volay
|
|
59
59
|
# Initialize mixer for controlling volume
|
60
60
|
#
|
61
61
|
def self.mixer
|
62
|
-
raise MixerNotFound unless which('
|
63
|
-
|
64
|
-
@mixer ||= Volay::Mixer::Alsa.new
|
62
|
+
raise MixerNotFound unless which('pacmd')
|
63
|
+
@mixer ||= Volay::Mixer::Pulse.new
|
65
64
|
end
|
66
65
|
|
67
66
|
##
|
@@ -0,0 +1,197 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Volay module
|
4
|
+
module Volay
|
5
|
+
# Mixer module
|
6
|
+
module Mixer
|
7
|
+
# Pulse class for playing with pacmd command
|
8
|
+
class Pulse < Default
|
9
|
+
DEFAULT_VALUE = 2
|
10
|
+
MAX_VALUE = 65_536
|
11
|
+
|
12
|
+
attr_reader :default_sink_id
|
13
|
+
attr_accessor :cards
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@cards = {}
|
17
|
+
refresh
|
18
|
+
end
|
19
|
+
|
20
|
+
def up(value = DEFAULT_VALUE)
|
21
|
+
set_volume(
|
22
|
+
volume_percent(@cards[@default_sink_id]['volume']) + value
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def down(value = DEFAULT_VALUE)
|
27
|
+
set_volume(
|
28
|
+
volume_percent(@cards[@default_sink_id]['volume']) - value
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def value=(value)
|
33
|
+
set_volume(value.to_i)
|
34
|
+
end
|
35
|
+
|
36
|
+
def toggle
|
37
|
+
value = if current_sink['muted'] == 'yes'
|
38
|
+
'no'
|
39
|
+
else
|
40
|
+
'yes'
|
41
|
+
end
|
42
|
+
current_sink['muted'] = value
|
43
|
+
command("set-sink-mute #{@cards[@default_sink_id]['sink']} #{value}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def current
|
47
|
+
{
|
48
|
+
value: current_sink['volume'],
|
49
|
+
max_value: MAX_VALUE,
|
50
|
+
percent: volume_percent(current_sink['volume']),
|
51
|
+
muted: current_sink['muted'] == 'yes'
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Change card
|
57
|
+
#
|
58
|
+
# @param [Integer] newdefault New default index
|
59
|
+
#
|
60
|
+
def change_card(newdefault)
|
61
|
+
return unless @cards.key?(newdefault)
|
62
|
+
|
63
|
+
# Change default sink
|
64
|
+
command("set-default-sink #{@cards[newdefault]['sink']}")
|
65
|
+
|
66
|
+
# Now to move all current playing stuff to the new sink....
|
67
|
+
dump = command('list-sink-inputs').lines
|
68
|
+
dump.each do |line|
|
69
|
+
args = line.split
|
70
|
+
# We need to find the item index for each playing stream
|
71
|
+
if args[0] == 'index:'
|
72
|
+
# And now to shift them all to the new sink.
|
73
|
+
command("move-sink-input #{args[1]} #{@cards[newdefault]['sink']}")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
refresh
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
##
|
83
|
+
# Get volume percent
|
84
|
+
#
|
85
|
+
# @return Integer
|
86
|
+
#
|
87
|
+
def volume_percent(value)
|
88
|
+
value * 100 / MAX_VALUE
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Refresh cards data
|
93
|
+
#
|
94
|
+
def refresh
|
95
|
+
dump = command('dump').lines
|
96
|
+
dump.each do |line|
|
97
|
+
args = line.split
|
98
|
+
|
99
|
+
# We are using the id to actually enumerate all cards.
|
100
|
+
if args[1] == 'module-alsa-card'
|
101
|
+
number = args[2].sub('device_id="', '').sub('"', '').to_i
|
102
|
+
@cards[number] = {}
|
103
|
+
@cards[number]['name'] = args[3].sub('name="', '').sub('"', '')
|
104
|
+
# we already have something in the array
|
105
|
+
elsif @cards.keys.length.positive?
|
106
|
+
set_data(args)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
set_long_names
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Set cards data such as default sink
|
115
|
+
# volume and if card is muted
|
116
|
+
#
|
117
|
+
# @param [Hash] args Parameters
|
118
|
+
#
|
119
|
+
def set_data(args)
|
120
|
+
@cards.each do |id, card|
|
121
|
+
next if args[1].nil? || !args[1].include?(card['name'])
|
122
|
+
case args[0]
|
123
|
+
when 'set-default-sink'
|
124
|
+
@default_sink_id = id
|
125
|
+
when 'set-sink-volume'
|
126
|
+
@cards[id]['volume'] = args[2].hex
|
127
|
+
@cards[id]['sink'] = args[1]
|
128
|
+
when 'set-sink-mute'
|
129
|
+
@cards[id]['muted'] = args[2]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# Get long name from list-cards command
|
136
|
+
#
|
137
|
+
def set_long_names
|
138
|
+
dump = command(
|
139
|
+
"list-cards | grep -e device.string -e 'name:' -e 'card_name'"
|
140
|
+
)
|
141
|
+
.split('name: ')
|
142
|
+
.reject { |x| x.strip.empty? }
|
143
|
+
|
144
|
+
dump.each do |card|
|
145
|
+
id = nil
|
146
|
+
name = nil
|
147
|
+
card.lines.each do |line|
|
148
|
+
args = line.strip.split(' = ')
|
149
|
+
if args[0] == 'device.string'
|
150
|
+
id = args[1].delete('"').to_i
|
151
|
+
elsif args[0] == 'alsa.card_name'
|
152
|
+
name = args[1].delete('"')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
@cards[id]['long_name'] = name
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Get current sink
|
162
|
+
#
|
163
|
+
# @return [Hash]
|
164
|
+
#
|
165
|
+
def current_sink
|
166
|
+
@cards[@default_sink_id]
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Set up volume
|
171
|
+
#
|
172
|
+
# @param [Integer] volume Volume to set up, must be a percentage
|
173
|
+
#
|
174
|
+
def set_volume(volume)
|
175
|
+
volume = [[0, (volume * MAX_VALUE / 100)].max, MAX_VALUE].min
|
176
|
+
@cards[@default_sink_id]['volume'] = volume
|
177
|
+
sink = @cards[@default_sink_id]['sink']
|
178
|
+
command("set-sink-volume #{sink} #{format('0x%<v>x', v: volume)}")
|
179
|
+
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# Run command
|
183
|
+
#
|
184
|
+
# @param [String] cmd Command to run
|
185
|
+
#
|
186
|
+
def command(cmd)
|
187
|
+
command = "pacmd #{cmd}"
|
188
|
+
result = Mixlib::ShellOut.new(command)
|
189
|
+
Volay::Config.logger.debug(command)
|
190
|
+
result.run_command
|
191
|
+
Volay::Config.logger.error(result.stderr) unless result.stderr.empty?
|
192
|
+
Volay::Config.logger.debug(result.stdout) unless result.stdout.empty?
|
193
|
+
result.stdout
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
data/lib/volay/version.rb
CHANGED
data/lib/volay/widget/events.rb
CHANGED
@@ -10,6 +10,34 @@ module Volay
|
|
10
10
|
RIGHT_CLICK = 3
|
11
11
|
M_KEYCODE = 47
|
12
12
|
|
13
|
+
##
|
14
|
+
# When popup window menu is draw
|
15
|
+
#
|
16
|
+
def init
|
17
|
+
return unless @app&.mixer&.cards
|
18
|
+
|
19
|
+
cards_menu = Gtk::MenuItem.new(label: 'Cards')
|
20
|
+
menu = Gtk::Menu.new
|
21
|
+
last_item = nil
|
22
|
+
@app.mixer.cards.each do |id, card|
|
23
|
+
radio_menu_item = Gtk::RadioMenuItem.new(nil, card['long_name'])
|
24
|
+
radio_menu_item.join_group(last_item) if last_item
|
25
|
+
radio_menu_item.name = "card_menu_#{id}"
|
26
|
+
radio_menu_item.active = @app.mixer.default_sink_id == id
|
27
|
+
last_item = radio_menu_item
|
28
|
+
menu.append(radio_menu_item)
|
29
|
+
|
30
|
+
radio_menu_item.signal_connect('activate') do |widget|
|
31
|
+
next unless widget.active?
|
32
|
+
@app.mixer.change_card(id)
|
33
|
+
@app.utils.update_status_icon
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
cards_menu.submenu = menu
|
38
|
+
@app.get_object('popup_menu').prepend(cards_menu)
|
39
|
+
end
|
40
|
+
|
13
41
|
##
|
14
42
|
# When left click on the status icon, popup the window menu
|
15
43
|
#
|
data/spec/volay/app_spec.rb
CHANGED
@@ -9,14 +9,14 @@ require 'volay/widget/events'
|
|
9
9
|
require 'volay/widget/system_tray'
|
10
10
|
require 'volay/widget/volume_control'
|
11
11
|
require 'volay/mixer/default'
|
12
|
-
require 'volay/mixer/
|
12
|
+
require 'volay/mixer/pulse'
|
13
13
|
require 'volay/exceptions'
|
14
14
|
|
15
15
|
describe 'Volay::App' do
|
16
16
|
include FakeFS::SpecHelpers
|
17
17
|
|
18
18
|
context '#events' do
|
19
|
-
it 'should
|
19
|
+
it 'should initiliaze events' do
|
20
20
|
allow_any_instance_of(Volay::App).to receive(:initialize_mixer)
|
21
21
|
allow_any_instance_of(Volay::App).to receive(:initialize_ui)
|
22
22
|
allow_any_instance_of(Volay::Utils).to receive(:update_status_icon)
|
@@ -30,7 +30,7 @@ describe 'Volay::App' do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
context '#ui' do
|
33
|
-
it 'should
|
33
|
+
it 'should initialize events' do
|
34
34
|
allow_any_instance_of(Volay::App).to receive(:initialize_mixer)
|
35
35
|
allow_any_instance_of(Volay::App).to receive(:initialize_events)
|
36
36
|
|
data/spec/volay/config_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
require 'logger'
|
5
5
|
require 'volay/config'
|
6
6
|
require 'volay/mixer/default'
|
7
|
-
require 'volay/mixer/
|
7
|
+
require 'volay/mixer/pulse'
|
8
8
|
require 'volay/exceptions'
|
9
9
|
|
10
10
|
describe 'Volay::Config' do
|
@@ -39,9 +39,9 @@ describe 'Volay::Config' do
|
|
39
39
|
expect(Volay::Config.which('ruby')).to eq('/usr/bin/ruby')
|
40
40
|
end
|
41
41
|
|
42
|
-
it "shouldn't find
|
42
|
+
it "shouldn't find pacmd executable" do
|
43
43
|
config
|
44
|
-
expect(Volay::Config.which('
|
44
|
+
expect(Volay::Config.which('pacmd')).to be_nil
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -53,14 +53,16 @@ describe 'Volay::Config' do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'should not return pulseaudio' do
|
56
|
-
app_mixer('pulseaudio-ctl')
|
57
56
|
expect { Volay::Config.mixer }
|
58
57
|
.to raise_error(Volay::MixerNotFound)
|
59
58
|
end
|
60
59
|
|
61
|
-
it 'should return
|
62
|
-
|
63
|
-
|
60
|
+
it 'should return a mixer' do
|
61
|
+
Volay::Config.logger.level = :info
|
62
|
+
allow_any_instance_of(Mixlib::ShellOut).to receive(:new).twice
|
63
|
+
allow_any_instance_of(Mixlib::ShellOut).to receive(:run_command)
|
64
|
+
app_mixer('pacmd')
|
65
|
+
expect(Volay::Config.mixer).to be_a(Volay::Mixer::Pulse)
|
64
66
|
end
|
65
67
|
end
|
66
68
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'mixlib/shellout'
|
5
|
+
require 'volay/mixer/default'
|
6
|
+
|
7
|
+
describe 'Volay::Mixer::Pulse' do
|
8
|
+
let(:mixer) do
|
9
|
+
Volay::Mixer::Pulse.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def stub_shellout(cmd, stdout = '', stderr = '')
|
13
|
+
shellout = double(
|
14
|
+
run_command: nil,
|
15
|
+
error!: nil,
|
16
|
+
stdout: stdout,
|
17
|
+
stderr: stderr
|
18
|
+
)
|
19
|
+
|
20
|
+
expect(Mixlib::ShellOut).to receive(:new)
|
21
|
+
.with("pacmd #{cmd}")
|
22
|
+
.and_return(shellout)
|
23
|
+
end
|
24
|
+
|
25
|
+
before(:each) do
|
26
|
+
stub_shellout(
|
27
|
+
'dump',
|
28
|
+
File.read(
|
29
|
+
File.expand_path('../stubs/pulse_dump.stub', __FILE__)
|
30
|
+
)
|
31
|
+
)
|
32
|
+
stub_shellout(
|
33
|
+
"list-cards | grep -e device.string -e 'name:' -e 'card_name'",
|
34
|
+
File.read(
|
35
|
+
File.expand_path('../stubs/pulse_list-cards.stub', __FILE__)
|
36
|
+
)
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should raise error when calling up' do
|
41
|
+
stub_shellout(
|
42
|
+
'set-sink-volume alsa_output.pci-0000_01_00.1.hdmi-stereo 0x10000',
|
43
|
+
'Yes'
|
44
|
+
)
|
45
|
+
expect(mixer.up).to eq('Yes')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should raise error when calling down' do
|
49
|
+
stub_shellout(
|
50
|
+
'set-sink-volume alsa_output.pci-0000_01_00.1.hdmi-stereo 0xfae1',
|
51
|
+
'Yes'
|
52
|
+
)
|
53
|
+
expect(mixer.down).to eq('Yes')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should raise error when calling value=' do
|
57
|
+
stub_shellout(
|
58
|
+
'set-sink-volume alsa_output.pci-0000_01_00.1.hdmi-stereo 0x8000',
|
59
|
+
'Yes'
|
60
|
+
)
|
61
|
+
expect(mixer.value = '50').to eq('50')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should raise error when calling toggle' do
|
65
|
+
stub_shellout(
|
66
|
+
'set-sink-mute alsa_output.pci-0000_01_00.1.hdmi-stereo yes',
|
67
|
+
'Yes'
|
68
|
+
)
|
69
|
+
expect(mixer.toggle).to eq('Yes')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should raise error when calling current' do
|
73
|
+
expect(mixer.current).to eq(value: 65_536,
|
74
|
+
max_value: 65_536,
|
75
|
+
percent: 100,
|
76
|
+
muted: false)
|
77
|
+
end
|
78
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: volay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pierre Rambaud
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glib2
|
@@ -190,8 +190,8 @@ files:
|
|
190
190
|
- lib/volay/cli.rb
|
191
191
|
- lib/volay/config.rb
|
192
192
|
- lib/volay/exceptions.rb
|
193
|
-
- lib/volay/mixer/alsa.rb
|
194
193
|
- lib/volay/mixer/default.rb
|
194
|
+
- lib/volay/mixer/pulse.rb
|
195
195
|
- lib/volay/utils.rb
|
196
196
|
- lib/volay/version.rb
|
197
197
|
- lib/volay/volay.rb
|
@@ -201,8 +201,8 @@ files:
|
|
201
201
|
- spec/spec_helper.rb
|
202
202
|
- spec/volay/app_spec.rb
|
203
203
|
- spec/volay/config_spec.rb
|
204
|
-
- spec/volay/mixer/alsa_spec.rb
|
205
204
|
- spec/volay/mixer/default_spec.rb
|
205
|
+
- spec/volay/mixer/pulse_spec.rb
|
206
206
|
- spec/volay/utils_spec.rb
|
207
207
|
- spec/volay/widget/volume_control_spec.rb
|
208
208
|
- task/manifest.rake
|
data/lib/volay/mixer/alsa.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Volay module
|
4
|
-
module Volay
|
5
|
-
# Mixer module
|
6
|
-
module Mixer
|
7
|
-
# Alsa class for playing with amixer
|
8
|
-
class Alsa < Default
|
9
|
-
DEFAULT_VALUE = 2
|
10
|
-
|
11
|
-
def up(value = DEFAULT_VALUE)
|
12
|
-
command("-q set Master #{value}%+")
|
13
|
-
end
|
14
|
-
|
15
|
-
def down(value = DEFAULT_VALUE)
|
16
|
-
command("-q set Master #{value}%-")
|
17
|
-
end
|
18
|
-
|
19
|
-
def value=(value)
|
20
|
-
command("-q set Master #{value}%")
|
21
|
-
end
|
22
|
-
|
23
|
-
def toggle
|
24
|
-
command('-q set Master toggle')
|
25
|
-
end
|
26
|
-
|
27
|
-
def current
|
28
|
-
result = command('get Master')
|
29
|
-
max_value = result.match(/ 0 - (\d+)/)[1].to_i
|
30
|
-
current_percent = result.match(/\[([0-9]+)%\]\s+\[o(?:n|ff)\]/)[1].to_i
|
31
|
-
current_value = ((current_percent * max_value) / 100).to_i
|
32
|
-
current_state = result.match(/\[([a-z]+)\]/)[1].to_s
|
33
|
-
|
34
|
-
{ value: current_value,
|
35
|
-
max_value: max_value,
|
36
|
-
percent: current_percent,
|
37
|
-
muted: current_state != 'on' }
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def command(cmd)
|
43
|
-
result = Mixlib::ShellOut.new("amixer #{cmd}")
|
44
|
-
result.run_command
|
45
|
-
Volay::Config.logger.error(result.stderr) unless result.stderr.empty?
|
46
|
-
result.stdout
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'mixlib/shellout'
|
5
|
-
require 'volay/mixer/default'
|
6
|
-
|
7
|
-
describe 'Volay::Mixer::Alsa' do
|
8
|
-
let(:mixer) do
|
9
|
-
Volay::Mixer::Alsa.new
|
10
|
-
end
|
11
|
-
|
12
|
-
def stub_shellout(cmd, stdout = '', stderr = '')
|
13
|
-
allow_any_instance_of(Mixlib::ShellOut).to receive(:run_command)
|
14
|
-
allow_any_instance_of(Mixlib::ShellOut).to receive(:new)
|
15
|
-
.with("amixer #{cmd}")
|
16
|
-
allow_any_instance_of(Mixlib::ShellOut).to receive(:stdout)
|
17
|
-
.and_return(stdout)
|
18
|
-
allow_any_instance_of(Mixlib::ShellOut).to receive(:stderr)
|
19
|
-
.and_return(stderr)
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should raise error when calling up' do
|
23
|
-
stub_shellout('-q set Master 2%+', 'Yes')
|
24
|
-
expect(mixer.up).to eq('Yes')
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'should raise error when calling down' do
|
28
|
-
stub_shellout('-q set Master 2%-', 'Yes')
|
29
|
-
expect(mixer.down).to eq('Yes')
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'should raise error when calling value=' do
|
33
|
-
stub_shellout('-q set Master 50%', 'Yes')
|
34
|
-
expect(mixer.value = '50').to eq('50')
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should raise error when calling toggle' do
|
38
|
-
stub_shellout('-q set Master toggle', 'Yes')
|
39
|
-
expect(mixer.toggle).to eq('Yes')
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should raise error when calling current' do
|
43
|
-
stdout = <<-OUTPUT
|
44
|
-
Simple mixer control 'Master',0
|
45
|
-
Capabilities: pvolume pswitch pswitch-joined
|
46
|
-
Playback channels: Front Left - Front Right
|
47
|
-
Limits: Playback 0 - 65536
|
48
|
-
Mono:
|
49
|
-
Front Left: Playback 13108 [20%] [off]
|
50
|
-
Front Right: Playback 13108 [20%] [off]
|
51
|
-
OUTPUT
|
52
|
-
stub_shellout('get Master', stdout)
|
53
|
-
expect(mixer.current).to eq(value: 13_107,
|
54
|
-
max_value: 65_536,
|
55
|
-
percent: 20,
|
56
|
-
muted: true)
|
57
|
-
end
|
58
|
-
end
|