-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
InputDeviceMonitor.vala
128 lines (106 loc) · 3.78 KB
/
InputDeviceMonitor.vala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
/*-
* Copyright (c) 2016-2017 elementary LLC. (https://elementary.io)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Authored by: Corentin Noël <corentin@elementary.io>
*/
public class Sound.InputDeviceMonitor : GLib.Object {
public signal void update_fraction (float fraction);
private PulseAudio.Stream steam;
private unowned Device device;
private bool allow_record = false;
public InputDeviceMonitor () {
}
~InputDeviceMonitor () {
if (steam != null) {
steam.set_read_callback (null);
steam.set_suspended_callback (null);
steam.disconnect ();
}
}
public void stop_record () {
if (allow_record == false) {
return;
}
allow_record = false;
if (steam != null) {
steam.disconnect ();
steam = null;
}
}
public void start_record () {
allow_record = true;
if (device == null) {
return;
}
if (steam != null) {
steam.disconnect ();
steam = null;
}
unowned PulseAudio.Context c = PulseAudioManager.get_default ().context;
var ss = PulseAudio.SampleSpec () {
format = PulseAudio.SampleFormat.FLOAT32NE,
rate = 25,
channels = 1
};
var props = new PulseAudio.Proplist ();
props.sets (PulseAudio.Proplist.PROP_APPLICATION_NAME, "Sound Settings");
props.sets (PulseAudio.Proplist.PROP_APPLICATION_ID, "io.elementary.settings.sound");
props.sets (PulseAudio.Proplist.PROP_APPLICATION_ICON_NAME, "preferences-desktop-sound");
props.sets (PulseAudio.Proplist.PROP_APPLICATION_VERSION, "0.1");
steam = new PulseAudio.Stream (c, _("Peak detect"), ss, null, props);
steam.set_read_callback (steam_read_callback);
steam.set_suspended_callback (steam_suspended_callback);
var a = PulseAudio.Stream.BufferAttr () {
maxlength = uint32.MAX,
fragsize = (uint32)sizeof (float)
};
steam.connect_record ("%u".printf (device.source_index), a, PulseAudio.Stream.Flags.DONT_MOVE | PulseAudio.Stream.Flags.PEAK_DETECT | PulseAudio.Stream.Flags.ADJUST_LATENCY);
}
public void set_device (Device device) {
this.device = device;
if (allow_record) {
start_record ();
} else {
stop_record ();
}
}
private void steam_read_callback (PulseAudio.Stream s, size_t nbytes) {
void *data;
if (s.peek (out data, out nbytes) < 0) {
warning ("Failed to read data from stream");
return;
}
if (data == null) {
s.drop ();
return;
}
float v = ((float[]) data)[nbytes / sizeof (float) - 1];
s.drop ();
if (v < 0) {
v = 0;
}
if (v > 1) {
v = 1;
}
update_fraction (v);
}
private void steam_suspended_callback (PulseAudio.Stream s) {
update_fraction (0);
}
}