Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
panelcontrol
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
minus
panelcontrol
Commits
5aa82d41
Commit
5aa82d41
authored
Sep 15, 2019
by
minus
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add PA controlling functions and wire them up
parent
5a61dfa8
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
105 additions
and
44 deletions
+105
-44
pa.c
pa.c
+35
-6
pa.h
pa.h
+6
-0
pa_siso_watch_list.c
pa_siso_watch_list.c
+30
-27
pa_siso_watch_list.h
pa_siso_watch_list.h
+10
-5
panelcontrol.c
panelcontrol.c
+22
-4
panelcontrol.h
panelcontrol.h
+2
-2
No files found.
pa.c
View file @
5aa82d41
...
...
@@ -4,7 +4,6 @@
#include "panelcontrol.h"
#include "pa.h"
#include "pa_siso_watch_list.h"
static
pa_glib_mainloop
*
xpa_main_loop
;
...
...
@@ -20,8 +19,7 @@ static void xpa_on_sink_input_info(pa_context *ctx,
struct
siso_watch_list
*
wl
=
userdata
;
struct
siso_watch
*
w
=
siso_get
(
wl
,
info
->
name
);
if
(
w
)
{
siso_watch_add_index
(
w
,
info
->
index
);
siso_watch_update
(
w
,
info
->
sink
,
info
->
volume
.
values
[
0
],
info
->
mute
!=
0
);
siso_watch_update
(
w
,
info
->
index
,
info
->
sink
,
info
->
volume
,
info
->
mute
!=
0
);
}
}
...
...
@@ -34,8 +32,7 @@ static void xpa_on_sink_info(pa_context *ctx,
struct
siso_watch_list
*
wl
=
userdata
;
struct
siso_watch
*
w
=
siso_get
(
wl
,
info
->
name
);
if
(
w
)
{
siso_watch_add_index
(
w
,
info
->
index
);
siso_watch_update
(
w
,
-
1
,
info
->
volume
.
values
[
0
],
info
->
mute
!=
0
);
siso_watch_update
(
w
,
info
->
index
,
-
1
,
info
->
volume
,
info
->
mute
!=
0
);
}
}
...
...
@@ -51,6 +48,7 @@ static void xpa_on_subscribe(pa_context *ctx,
struct
siso_watch_list
*
wl
=
NULL
;
pa_sink_info_cb_t
cb
=
NULL
;
if
((
type
&
PA_SUBSCRIPTION_EVENT_FACILITY_MASK
)
==
PA_SUBSCRIPTION_EVENT_SINK_INPUT
)
{
type_str
=
"sink input"
;
if
(
etype
==
PA_SUBSCRIPTION_EVENT_REMOVE
)
{
siso_remove_index
(
&
sink_inputs
,
idx
);
}
else
{
...
...
@@ -59,6 +57,7 @@ static void xpa_on_subscribe(pa_context *ctx,
pa_operation_unref
(
op
);
}
}
else
if
((
type
&
PA_SUBSCRIPTION_EVENT_FACILITY_MASK
)
==
PA_SUBSCRIPTION_EVENT_SINK
)
{
type_str
=
"sink"
;
if
(
etype
==
PA_SUBSCRIPTION_EVENT_REMOVE
)
{
siso_remove_index
(
&
sinks
,
idx
);
}
else
{
...
...
@@ -85,11 +84,41 @@ static void xpa_on_connect(pa_context *ctx, void *userdata) {
}
}
static
pa_context
*
ctx
;
void
xpa_sink_input_set_volume
(
struct
siso_watch
*
w
,
float
delta
)
{
for
(
size_t
i
=
0
;
i
<
w
->
sisos
.
len
;
i
++
)
{
struct
siso
*
s
=
&
w
->
sisos
.
items
[
i
];
for
(
int
ch
=
0
;
ch
<
s
->
volume
.
channels
;
ch
++
)
{
float
p
=
(
float
)(
s
->
volume
.
values
[
ch
]
-
PA_VOLUME_MUTED
)
/
(
PA_VOLUME_NORM
-
PA_VOLUME_MUTED
);
p
+=
delta
;
if
(
p
>
1
.
0
f
)
p
=
1
.
0
f
;
else
if
(
p
<
0
.
0
f
)
p
=
0
.
0
f
;
s
->
volume
.
values
[
ch
]
=
PA_VOLUME_MUTED
+
p
*
(
PA_VOLUME_NORM
-
PA_VOLUME_MUTED
);
}
pa_operation_unref
(
pa_context_set_sink_input_volume
(
ctx
,
s
->
index
,
&
s
->
volume
,
NULL
,
NULL
));
}
}
void
xpa_sink_input_set_mute
(
struct
siso_watch
*
w
,
bool
mute
)
{
for
(
size_t
i
=
0
;
i
<
w
->
sisos
.
len
;
i
++
)
{
struct
siso
*
s
=
&
w
->
sisos
.
items
[
i
];
pa_operation_unref
(
pa_context_set_sink_input_mute
(
ctx
,
s
->
index
,
mute
,
NULL
,
NULL
));
}
}
void
xpa_sink_input_set_sink
(
struct
siso_watch
*
w
,
uint32_t
sink_index
)
{
for
(
size_t
i
=
0
;
i
<
w
->
sisos
.
len
;
i
++
)
{
struct
siso
*
s
=
&
w
->
sisos
.
items
[
i
];
pa_operation_unref
(
pa_context_move_sink_input_by_index
(
ctx
,
s
->
index
,
sink_index
,
NULL
,
NULL
));
}
}
void
pa
()
{
// connect to PA
xpa_main_loop
=
pa_glib_mainloop_new
(
g_main_context_default
());
pa_mainloop_api
*
api
=
pa_glib_mainloop_get_api
(
xpa_main_loop
);
pa_context
*
ctx
=
pa_context_new
(
api
,
CLIENT_NAME
);
ctx
=
pa_context_new
(
api
,
CLIENT_NAME
);
pa_context_connect
(
ctx
,
NULL
,
PA_CONTEXT_NOAUTOSPAWN
,
NULL
);
pa_context_set_state_callback
(
ctx
,
&
xpa_on_connect
,
NULL
);
...
...
pa.h
View file @
5aa82d41
#ifndef PA_H
#define PA_H
#include "pa_siso_watch_list.h"
extern
struct
siso_watch_list
sink_inputs
;
extern
struct
siso_watch_list
sinks
;
void
xpa_sink_input_set_volume
(
struct
siso_watch
*
w
,
float
delta
);
void
xpa_sink_input_set_mute
(
struct
siso_watch
*
w
,
bool
mute
);
void
xpa_sink_input_set_sink
(
struct
siso_watch
*
w
,
uint32_t
sink_index
);
void
pa
();
#endif
pa_siso_watch_list.c
View file @
5aa82d41
...
...
@@ -2,46 +2,50 @@
#include "pa_siso_watch_list.h"
void
siso_watch_add_index
(
struct
siso_watch
*
w
,
uint32_t
pa_index
)
{
for
(
size_t
i
=
0
;
i
<
w
->
indices
.
len
;)
{
if
(
w
->
indices
.
items
[
i
]
==
pa_index
)
{
return
;
}
}
w
->
indices
.
len
++
;
w
->
indices
.
items
=
realloc
(
w
->
indices
.
items
,
sizeof
(
uint32_t
)
*
w
->
indices
.
len
);
w
->
indices
.
items
[
w
->
indices
.
len
-
1
]
=
pa_index
;
}
void
siso_watch_remove_index
(
struct
siso_watch
*
w
,
uint32_t
pa_index
)
{
if
(
w
->
indice
s
.
len
==
0
)
return
;
if
(
w
->
siso
s
.
len
==
0
)
return
;
for
(
size_t
i
=
0
;
i
<
w
->
indice
s
.
len
;)
{
if
(
w
->
indices
.
items
[
i
]
==
pa_index
)
{
memmove
(
&
w
->
indices
.
items
[
i
],
&
w
->
indice
s
.
items
[
i
+
1
],
w
->
indice
s
.
len
-
i
-
1
);
w
->
indice
s
.
len
--
;
w
->
indices
.
items
=
realloc
(
w
->
indice
s
.
items
,
sizeof
(
uint32_t
)
*
w
->
indice
s
.
len
);
for
(
size_t
i
=
0
;
i
<
w
->
siso
s
.
len
;)
{
if
(
w
->
sisos
.
items
[
i
].
index
==
pa_index
)
{
memmove
(
&
w
->
sisos
.
items
[
i
],
&
w
->
siso
s
.
items
[
i
+
1
],
w
->
siso
s
.
len
-
i
-
1
);
w
->
siso
s
.
len
--
;
w
->
sisos
.
items
=
realloc
(
w
->
siso
s
.
items
,
sizeof
(
uint32_t
)
*
w
->
siso
s
.
len
);
}
else
{
i
++
;
}
}
}
void
siso_watch_update
(
struct
siso_watch
*
w
,
uint32_t
target_index
,
pa_volume_t
volume
,
bool
mute
)
{
void
siso_watch_update
(
struct
siso_watch
*
w
,
uint32_t
pa_index
,
uint32_t
target_index
,
pa_cvolume
volume
,
bool
mute
)
{
w
->
target
=
target_index
;
w
->
volume
=
volume
;
w
->
mute
=
mute
;
struct
siso
*
s
=
NULL
;
for
(
size_t
i
=
0
;
i
<
w
->
sisos
.
len
;
i
++
)
{
if
(
w
->
sisos
.
items
[
i
].
index
==
pa_index
)
{
s
=
&
w
->
sisos
.
items
[
i
];
break
;
}
}
if
(
!
s
)
{
w
->
sisos
.
len
++
;
w
->
sisos
.
items
=
realloc
(
w
->
sisos
.
items
,
sizeof
(
struct
siso
)
*
w
->
sisos
.
len
);
s
=
&
w
->
sisos
.
items
[
w
->
sisos
.
len
-
1
];
}
s
->
index
=
pa_index
;
s
->
volume
=
volume
;
s
->
mute
=
mute
;
if
(
w
->
volume_changed
)
{
w
->
volume_changed
(
w
);
}
}
uint32_t
siso_watch_get_first_or_default
(
struct
siso_watch
*
w
,
uint32_t
default_
)
{
if
(
!
w
||
w
->
indice
s
.
len
==
0
)
return
default_
;
return
w
->
indices
.
items
[
0
]
;
if
(
!
w
||
w
->
siso
s
.
len
==
0
)
return
default_
;
return
w
->
sisos
.
items
[
0
].
index
;
}
struct
siso_watch
*
siso_add_name
(
struct
siso_watch_list
*
wl
,
const
char
*
name
)
{
...
...
@@ -51,10 +55,9 @@ struct siso_watch *siso_add_name(struct siso_watch_list *wl, const char* name) {
struct
siso_watch
*
item
=
&
wl
->
items
[
wl
->
len
-
1
];
item
->
name
=
strdup
(
name
);
item
->
target
=
-
1
;
item
->
volume
=
PA_VOLUME_MUTED
;
item
->
mute
=
true
;
item
->
indice
s
.
len
=
0
;
item
->
indice
s
.
items
=
NULL
;
item
->
siso
s
.
len
=
0
;
item
->
siso
s
.
items
=
NULL
;
item
->
volume_changed
=
NULL
;
item
->
userdata
=
NULL
;
...
...
pa_siso_watch_list.h
View file @
5aa82d41
...
...
@@ -7,15 +7,20 @@
// siso (sink source) watch lists help keeping track of the indices of
// PulseAudio Sink/Source/Sink Input/Source Output indices by name.
struct
siso
{
uint32_t
index
;
pa_cvolume
volume
;
bool
mute
;
};
struct
siso_watch
{
const
char
*
name
;
uint32_t
target
;
// sink in case of watching a sink input
pa_volume_t
volume
;
bool
mute
;
struct
indices_list
{
size_t
len
;
uint32_t
*
items
;
}
indice
s
;
struct
siso
*
items
;
}
siso
s
;
void
(
*
volume_changed
)(
struct
siso_watch
*
);
void
*
userdata
;
};
...
...
@@ -25,9 +30,9 @@ struct siso_watch_list {
struct
siso_watch
*
items
;
};
void
siso_watch_add_index
(
struct
siso_watch
*
w
,
uint32_t
pa_index
);
void
siso_watch_remove_index
(
struct
siso_watch
*
w
,
uint32_t
pa_index
);
void
siso_watch_update
(
struct
siso_watch
*
w
,
uint32_t
target_index
,
pa_volume_t
volume
,
bool
mute
);
void
siso_watch_update
(
struct
siso_watch
*
w
,
uint32_t
pa_index
,
uint32_t
target_index
,
pa_cvolume
volume
,
bool
mute
);
uint32_t
siso_watch_get_first_or_default
(
struct
siso_watch
*
w
,
uint32_t
default_
);
struct
siso_watch
*
siso_add_name
(
struct
siso_watch_list
*
wl
,
const
char
*
name
);
struct
siso_watch
*
siso_get
(
struct
siso_watch_list
*
wl
,
const
char
*
name
);
...
...
panelcontrol.c
View file @
5aa82d41
...
...
@@ -22,12 +22,28 @@ void show_mute_and_speakers(struct siso_watch *w) {
midi_button_led
(
sp
->
seq
,
sp
->
port
,
BOTTOM1
,
w
->
target
==
speakers
?
BUTTON_LED_ON
:
BUTTON_LED_OFF
);
}
void
button_
test
(
enum
button
button
,
enum
button_direction
direction
,
void
*
userdata
)
{
void
button_
mute
(
enum
button
button
,
enum
button_direction
direction
,
void
*
userdata
)
{
fprintf
(
stdout
,
"button pressed: %i dir=%i
\n
"
,
button
,
direction
);
if
(
direction
!=
BUTTON_PRESS
)
return
;
struct
siso_watch
*
w
=
userdata
;
xpa_sink_input_set_mute
(
w
,
!
w
->
mute
);
}
void
encoder_test
(
enum
encoder
encoder
,
int
delta
,
void
*
userdata
)
{
void
button_sink
(
enum
button
button
,
enum
button_direction
direction
,
void
*
userdata
)
{
fprintf
(
stdout
,
"button pressed: %i dir=%i
\n
"
,
button
,
direction
);
if
(
direction
!=
BUTTON_PRESS
)
return
;
struct
siso_watch
*
w
=
userdata
;
uint32_t
speakers
=
siso_watch_get_first_or_default
(
siso_get
(
&
sinks
,
"speakers"
),
-
1
);
uint32_t
headphones
=
siso_watch_get_first_or_default
(
siso_get
(
&
sinks
,
"headphones"
),
-
1
);
uint32_t
sink
=
w
->
target
==
speakers
?
headphones
:
speakers
;
xpa_sink_input_set_sink
(
w
,
sink
);
}
void
encoder_volume
(
enum
encoder
encoder
,
int
delta
,
void
*
userdata
)
{
fprintf
(
stdout
,
"encoder turned: %i delta=%i
\n
"
,
encoder
,
delta
);
struct
siso_watch
*
w
=
userdata
;
if
(
delta
>=
64
)
delta
=
-
(
delta
-
64
);
xpa_sink_input_set_volume
(
w
,
delta
/
100
.
0
f
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
...
...
@@ -39,6 +55,7 @@ int main(int argc, char *argv[]) {
// keep track of speakers sink PA index
siso_add_name
(
&
sinks
,
"speakers"
);
siso_add_name
(
&
sinks
,
"headphones"
);
struct
seq_port
sp
;
alsa
(
source
,
&
sp
.
seq
,
&
sp
.
port
);
...
...
@@ -48,8 +65,9 @@ int main(int argc, char *argv[]) {
mpd
->
volume_changed
=
show_mute_and_speakers
;
button_callback_add
(
TOP1
,
button_test
,
NULL
);
encoder_callback_add
(
ENC1
,
encoder_test
,
NULL
);
button_callback_add
(
TOP1
,
button_mute
,
mpd
);
button_callback_add
(
BOTTOM1
,
button_sink
,
mpd
);
encoder_callback_add
(
ENC1
,
encoder_volume
,
mpd
);
pa
();
...
...
panelcontrol.h
View file @
5aa82d41
...
...
@@ -35,8 +35,8 @@ enum button_led_state {
};
enum
button_direction
{
BUTTON_
DOWN
=
127
,
BUTTON_
UP
=
0
,
BUTTON_
PRESS
=
127
,
BUTTON_
RELEASE
=
0
,
};
enum
encoder
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment