pulseaudio 0.0.6 → 0.0.7

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.7
@@ -1,118 +1,304 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <interface>
3
3
  <!-- interface-requires gtk+ 3.0 -->
4
- <object class="GtkListStore" id="liststore1"/>
4
+ <object class="GtkAdjustment" id="adjustmentSinkVolume">
5
+ <property name="upper">100</property>
6
+ <property name="step_increment">1</property>
7
+ <property name="page_increment">10</property>
8
+ </object>
9
+ <object class="GtkAdjustment" id="adjustmentSourceVolume">
10
+ <property name="upper">100</property>
11
+ <property name="step_increment">1</property>
12
+ <property name="page_increment">10</property>
13
+ </object>
5
14
  <object class="GtkWindow" id="window">
6
15
  <property name="can_focus">False</property>
7
16
  <property name="title" translatable="yes">Choose active sink</property>
8
17
  <property name="window_position">center</property>
9
18
  <property name="default_width">440</property>
10
19
  <property name="default_height">400</property>
20
+ <signal name="window-state-event" handler="on_window_window_state_event" swapped="no"/>
11
21
  <signal name="delete-event" handler="on_window_delete_event" swapped="no"/>
12
22
  <child>
13
- <object class="GtkVPaned" id="vpaned1">
23
+ <object class="GtkNotebook" id="notebook1">
14
24
  <property name="visible">True</property>
15
25
  <property name="can_focus">True</property>
16
- <property name="position">200</property>
17
- <property name="position_set">True</property>
18
26
  <child>
19
- <object class="GtkFrame" id="frame1">
27
+ <object class="GtkVBox" id="vbox1">
20
28
  <property name="visible">True</property>
21
29
  <property name="can_focus">False</property>
22
- <property name="label_xalign">0</property>
23
- <property name="shadow_type">none</property>
30
+ <property name="spacing">4</property>
24
31
  <child>
25
- <object class="GtkAlignment" id="alignment1">
32
+ <object class="GtkFrame" id="frame1">
26
33
  <property name="visible">True</property>
27
34
  <property name="can_focus">False</property>
28
- <property name="left_padding">12</property>
35
+ <property name="label_xalign">0</property>
36
+ <property name="shadow_type">none</property>
29
37
  <child>
30
- <object class="GtkViewport" id="viewport1">
38
+ <object class="GtkAlignment" id="alignment1">
31
39
  <property name="visible">True</property>
32
40
  <property name="can_focus">False</property>
41
+ <property name="left_padding">12</property>
33
42
  <child>
34
- <object class="GtkScrolledWindow" id="scrolledwindow2">
43
+ <object class="GtkTable" id="table1">
35
44
  <property name="visible">True</property>
36
- <property name="can_focus">True</property>
37
- <property name="shadow_type">in</property>
45
+ <property name="can_focus">False</property>
46
+ <property name="n_rows">2</property>
47
+ <property name="n_columns">2</property>
38
48
  <child>
39
- <object class="GtkTreeView" id="tvSinks">
49
+ <object class="GtkHScale" id="hscaleSinkVolume">
40
50
  <property name="visible">True</property>
41
51
  <property name="can_focus">True</property>
42
- <signal name="cursor-changed" handler="on_tvSinks_cursor_changed" swapped="no"/>
43
- <child internal-child="selection">
44
- <object class="GtkTreeSelection" id="treeview-selection1"/>
45
- </child>
52
+ <property name="adjustment">adjustmentSinkVolume</property>
53
+ <property name="round_digits">1</property>
54
+ <property name="draw_value">False</property>
55
+ <signal name="change-value" handler="on_hscaleSinkVolume_change_value" after="yes" swapped="no"/>
46
56
  </object>
57
+ <packing>
58
+ <property name="right_attach">2</property>
59
+ <property name="y_options">GTK_FILL</property>
60
+ </packing>
61
+ </child>
62
+ <child>
63
+ <object class="GtkCheckButton" id="cbSinkMute">
64
+ <property name="label" translatable="yes">Mute</property>
65
+ <property name="use_action_appearance">False</property>
66
+ <property name="visible">True</property>
67
+ <property name="can_focus">True</property>
68
+ <property name="receives_default">False</property>
69
+ <property name="use_action_appearance">False</property>
70
+ <property name="xalign">0</property>
71
+ <property name="draw_indicator">True</property>
72
+ <signal name="toggled" handler="on_cbSinkMute_toggled" after="yes" swapped="no"/>
73
+ </object>
74
+ <packing>
75
+ <property name="right_attach">2</property>
76
+ <property name="top_attach">1</property>
77
+ <property name="bottom_attach">2</property>
78
+ <property name="y_options">GTK_FILL</property>
79
+ </packing>
47
80
  </child>
48
81
  </object>
49
82
  </child>
50
83
  </object>
51
84
  </child>
85
+ <child type="label">
86
+ <object class="GtkLabel" id="label4">
87
+ <property name="visible">True</property>
88
+ <property name="can_focus">False</property>
89
+ <property name="label" translatable="yes">&lt;b&gt;Volume&lt;/b&gt;</property>
90
+ <property name="use_markup">True</property>
91
+ </object>
92
+ </child>
52
93
  </object>
94
+ <packing>
95
+ <property name="expand">False</property>
96
+ <property name="fill">True</property>
97
+ <property name="position">0</property>
98
+ </packing>
53
99
  </child>
54
- <child type="label">
55
- <object class="GtkLabel" id="label1">
100
+ <child>
101
+ <object class="GtkFrame" id="frameChooseDefaultSink">
56
102
  <property name="visible">True</property>
57
103
  <property name="can_focus">False</property>
58
- <property name="label" translatable="yes">&lt;b&gt;Choose active sink&lt;/b&gt;</property>
59
- <property name="use_markup">True</property>
104
+ <property name="label_xalign">0</property>
105
+ <property name="shadow_type">none</property>
106
+ <child>
107
+ <object class="GtkAlignment" id="alignmentChooseDefaultSink">
108
+ <property name="visible">True</property>
109
+ <property name="can_focus">False</property>
110
+ <property name="left_padding">12</property>
111
+ <child>
112
+ <object class="GtkViewport" id="viewport1">
113
+ <property name="visible">True</property>
114
+ <property name="can_focus">False</property>
115
+ <child>
116
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
117
+ <property name="visible">True</property>
118
+ <property name="can_focus">True</property>
119
+ <property name="shadow_type">in</property>
120
+ <child>
121
+ <object class="GtkTreeView" id="tvSinks">
122
+ <property name="visible">True</property>
123
+ <property name="can_focus">True</property>
124
+ <signal name="cursor-changed" handler="on_tvSinks_cursor_changed" swapped="no"/>
125
+ <child internal-child="selection">
126
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
127
+ </child>
128
+ </object>
129
+ </child>
130
+ </object>
131
+ </child>
132
+ </object>
133
+ </child>
134
+ </object>
135
+ </child>
136
+ <child type="label">
137
+ <object class="GtkLabel" id="labelChooseDefaultSink">
138
+ <property name="visible">True</property>
139
+ <property name="can_focus">False</property>
140
+ <property name="label" translatable="yes">&lt;b&gt;Choose default sink&lt;/b&gt;</property>
141
+ <property name="use_markup">True</property>
142
+ </object>
143
+ </child>
60
144
  </object>
145
+ <packing>
146
+ <property name="expand">True</property>
147
+ <property name="fill">True</property>
148
+ <property name="position">1</property>
149
+ </packing>
61
150
  </child>
62
151
  </object>
152
+ </child>
153
+ <child type="tab">
154
+ <object class="GtkLabel" id="label1">
155
+ <property name="visible">True</property>
156
+ <property name="can_focus">False</property>
157
+ <property name="label" translatable="yes">Sinks</property>
158
+ </object>
63
159
  <packing>
64
- <property name="resize">False</property>
65
- <property name="shrink">True</property>
160
+ <property name="tab_fill">False</property>
66
161
  </packing>
67
162
  </child>
68
163
  <child>
69
- <object class="GtkFrame" id="frame2">
164
+ <object class="GtkVBox" id="vbox2">
70
165
  <property name="visible">True</property>
71
166
  <property name="can_focus">False</property>
72
- <property name="label_xalign">0</property>
73
- <property name="shadow_type">none</property>
167
+ <property name="spacing">4</property>
74
168
  <child>
75
- <object class="GtkAlignment" id="alignment2">
169
+ <object class="GtkFrame" id="frameSourceVolume">
76
170
  <property name="visible">True</property>
77
171
  <property name="can_focus">False</property>
78
- <property name="left_padding">12</property>
172
+ <property name="label_xalign">0</property>
173
+ <property name="shadow_type">none</property>
79
174
  <child>
80
- <object class="GtkViewport" id="viewport2">
175
+ <object class="GtkAlignment" id="alignmentSourceVolume">
81
176
  <property name="visible">True</property>
82
177
  <property name="can_focus">False</property>
178
+ <property name="left_padding">12</property>
83
179
  <child>
84
- <object class="GtkScrolledWindow" id="scrolledwindow1">
180
+ <object class="GtkTable" id="tableSourceVolume">
85
181
  <property name="visible">True</property>
86
- <property name="can_focus">True</property>
87
- <property name="shadow_type">in</property>
182
+ <property name="can_focus">False</property>
183
+ <property name="n_rows">2</property>
184
+ <property name="n_columns">2</property>
88
185
  <child>
89
- <object class="GtkTreeView" id="tvSources">
186
+ <object class="GtkHScale" id="hscaleSourceVolume">
90
187
  <property name="visible">True</property>
91
188
  <property name="can_focus">True</property>
92
- <signal name="cursor-changed" handler="on_tvSources_cursor_changed" swapped="no"/>
93
- <child internal-child="selection">
94
- <object class="GtkTreeSelection" id="treeview-selection"/>
95
- </child>
189
+ <property name="adjustment">adjustmentSourceVolume</property>
190
+ <property name="round_digits">1</property>
191
+ <property name="draw_value">False</property>
192
+ <signal name="change-value" handler="on_hscaleSourceVolume_change_value" after="yes" swapped="no"/>
96
193
  </object>
194
+ <packing>
195
+ <property name="right_attach">2</property>
196
+ <property name="y_options">GTK_FILL</property>
197
+ </packing>
198
+ </child>
199
+ <child>
200
+ <object class="GtkCheckButton" id="cbSourceMute">
201
+ <property name="label" translatable="yes">Mute</property>
202
+ <property name="use_action_appearance">False</property>
203
+ <property name="visible">True</property>
204
+ <property name="can_focus">True</property>
205
+ <property name="receives_default">False</property>
206
+ <property name="use_action_appearance">False</property>
207
+ <property name="xalign">0</property>
208
+ <property name="draw_indicator">True</property>
209
+ <signal name="toggled" handler="on_cbSourceMute_toggled" after="yes" swapped="no"/>
210
+ </object>
211
+ <packing>
212
+ <property name="right_attach">2</property>
213
+ <property name="top_attach">1</property>
214
+ <property name="bottom_attach">2</property>
215
+ <property name="y_options">GTK_FILL</property>
216
+ </packing>
97
217
  </child>
98
218
  </object>
99
219
  </child>
100
220
  </object>
101
221
  </child>
222
+ <child type="label">
223
+ <object class="GtkLabel" id="label5">
224
+ <property name="visible">True</property>
225
+ <property name="can_focus">False</property>
226
+ <property name="label" translatable="yes">&lt;b&gt;Volume&lt;/b&gt;</property>
227
+ <property name="use_markup">True</property>
228
+ </object>
229
+ </child>
102
230
  </object>
231
+ <packing>
232
+ <property name="expand">False</property>
233
+ <property name="fill">True</property>
234
+ <property name="position">0</property>
235
+ </packing>
103
236
  </child>
104
- <child type="label">
105
- <object class="GtkLabel" id="label2">
237
+ <child>
238
+ <object class="GtkFrame" id="frame2">
106
239
  <property name="visible">True</property>
107
240
  <property name="can_focus">False</property>
108
- <property name="label" translatable="yes">&lt;b&gt;Choose default source&lt;/b&gt;</property>
109
- <property name="use_markup">True</property>
241
+ <property name="label_xalign">0</property>
242
+ <property name="shadow_type">none</property>
243
+ <child>
244
+ <object class="GtkAlignment" id="alignment2">
245
+ <property name="visible">True</property>
246
+ <property name="can_focus">False</property>
247
+ <property name="left_padding">12</property>
248
+ <child>
249
+ <object class="GtkViewport" id="viewport2">
250
+ <property name="visible">True</property>
251
+ <property name="can_focus">False</property>
252
+ <child>
253
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
254
+ <property name="visible">True</property>
255
+ <property name="can_focus">True</property>
256
+ <property name="shadow_type">in</property>
257
+ <child>
258
+ <object class="GtkTreeView" id="tvSources">
259
+ <property name="visible">True</property>
260
+ <property name="can_focus">True</property>
261
+ <signal name="cursor-changed" handler="on_tvSources_cursor_changed" swapped="no"/>
262
+ <child internal-child="selection">
263
+ <object class="GtkTreeSelection" id="treeview-selection2"/>
264
+ </child>
265
+ </object>
266
+ </child>
267
+ </object>
268
+ </child>
269
+ </object>
270
+ </child>
271
+ </object>
272
+ </child>
273
+ <child type="label">
274
+ <object class="GtkLabel" id="labelChooseDefaultSource">
275
+ <property name="visible">True</property>
276
+ <property name="can_focus">False</property>
277
+ <property name="label" translatable="yes">&lt;b&gt;Choose default source&lt;/b&gt;</property>
278
+ <property name="use_markup">True</property>
279
+ </object>
280
+ </child>
110
281
  </object>
282
+ <packing>
283
+ <property name="expand">True</property>
284
+ <property name="fill">True</property>
285
+ <property name="position">1</property>
286
+ </packing>
111
287
  </child>
112
288
  </object>
113
289
  <packing>
114
- <property name="resize">True</property>
115
- <property name="shrink">True</property>
290
+ <property name="position">1</property>
291
+ </packing>
292
+ </child>
293
+ <child type="tab">
294
+ <object class="GtkLabel" id="label3">
295
+ <property name="visible">True</property>
296
+ <property name="can_focus">False</property>
297
+ <property name="label" translatable="yes">Sources</property>
298
+ </object>
299
+ <packing>
300
+ <property name="position">1</property>
301
+ <property name="tab_fill">False</property>
116
302
  </packing>
117
303
  </child>
118
304
  </object>
@@ -36,12 +36,23 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
36
36
  events = PulseAudio::Events.instance
37
37
  events.connect(:event => :remove, &self.method(:on_remove))
38
38
  events.connect(:event => :new, &self.method(:on_new))
39
+ events.connect(:event => :change, &self.method(:on_change))
39
40
 
40
41
  @sicon = Gtk::StatusIcon.new
41
42
  @sicon.signal_connect("activate", &self.method(:on_sicon_activate))
42
43
  @sicon.signal_connect("popup-menu", &self.method(:on_sicon_popupmenu))
43
44
  @sicon.signal_connect("scroll-event", &self.method(:on_sicon_scroll))
44
45
  self.update_icon
46
+ self.update_sink_info
47
+ self.update_source_info
48
+ end
49
+
50
+ #Called when the window-state is changed to close window instead of minimize.
51
+ def on_window_window_state_event(win, win_state)
52
+ if win_state.new_window_state == 130
53
+ @ui["window"].hide
54
+ @ui["window"].deiconify
55
+ end
45
56
  end
46
57
 
47
58
  #Called when something is removed from PulseAudio. Removes items from the treeviews automatically.
@@ -80,15 +91,27 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
80
91
  end
81
92
  end
82
93
 
94
+ #Called when something is changed. Updates mute-toggle-values, adjustment-values and more automatically.
95
+ def on_change(args)
96
+ event, ele, ele_id = args[:args][:event].to_sym, args[:args][:element].to_s, args[:args][:element_id].to_i
97
+
98
+ if ele == "sink"
99
+ self.update_sink_info
100
+ elsif ele == "source"
101
+ self.update_source_info
102
+ else
103
+ return nil
104
+ end
105
+ end
106
+
83
107
  #Updates the statusicons icon based on the current sinks volume.
84
108
  def update_icon
85
109
  #Get the current active sink which should be manipulated.
86
- sink_def = PulseAudio::Sink.by_default
87
- return nil if !sink_def
110
+ return nil if !@sink
88
111
 
89
112
 
90
113
  #Evaluate which icon is the closest to the current volume.
91
- vol_perc = sink_def.vol_perc
114
+ vol_perc = @sink.vol_perc
92
115
  levels = [0, 33, 66, 100]
93
116
 
94
117
  vol_closest = levels.first
@@ -107,6 +130,52 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
107
130
  @sicon.set_from_file(icon_filepath)
108
131
  end
109
132
 
133
+ def update_sink_info
134
+ if @sink.muted?
135
+ @ui["cbSinkMute"].active = true
136
+ else
137
+ @ui["cbSinkMute"].active = false
138
+ end
139
+
140
+ @ui["adjustmentSinkVolume"].value = @sink.vol_perc.to_f
141
+ end
142
+
143
+ def update_source_info
144
+ if @source.muted?
145
+ @ui["cbSourceMute"].active = true
146
+ else
147
+ @ui["cbSourceMute"].active = false
148
+ end
149
+
150
+ @ui["adjustmentSourceVolume"].value = @source.vol_perc.to_f
151
+ end
152
+
153
+ def on_hscaleSinkVolume_change_value
154
+ GLib.source_remove(@timeout_sink_volume_change) if @timeout_sink_volume_change
155
+
156
+ @timeout_sink_volume_change = GLib.timeout_add(GLib::PRIORITY_DEFAULT_IDLE, 50, proc{
157
+ @timeout_sink_volume_change = nil
158
+ @sink.vol_perc = @ui["adjustmentSinkVolume"].value
159
+ }, nil, nil)
160
+ end
161
+
162
+ def on_hscaleSourceVolume_change_value
163
+ GLib.source_remove(@timeout_source_volume_change) if @timeout_source_volume_change
164
+
165
+ @timeout_source_volume_change = GLib.timeout_add(GLib::PRIORITY_DEFAULT_IDLE, 50, proc{
166
+ @timeout_source_volume_change = nil
167
+ @source.vol_perc = @ui["adjustmentSourceVolume"].value
168
+ }, nil, nil)
169
+ end
170
+
171
+ def on_cbSinkMute_toggled
172
+ @sink.mute = @ui["cbSinkMute"].active
173
+ end
174
+
175
+ def on_cbSourceMute_toggled
176
+ @source.mute = @ui["cbSourceMute"].active
177
+ end
178
+
110
179
  def on_sicon_activate(*args)
111
180
  if !@ui["window"].get_visible
112
181
  @ui["window"].show_all
@@ -118,12 +187,11 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
118
187
  def on_sicon_scroll(sicon, scroll_e, temp)
119
188
  direction = scroll_e.direction.to_s
120
189
  return nil if direction == "smooth"
121
- sink_def = PulseAudio::Sink.by_default
122
190
 
123
191
  if direction == "up"
124
- sink_def.vol_incr
192
+ @sink.vol_incr
125
193
  elsif direction == "down"
126
- sink_def.vol_decr
194
+ @sink.vol_decr
127
195
  end
128
196
 
129
197
  self.update_icon
@@ -146,6 +214,7 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
146
214
 
147
215
  if sink.default?
148
216
  @ui["tvSinks"].selection.select_iter(append_data[:iter])
217
+ @sink = sink
149
218
  end
150
219
  end
151
220
 
@@ -166,6 +235,7 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
166
235
 
167
236
  if source.default?
168
237
  @ui["tvSources"].selection.select_iter(append_data[:iter])
238
+ @source = source
169
239
  end
170
240
  end
171
241
 
@@ -177,7 +247,6 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
177
247
  return nil if @reloading or !@tv_sinks
178
248
  sel = @tv_sinks.sel
179
249
  return nil if !sel
180
- puts sel
181
250
 
182
251
  sink = nil
183
252
  PulseAudio::Sink.list do |sink_i|
@@ -188,8 +257,10 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
188
257
  end
189
258
 
190
259
  raise "Could not find sink." if !sink
260
+ @sink = sink
191
261
  sink.default!
192
262
  self.update_icon
263
+ self.update_sink_info
193
264
  rescue => e
194
265
  Gtk3assist::Msgbox.error(e)
195
266
  end
@@ -210,8 +281,10 @@ class PulseAudio::Gui::Choose_active_sink_gtk3
210
281
  end
211
282
 
212
283
  raise "Could not find source." if !source
284
+ @source = source
213
285
  source.default!
214
286
  self.update_icon
287
+ self.update_source_info
215
288
  rescue => e
216
289
  Gtk3assist::Msgbox.error(e)
217
290
  end
@@ -70,6 +70,18 @@ class PulseAudio::Sink
70
70
  return PulseAudio::Sink.by_id(sink_id.to_i)
71
71
  end
72
72
 
73
+ #This automatically reloads a sink when a 'change'-event appears.
74
+ PulseAudio::Events.instance.connect(:event => :change, :element => "sink") do |args|
75
+ if @@sinks.key?(args[:args][:element_id]) and sink = @@sinks.get(args[:args][:element_id])
76
+ sink.reload
77
+ end
78
+ end
79
+
80
+ #Reloads the information on the sink.
81
+ def reload
82
+ PulseAudio::Sink.list #Reloads information on all sinks.
83
+ end
84
+
73
85
  #Returns a sink by its sink-ID.
74
86
  #===Examples
75
87
  # sink = PulseAudio::Sink.by_id(3)
@@ -134,7 +146,6 @@ class PulseAudio::Sink
134
146
  %x[pactl set-sink-mute #{self.sink_id} 0]
135
147
  end
136
148
 
137
- PulseAudio::Sink.list #reload info.
138
149
  return nil
139
150
  end
140
151
 
@@ -143,7 +154,6 @@ class PulseAudio::Sink
143
154
  # sink.vol_incr if sink.active? #=> nil
144
155
  def vol_incr
145
156
  %x[pactl set-sink-volume #{self.sink_id} -- +5%]
146
- PulseAudio::Sink.list #reload info.
147
157
  return nil
148
158
  end
149
159
 
@@ -152,7 +162,11 @@ class PulseAudio::Sink
152
162
  # sink.vol_decr if sink.active? #=> nil
153
163
  def vol_decr
154
164
  %x[pactl set-sink-volume #{self.sink_id} -- -5%]
155
- PulseAudio::Sink.list #reload info.
165
+ return nil
166
+ end
167
+
168
+ def vol_perc=(newval)
169
+ %x[pactl set-sink-volume #{self.sink_id} #{newval.to_i}%]
156
170
  return nil
157
171
  end
158
172
 
@@ -176,6 +190,7 @@ class PulseAudio::Sink
176
190
  #===Examples
177
191
  # sink.default!
178
192
  def default!
193
+ #Set all inputs to the this sink.
179
194
  PulseAudio::Sink::Input.list do |input|
180
195
  input.sink = self
181
196
  end
@@ -74,11 +74,82 @@ class PulseAudio::Source
74
74
  raise NameError, "No source by that ID: '#{id}' (#{id.class.name})."
75
75
  end
76
76
 
77
+ #This automatically reloads a source when a 'change'-event appears.
78
+ PulseAudio::Events.instance.connect(:event => :change, :element => "source") do |args|
79
+ if @@sources.key?(args[:args][:element_id]) and source = @@sources.get(args[:args][:element_id])
80
+ source.reload
81
+ end
82
+ end
83
+
84
+ #Reloads the information on the source.
85
+ def reload
86
+ PulseAudio::Source.list #Reloads info on all sources.
87
+ end
88
+
77
89
  #Updates the data on the object. This should not be called.
78
90
  def update(args)
79
91
  @args = args
80
92
  end
81
93
 
94
+ #Returns true if the source is muted. Otherwise false.
95
+ #===Examples
96
+ # source.muted? #=> false
97
+ def muted?
98
+ return true if @args[:props]["mute"] == "yes"
99
+ return false
100
+ end
101
+
102
+ #Toggles the mute-functionality of the source. If it is muted: unmutes. If it isnt muted: mutes.
103
+ #===Examples
104
+ # source.mute_toggle #=> nil
105
+ def mute_toggle
106
+ self.mute = !self.muted?
107
+ return nil
108
+ end
109
+
110
+ #Sets the mute to something specific.
111
+ #===Examples
112
+ # source.mute = true #=> nil
113
+ def mute=(val)
114
+ if val
115
+ %x[pactl set-source-mute #{self.source_id} 1]
116
+ else
117
+ %x[pactl set-source-mute #{self.source_id} 0]
118
+ end
119
+
120
+ return nil
121
+ end
122
+
123
+ #Increases the volume of the source by 5%.
124
+ #===Examples
125
+ # source.vol_incr if source.active? #=> nil
126
+ def vol_incr
127
+ %x[pactl set-source-volume #{self.source_id} -- +5%]
128
+ return nil
129
+ end
130
+
131
+ #Decreases the volume of the source by 5%.
132
+ #===Examples
133
+ # source.vol_decr if source.active? #=> nil
134
+ def vol_decr
135
+ %x[pactl set-source-volume #{self.source_id} -- -5%]
136
+ return nil
137
+ end
138
+
139
+ def vol_perc=(newval)
140
+ %x[pactl set-source-volume #{self.source_id} #{newval.to_i}%]
141
+ return nil
142
+ end
143
+
144
+ #Returns the current percent of the volume.
145
+ def vol_perc
146
+ if match = @args[:props]["volume"].to_s.match(/(\d+):\s*(\d+)%/)
147
+ return match[2].to_i
148
+ end
149
+
150
+ raise "Could not figure out the volume."
151
+ end
152
+
82
153
  #Returns the ID of the source.
83
154
  #===Examples
84
155
  # source.source_id #=> 2
data/pulseaudio.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "pulseaudio"
8
- s.version = "0.0.6"
8
+ s.version = "0.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kasper Johansen"]
12
- s.date = "2012-09-30"
12
+ s.date = "2012-10-03"
13
13
  s.description = "Ruby-library for controlling PulseAudio via 'pactl'."
14
14
  s.email = "k@spernj.org"
15
15
  s.executables = ["pulseaudio_volume.rb"]
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: pulseaudio
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.6
5
+ version: 0.0.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Kasper Johansen
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-09-30 00:00:00 Z
13
+ date: 2012-10-03 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: wref
@@ -164,7 +164,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
164
  requirements:
165
165
  - - ">="
166
166
  - !ruby/object:Gem::Version
167
- hash: -1301824168619278043
167
+ hash: 1285424623138543590
168
168
  segments:
169
169
  - 0
170
170
  version: "0"