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
|
#if 0
pkg = libpulse
src = $(MAKEFILE_LIST)
app = $(basename $(src))
CFLAGS = $(shell pkg-config --cflags $(pkg)) -x c
LDFLAGS = $(shell pkg-config --libs $(pkg))
$(app): $(src)
define source
#endif
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <pulse/mainloop.h>
#include <pulse/ext-stream-restore.h>
#include <err.h>
void adjust_stream(pa_mainloop *loop, pa_context *ctx,
char *name, unsigned value, bool mute)
{
pa_volume_t vol;
pa_ext_stream_restore_info info;
pa_operation *o;
vol = (value * PA_VOLUME_NORM) / 100;
info = (pa_ext_stream_restore_info) {
.name = name,
.channel_map = {
.channels = 1,
.map = { PA_CHANNEL_POSITION_MONO },
},
.volume = {
.channels = 1,
.values = { mute ? PA_VOLUME_MUTED : vol },
},
.device = "",
.mute = mute,
};
//assert(pa_cvolume_compatible_with_channel_map(&info.volume, &info.channel_map));
o = pa_ext_stream_restore_write(ctx, PA_UPDATE_REPLACE, &info, 1,
true, NULL, NULL);
if (!o)
errx(1, "pa_ext_stream_restore_write failed");
pa_mainloop_iterate(loop, 1, NULL);
}
void try_connect(pa_mainloop *loop, pa_context *ctx) {
if (pa_context_connect(ctx, NULL, PA_CONTEXT_NOFAIL, NULL) < 0)
errx(1, "connection to PulseAudio failed");
for (;;) {
pa_mainloop_iterate(loop, 1, NULL);
switch (pa_context_get_state(ctx)) {
case PA_CONTEXT_READY:
return;
case PA_CONTEXT_FAILED:
errx(1, "handshake with PulseAudio failed");
return;
}
}
}
void pa_main(unsigned percent, bool muted) {
pa_mainloop *loop;
pa_context *ctx;
loop = pa_mainloop_new();
ctx = pa_context_new(pa_mainloop_get_api(loop), "knob");
try_connect(loop, ctx);
adjust_stream(loop, ctx, "sink-input-by-media-role:event", percent, muted);
pa_context_unref(ctx);
pa_mainloop_free(loop);
}
int main(int argc, char *argv[]) {
unsigned long percent = 0;
bool muted = false;
if (argc != 2)
errx(1, "missing volume level argument");
percent = strtoul(argv[1], NULL, 10);
pa_main(percent, muted);
return 0;
}
#if 0
endef
#endif
|