Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Wim Taymans
alsa-card-profile
Commits
36817559
Commit
36817559
authored
Apr 06, 2021
by
Wim Taymans
Browse files
sync with pipewire
parent
6a660bbd
Changes
9
Hide whitespace changes
Inline
Side-by-side
lib/acp/acp.c
View file @
36817559
...
...
@@ -266,6 +266,131 @@ static void profile_free(void *data)
}
}
static
int
add_pro_profile
(
pa_card
*
impl
,
uint32_t
index
)
{
snd_ctl_t
*
ctl_hndl
;
int
err
,
dev
,
count
=
0
;
pa_alsa_profile
*
ap
;
pa_alsa_profile_set
*
ps
=
impl
->
profile_set
;
pa_alsa_mapping
*
m
;
char
*
device
;
snd_pcm_info_t
*
pcminfo
;
pa_sample_spec
ss
;
snd_pcm_uframes_t
try_period_size
,
try_buffer_size
;
ss
.
format
=
PA_SAMPLE_S32LE
;
ss
.
rate
=
48000
;
ss
.
channels
=
64
;
ap
=
pa_xnew0
(
pa_alsa_profile
,
1
);
ap
->
profile_set
=
ps
;
ap
->
profile
.
name
=
ap
->
name
=
pa_xstrdup
(
"pro-audio"
);
ap
->
profile
.
description
=
ap
->
description
=
pa_xstrdup
(
_
(
"Pro Audio"
));
ap
->
profile
.
available
=
ACP_AVAILABLE_YES
;
ap
->
output_mappings
=
pa_idxset_new
(
pa_idxset_trivial_hash_func
,
pa_idxset_trivial_compare_func
);
ap
->
input_mappings
=
pa_idxset_new
(
pa_idxset_trivial_hash_func
,
pa_idxset_trivial_compare_func
);
pa_hashmap_put
(
ps
->
profiles
,
ap
->
name
,
ap
);
ap
->
output_name
=
pa_xstrdup
(
"pro-output"
);
ap
->
input_name
=
pa_xstrdup
(
"pro-input"
);
ap
->
priority
=
1
;
pa_assert_se
(
asprintf
(
&
device
,
"hw:%d"
,
index
)
>=
0
);
if
((
err
=
snd_ctl_open
(
&
ctl_hndl
,
device
,
0
))
<
0
)
{
pa_log_error
(
"can't open control for card %s: %s"
,
device
,
snd_strerror
(
err
));
return
err
;
}
snd_pcm_info_alloca
(
&
pcminfo
);
dev
=
-
1
;
while
(
1
)
{
char
desc
[
128
],
devstr
[
128
],
*
name
;
if
((
err
=
snd_ctl_pcm_next_device
(
ctl_hndl
,
&
dev
))
<
0
)
{
pa_log_error
(
"error iterating devices: %s"
,
snd_strerror
(
err
));
break
;
}
if
(
dev
<
0
)
break
;
snd_pcm_info_set_device
(
pcminfo
,
dev
);
snd_pcm_info_set_subdevice
(
pcminfo
,
0
);
snprintf
(
devstr
,
sizeof
(
devstr
),
"hw:%d,%d"
,
index
,
dev
);
if
(
count
++
==
0
)
snprintf
(
desc
,
sizeof
(
desc
),
"Pro"
);
else
snprintf
(
desc
,
sizeof
(
desc
),
"Pro %d"
,
dev
);
snd_pcm_info_set_stream
(
pcminfo
,
SND_PCM_STREAM_PLAYBACK
);
if
((
err
=
snd_ctl_pcm_info
(
ctl_hndl
,
pcminfo
))
<
0
)
{
if
(
err
!=
-
ENOENT
)
pa_log_error
(
"error pcm info: %s"
,
snd_strerror
(
err
));
}
if
(
err
>=
0
)
{
pa_assert_se
(
asprintf
(
&
name
,
"Mapping pro-output-%d"
,
dev
)
>=
0
);
m
=
pa_alsa_mapping_get
(
ps
,
name
);
m
->
description
=
pa_xstrdup
(
desc
);
m
->
device_strings
=
pa_split_spaces_strv
(
devstr
);
try_period_size
=
1024
;
try_buffer_size
=
1024
*
64
;
m
->
sample_spec
=
ss
;
if
((
m
->
output_pcm
=
pa_alsa_open_by_template
(
m
->
device_strings
,
devstr
,
NULL
,
&
m
->
sample_spec
,
&
m
->
channel_map
,
SND_PCM_STREAM_PLAYBACK
,
&
try_period_size
,
&
try_buffer_size
,
0
,
NULL
,
NULL
,
false
)))
{
pa_alsa_init_proplist_pcm
(
NULL
,
m
->
output_proplist
,
m
->
output_pcm
);
snd_pcm_close
(
m
->
output_pcm
);
m
->
output_pcm
=
NULL
;
m
->
supported
=
true
;
pa_channel_map_init_pro
(
&
m
->
channel_map
,
m
->
sample_spec
.
channels
);
}
pa_idxset_put
(
ap
->
output_mappings
,
m
,
NULL
);
free
(
name
);
}
snd_pcm_info_set_stream
(
pcminfo
,
SND_PCM_STREAM_CAPTURE
);
if
((
err
=
snd_ctl_pcm_info
(
ctl_hndl
,
pcminfo
))
<
0
)
{
if
(
err
!=
-
ENOENT
)
pa_log_error
(
"error pcm info: %s"
,
snd_strerror
(
err
));
}
if
(
err
>=
0
)
{
pa_assert_se
(
asprintf
(
&
name
,
"Mapping pro-input-%d"
,
dev
)
>=
0
);
m
=
pa_alsa_mapping_get
(
ps
,
name
);
m
->
description
=
pa_xstrdup
(
desc
);
m
->
device_strings
=
pa_split_spaces_strv
(
devstr
);
try_period_size
=
1024
;
try_buffer_size
=
1024
*
64
;
m
->
sample_spec
=
ss
;
if
((
m
->
input_pcm
=
pa_alsa_open_by_template
(
m
->
device_strings
,
devstr
,
NULL
,
&
m
->
sample_spec
,
&
m
->
channel_map
,
SND_PCM_STREAM_CAPTURE
,
&
try_period_size
,
&
try_buffer_size
,
0
,
NULL
,
NULL
,
false
)))
{
pa_alsa_init_proplist_pcm
(
NULL
,
m
->
input_proplist
,
m
->
input_pcm
);
snd_pcm_close
(
m
->
input_pcm
);
m
->
input_pcm
=
NULL
;
m
->
supported
=
true
;
pa_channel_map_init_pro
(
&
m
->
channel_map
,
m
->
sample_spec
.
channels
);
}
pa_idxset_put
(
ap
->
input_mappings
,
m
,
NULL
);
free
(
name
);
}
}
snd_ctl_close
(
ctl_hndl
);
return
0
;
}
static
void
add_profiles
(
pa_card
*
impl
)
{
pa_alsa_profile
*
ap
;
...
...
@@ -286,6 +411,9 @@ static void add_profiles(pa_card *impl)
ap
->
profile
.
flags
=
ACP_PROFILE_OFF
;
pa_hashmap_put
(
impl
->
profiles
,
ap
->
name
,
ap
);
if
(
!
impl
->
use_ucm
)
add_pro_profile
(
impl
,
impl
->
card
.
index
);
PA_HASHMAP_FOREACH
(
ap
,
impl
->
profile_set
->
profiles
,
state
)
{
pa_alsa_mapping
*
m
;
...
...
@@ -446,7 +574,7 @@ static void profile_set_available(pa_card *impl, uint32_t index,
p
->
available
=
status
;
if
(
emit
&&
impl
&&
impl
->
events
&&
impl
->
events
->
profile_available
)
if
(
emit
&&
impl
->
events
&&
impl
->
events
->
profile_available
)
impl
->
events
->
profile_available
(
impl
->
user_data
,
index
,
old
,
status
);
}
...
...
@@ -807,11 +935,9 @@ uint32_t acp_card_find_best_profile_index(struct acp_card *card, const char *nam
struct
acp_card_profile
*
p
=
profiles
[
i
];
if
(
name
)
{
if
(
strcmp
(
name
,
p
->
name
))
if
(
strcmp
(
name
,
p
->
name
)
==
0
)
best
=
i
;
continue
;
}
if
(
p
->
flags
&
ACP_PROFILE_OFF
)
{
}
else
if
(
p
->
flags
&
ACP_PROFILE_OFF
)
{
off
=
i
;
}
else
if
(
p
->
available
==
ACP_AVAILABLE_YES
)
{
if
(
best
==
ACP_INVALID_INDEX
||
p
->
priority
>
profiles
[
best
]
->
priority
)
...
...
@@ -917,7 +1043,6 @@ static int read_volume(pa_alsa_device *dev)
static
void
set_volume
(
pa_alsa_device
*
dev
,
const
pa_cvolume
*
v
)
{
pa_card
*
impl
=
dev
->
card
;
pa_cvolume
r
;
dev
->
real_volume
=
*
v
;
...
...
@@ -957,18 +1082,7 @@ static void set_volume(pa_alsa_device *dev, const pa_cvolume *v)
if
(
accurate_enough
)
pa_cvolume_reset
(
&
new_soft_volume
,
new_soft_volume
.
channels
);
if
(
!
pa_cvolume_equal
(
&
dev
->
soft_volume
,
&
new_soft_volume
))
{
dev
->
soft_volume
=
new_soft_volume
;
if
(
impl
->
events
&&
impl
->
events
->
set_soft_volume
)
{
uint32_t
i
,
n_volumes
=
new_soft_volume
.
channels
;
float
volumes
[
n_volumes
];
for
(
i
=
0
;
i
<
n_volumes
;
i
++
)
volumes
[
i
]
=
pa_sw_volume_to_linear
(
new_soft_volume
.
values
[
i
]);
impl
->
events
->
set_soft_volume
(
impl
->
user_data
,
&
dev
->
device
,
volumes
,
n_volumes
);
}
}
dev
->
soft_volume
=
new_soft_volume
;
}
else
{
pa_log_debug
(
"Wrote hardware volume: %d"
,
pa_cvolume_max
(
&
r
));
/* We can't match exactly what the user requested, hence let's
...
...
@@ -1179,11 +1293,16 @@ static int device_enable(pa_card *impl, pa_alsa_mapping *mapping, pa_alsa_device
p
->
port
.
priority
=
p
->
priority
;
}
port_index
=
acp_device_find_best_port_index
(
&
dev
->
device
,
NULL
);
if
(
impl
->
auto_port
)
port_index
=
acp_device_find_best_port_index
(
&
dev
->
device
,
NULL
);
else
port_index
=
ACP_INVALID_INDEX
;
if
(
port_index
==
ACP_INVALID_INDEX
)
dev
->
active_port
=
NULL
;
else
dev
->
active_port
=
(
pa_device_port
*
)
impl
->
card
.
ports
[
port_index
];
if
(
dev
->
active_port
)
dev
->
active_port
->
port
.
flags
|=
ACP_PORT_ACTIVE
;
...
...
@@ -1197,7 +1316,7 @@ static int device_enable(pa_card *impl, pa_alsa_mapping *mapping, pa_alsa_device
return
0
;
}
int
acp_card_set_profile
(
struct
acp_card
*
card
,
uint32_t
new_index
)
int
acp_card_set_profile
(
struct
acp_card
*
card
,
uint32_t
new_index
,
uint32_t
flags
)
{
pa_card
*
impl
=
(
pa_card
*
)
card
;
pa_alsa_mapping
*
am
;
...
...
@@ -1260,14 +1379,14 @@ int acp_card_set_profile(struct acp_card *card, uint32_t new_index)
PA_IDXSET_FOREACH
(
am
,
np
->
input_mappings
,
idx
)
{
if
(
impl
->
use_ucm
)
/* Update ports priorities */
pa_alsa_ucm_add_ports_combination
(
am
->
out
put
.
ports
,
&
am
->
ucm_context
,
pa_alsa_ucm_add_ports_combination
(
am
->
in
put
.
ports
,
&
am
->
ucm_context
,
false
,
impl
->
ports
,
np
,
NULL
);
device_enable
(
impl
,
am
,
&
am
->
input
);
}
}
if
(
op
)
op
->
profile
.
flags
&=
~
ACP_PROFILE_ACTIVE
;
np
->
profile
.
flags
|=
ACP_PROFILE_ACTIVE
;
op
->
profile
.
flags
&=
~
(
ACP_PROFILE_ACTIVE
|
ACP_PROFILE_SAVE
)
;
np
->
profile
.
flags
|=
ACP_PROFILE_ACTIVE
|
flags
;
impl
->
card
.
active_profile_index
=
new_index
;
if
(
impl
->
events
&&
impl
->
events
->
profile_changed
)
...
...
@@ -1346,6 +1465,8 @@ struct acp_card *acp_card_new(uint32_t index, const struct acp_dict *props)
card
->
active_profile_index
=
ACP_INVALID_INDEX
;
impl
->
use_ucm
=
true
;
impl
->
auto_profile
=
true
;
impl
->
auto_port
=
true
;
if
(
props
)
{
if
((
s
=
acp_dict_lookup
(
props
,
"api.alsa.use-ucm"
))
!=
NULL
)
...
...
@@ -1358,6 +1479,10 @@ struct acp_card *acp_card_new(uint32_t index, const struct acp_dict *props)
profile_set
=
s
;
if
((
s
=
acp_dict_lookup
(
props
,
"device.profile"
))
!=
NULL
)
profile
=
s
;
if
((
s
=
acp_dict_lookup
(
props
,
"api.acp.auto-profile"
))
!=
NULL
)
impl
->
auto_profile
=
(
strcmp
(
s
,
"true"
)
==
0
||
atoi
(
s
)
==
1
);
if
((
s
=
acp_dict_lookup
(
props
,
"api.acp.auto-port"
))
!=
NULL
)
impl
->
auto_port
=
(
strcmp
(
s
,
"true"
)
==
0
||
atoi
(
s
)
==
1
);
}
impl
->
ucm
.
default_sample_spec
.
format
=
PA_SAMPLE_S16NE
;
...
...
@@ -1425,8 +1550,11 @@ struct acp_card *acp_card_new(uint32_t index, const struct acp_dict *props)
init_jacks
(
impl
);
if
(
!
impl
->
auto_profile
&&
profile
==
NULL
)
profile
=
"off"
;
profile_index
=
acp_card_find_best_profile_index
(
&
impl
->
card
,
profile
);
acp_card_set_profile
(
&
impl
->
card
,
profile_index
);
acp_card_set_profile
(
&
impl
->
card
,
profile_index
,
0
);
init_eld_ctls
(
impl
);
...
...
@@ -1579,11 +1707,9 @@ uint32_t acp_device_find_best_port_index(struct acp_device *dev, const char *nam
struct
acp_port
*
p
=
ports
[
i
];
if
(
name
)
{
if
(
strcmp
(
name
,
p
->
name
))
if
(
strcmp
(
name
,
p
->
name
)
==
0
)
best
=
i
;
continue
;
}
if
(
p
->
available
==
ACP_AVAILABLE_YES
)
{
}
else
if
(
p
->
available
==
ACP_AVAILABLE_YES
)
{
if
(
best
==
ACP_INVALID_INDEX
||
p
->
priority
>
ports
[
best
]
->
priority
)
best
=
i
;
}
else
if
(
p
->
available
!=
ACP_AVAILABLE_NO
)
{
...
...
@@ -1606,7 +1732,7 @@ uint32_t acp_device_find_best_port_index(struct acp_device *dev, const char *nam
return
ACP_INVALID_INDEX
;
}
int
acp_device_set_port
(
struct
acp_device
*
dev
,
uint32_t
port_index
)
int
acp_device_set_port
(
struct
acp_device
*
dev
,
uint32_t
port_index
,
uint32_t
flags
)
{
pa_alsa_device
*
d
=
(
pa_alsa_device
*
)
dev
;
pa_card
*
impl
=
d
->
card
;
...
...
@@ -1617,16 +1743,15 @@ int acp_device_set_port(struct acp_device *dev, uint32_t port_index)
return
-
EINVAL
;
p
=
(
pa_device_port
*
)
impl
->
card
.
ports
[
port_index
];
if
(
p
==
old
)
return
0
;
if
(
!
pa_hashmap_get
(
d
->
ports
,
p
->
name
))
return
-
EINVAL
;
p
->
port
.
flags
=
ACP_PORT_ACTIVE
|
flags
;
if
(
p
==
old
)
return
0
;
if
(
old
)
old
->
port
.
flags
&=
~
ACP_PORT_ACTIVE
;
old
->
port
.
flags
&=
~
(
ACP_PORT_ACTIVE
|
ACP_PORT_SAVE
)
;
d
->
active_port
=
p
;
p
->
port
.
flags
|=
ACP_PORT_ACTIVE
;
if
(
impl
->
use_ucm
)
{
pa_alsa_ucm_port_data
*
data
;
...
...
@@ -1636,7 +1761,8 @@ int acp_device_set_port(struct acp_device *dev, uint32_t port_index)
mixer_volume_init
(
impl
,
d
);
sync_mixer
(
d
,
p
);
res
=
pa_alsa_ucm_set_port
(
d
->
ucm_context
,
p
,
true
);
res
=
pa_alsa_ucm_set_port
(
d
->
ucm_context
,
p
,
dev
->
direction
==
ACP_DIRECTION_PLAYBACK
);
}
else
{
pa_alsa_port_data
*
data
;
...
...
@@ -1684,8 +1810,6 @@ int acp_device_set_volume(struct acp_device *dev, const float *volume, uint32_t
}
else
{
d
->
real_volume
=
v
;
d
->
soft_volume
=
v
;
if
(
impl
->
events
&&
impl
->
events
->
set_soft_volume
)
impl
->
events
->
set_soft_volume
(
impl
->
user_data
,
dev
,
volume
,
n_volume
);
}
if
(
!
pa_cvolume_equal
(
&
d
->
real_volume
,
&
old_volume
))
if
(
impl
->
events
&&
impl
->
events
->
volume_changed
)
...
...
@@ -1693,19 +1817,28 @@ int acp_device_set_volume(struct acp_device *dev, const float *volume, uint32_t
return
0
;
}
int
acp_device_get_volume
(
struct
acp_devic
e
*
de
v
,
float
*
volume
,
uint32_t
n_volume
)
static
int
get_volume
(
pa_cvolum
e
*
v
,
float
*
volume
,
uint32_t
n_volume
)
{
pa_alsa_device
*
d
=
(
pa_alsa_device
*
)
dev
;
pa_cvolume
v
;
uint32_t
i
;
v
=
d
->
real_volume
;
if
(
v
.
channels
==
0
)
if
(
v
->
channels
==
0
)
return
-
EIO
;
for
(
i
=
0
;
i
<
n_volume
;
i
++
)
volume
[
i
]
=
pa_sw_volume_to_linear
(
v
.
values
[
i
%
v
.
channels
]);
volume
[
i
]
=
pa_sw_volume_to_linear
(
v
->
values
[
i
%
v
->
channels
]);
return
0
;
}
int
acp_device_get_soft_volume
(
struct
acp_device
*
dev
,
float
*
volume
,
uint32_t
n_volume
)
{
pa_alsa_device
*
d
=
(
pa_alsa_device
*
)
dev
;
return
get_volume
(
&
d
->
soft_volume
,
volume
,
n_volume
);
}
int
acp_device_get_volume
(
struct
acp_device
*
dev
,
float
*
volume
,
uint32_t
n_volume
)
{
pa_alsa_device
*
d
=
(
pa_alsa_device
*
)
dev
;
return
get_volume
(
&
d
->
real_volume
,
volume
,
n_volume
);
}
int
acp_device_set_mute
(
struct
acp_device
*
dev
,
bool
mute
)
{
pa_alsa_device
*
d
=
(
pa_alsa_device
*
)
dev
;
...
...
@@ -1721,8 +1854,6 @@ int acp_device_set_mute(struct acp_device *dev, bool mute)
d
->
set_mute
(
d
,
mute
);
}
else
{
d
->
muted
=
mute
;
if
(
impl
->
events
&&
impl
->
events
->
set_soft_mute
)
impl
->
events
->
set_soft_mute
(
impl
->
user_data
,
dev
,
mute
);
}
if
(
old_muted
!=
mute
)
if
(
impl
->
events
&&
impl
->
events
->
mute_changed
)
...
...
lib/acp/acp.h
View file @
36817559
...
...
@@ -136,7 +136,7 @@ const char *acp_available_str(enum acp_available status);
#define ACP_KEY_PORT_TYPE "port.type"
/**< a Port type, like "aux", "speaker", ... */
#define ACP_KEY_PORT_AVAILABILITY_GROUP "port.availability-group"
/**< An i
n
dentifier for the group of ports that share their availability status with
/**< An identifier for the group of ports that share their availability status with
* each other. This is meant especially for handling cases where one 3.5 mm connector
* is used for headphones, headsets and microphones, and the hardware can only tell
* that something was plugged in but not what exactly. In this situation the ports for
...
...
@@ -177,15 +177,12 @@ struct acp_card_events {
void
(
*
volume_changed
)
(
void
*
data
,
struct
acp_device
*
dev
);
void
(
*
mute_changed
)
(
void
*
data
,
struct
acp_device
*
dev
);
void
(
*
set_soft_volume
)
(
void
*
data
,
struct
acp_device
*
dev
,
const
float
*
volume
,
uint32_t
n_volume
);
void
(
*
set_soft_mute
)
(
void
*
data
,
struct
acp_device
*
dev
,
bool
mute
);
};
struct
acp_port
{
uint32_t
index
;
/**< unique index for this port */
#define ACP_PORT_ACTIVE (1<<0)
#define ACP_PORT_SAVE (1<<1)
/* if the port needs saving */
uint32_t
flags
;
/**< extra port flags */
const
char
*
name
;
/**< Name of this port */
...
...
@@ -229,6 +226,7 @@ struct acp_card_profile {
uint32_t
index
;
#define ACP_PROFILE_ACTIVE (1<<0)
#define ACP_PROFILE_OFF (1<<1)
/* the Off profile */
#define ACP_PROFILE_SAVE (1<<2)
/* if the profile needs saving */
uint32_t
flags
;
const
char
*
name
;
...
...
@@ -274,12 +272,13 @@ int acp_card_poll_descriptors_revents(struct acp_card *card, struct pollfd *pfds
int
acp_card_handle_events
(
struct
acp_card
*
card
);
uint32_t
acp_card_find_best_profile_index
(
struct
acp_card
*
card
,
const
char
*
name
);
int
acp_card_set_profile
(
struct
acp_card
*
card
,
uint32_t
profile_index
);
int
acp_card_set_profile
(
struct
acp_card
*
card
,
uint32_t
profile_index
,
uint32_t
flags
);
uint32_t
acp_device_find_best_port_index
(
struct
acp_device
*
dev
,
const
char
*
name
);
int
acp_device_set_port
(
struct
acp_device
*
dev
,
uint32_t
port_index
);
int
acp_device_set_port
(
struct
acp_device
*
dev
,
uint32_t
port_index
,
uint32_t
flags
);
int
acp_device_set_volume
(
struct
acp_device
*
dev
,
const
float
*
volume
,
uint32_t
n_volume
);
int
acp_device_get_soft_volume
(
struct
acp_device
*
dev
,
float
*
volume
,
uint32_t
n_volume
);
int
acp_device_get_volume
(
struct
acp_device
*
dev
,
float
*
volume
,
uint32_t
n_volume
);
int
acp_device_set_mute
(
struct
acp_device
*
dev
,
bool
mute
);
int
acp_device_get_mute
(
struct
acp_device
*
dev
,
bool
*
mute
);
...
...
lib/acp/alsa-mixer.c
View file @
36817559
...
...
@@ -4948,10 +4948,16 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
fn
=
pa_maybe_prefix_path
(
fname
?
fname
:
"default.conf"
,
get_default_profile_dir
());
if
(
access
(
fn
,
R_OK
)
!=
0
&&
fname
!=
NULL
)
{
pa_log_error
(
"profile-set '%s' can't be accessed, trying default.conf"
,
fn
);
fn
=
pa_maybe_prefix_path
(
"default.conf"
,
if
((
r
=
access
(
fn
,
R_OK
))
!=
0
)
{
if
(
fname
!=
NULL
)
{
pa_log_warn
(
"profile-set '%s' can't be accessed: %m"
,
fn
);
fn
=
pa_maybe_prefix_path
(
"default.conf"
,
get_default_profile_dir
());
r
=
access
(
fn
,
R_OK
);
}
if
(
r
!=
0
)
{
pa_log_warn
(
"profile-set '%s' can't be accessed: %m"
,
fn
);
}
}
r
=
pa_config_parse
(
fn
,
NULL
,
items
,
NULL
,
false
,
ps
);
pa_xfree
(
fn
);
...
...
@@ -5152,6 +5158,8 @@ void pa_alsa_profile_set_probe(
uint32_t
idx
;
p
=
*
pp
;
pa_log_debug
(
"Check Profile %s."
,
p
->
name
);
/* Skip if fallback and already found something */
if
(
found_input
&&
p
->
fallback_input
)
continue
;
...
...
lib/acp/alsa-mixer.h
View file @
36817559
...
...
@@ -180,7 +180,6 @@ struct pa_alsa_jack {
struct
pa_alsa_mixer_id
alsa_id
;
char
*
name
;
/* E g "Headphone" */
char
*
alsa_name
;
/* E g "Headphone Jack" */
bool
has_control
;
/* is the jack itself present? */
bool
plugged_in
;
/* is this jack currently plugged in? */
snd_mixer_elem_t
*
melem
;
/* Jack detection handle */
...
...
lib/acp/alsa-util.c
View file @
36817559
...
...
@@ -717,7 +717,7 @@ snd_pcm_t *pa_alsa_open_by_device_string(
if
(
!
pa_startswith
(
d
,
"plug:"
)
&&
!
pa_startswith
(
d
,
"plughw:"
))
{
char
*
t
;
t
=
pa_sprintf_malloc
(
"plug:%s"
,
d
);
t
=
pa_sprintf_malloc
(
"plug:
SLAVE='
%s
'
"
,
d
);
pa_xfree
(
d
);
d
=
t
;
...
...
lib/acp/card.h
View file @
36817559
...
...
@@ -44,6 +44,8 @@ struct pa_card {
bool
use_ucm
;
bool
soft_mixer
;
bool
auto_profile
;
bool
auto_port
;
pa_alsa_ucm_config
ucm
;
pa_alsa_profile_set
*
profile_set
;
...
...
lib/acp/channelmap.h
View file @
36817559
...
...
@@ -201,6 +201,17 @@ static inline pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m,
return
NULL
;
}
static
inline
pa_channel_map
*
pa_channel_map_init_pro
(
pa_channel_map
*
m
,
unsigned
channels
)
{
unsigned
i
;
pa_channel_map_init
(
m
);
for
(
i
=
0
;
i
<
channels
;
i
++
)
m
->
map
[
i
]
=
PA_CHANNEL_POSITION_INVALID
;
m
->
channels
=
(
uint8_t
)
channels
;
return
m
;
}
typedef
uint64_t
pa_channel_position_mask_t
;
#define PA_CHANNEL_POSITION_MASK(f) ((pa_channel_position_mask_t) (1ULL << (f)))
...
...
lib/acp/device-port.h
View file @
36817559
...
...
@@ -72,7 +72,7 @@ struct pa_device_port {
unsigned
priority
;
pa_available_t
available
;
/* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
char
*
availability_group
;
/* a string i
n
dentifier which determine the group of devices handling the available state simulteneously */
char
*
availability_group
;
/* a string identifier which determine the group of devices handling the available state simulteneously */
pa_direction_t
direction
;
int64_t
latency_offset
;
...
...
mixer/profile-sets/default.conf
View file @
36817559
...
...
@@ -461,6 +461,102 @@ channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority
=
6
direction
=
output
[
Mapping
hdmi
-
stereo
-
extra8
]
description
=
Digital
Stereo
(
HDMI
9
)
device
-
strings
=
hdmi
:%
f
,
8
paths
-
output
=
hdmi
-
output
-
8
channel
-
map
=
left
,
right
priority
=
7
direction
=
output
[
Mapping
hdmi
-
surround
-
extra8
]
description
=
Digital
Surround
5
.
1
(
HDMI
9
)
device
-
strings
=
hdmi
:%
f
,
8
paths
-
output
=
hdmi
-
output
-
8
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
priority
=
6
direction
=
output
[
Mapping
hdmi
-
surround71
-
extra8
]
description
=
Digital
Surround
7
.
1
(
HDMI
9
)
device
-
strings
=
hdmi
:%
f
,
8
paths
-
output
=
hdmi
-
output
-
8
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
,
side
-
left
,
side
-
right
priority
=
6
direction
=
output
[
Mapping
hdmi
-
dts
-
surround
-
extra8
]
description
=
Digital
Surround
5
.
1
(
HDMI
9
/
DTS
)
device
-
strings
=
dcahdmi
:%
f
,
8
paths
-
output
=
hdmi
-
output
-
8
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
priority
=
6
direction
=
output
[
Mapping
hdmi
-
stereo
-
extra9
]
description
=
Digital
Stereo
(
HDMI
10
)
device
-
strings
=
hdmi
:%
f
,
9
paths
-
output
=
hdmi
-
output
-
9
channel
-
map
=
left
,
right
priority
=
7
direction
=
output
[
Mapping
hdmi
-
surround
-
extra9
]
description
=
Digital
Surround
5
.
1
(
HDMI
10
)
device
-
strings
=
hdmi
:%
f
,
9
paths
-
output
=
hdmi
-
output
-
9
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
priority
=
6
direction
=
output
[
Mapping
hdmi
-
surround71
-
extra9
]
description
=
Digital
Surround
7
.
1
(
HDMI
10
)
device
-
strings
=
hdmi
:%
f
,
9
paths
-
output
=
hdmi
-
output
-
9
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
,
side
-
left
,
side
-
right
priority
=
6
direction
=
output
[
Mapping
hdmi
-
dts
-
surround
-
extra9
]
description
=
Digital
Surround
5
.
1
(
HDMI
10
/
DTS
)
device
-
strings
=
dcahdmi
:%
f
,
9
paths
-
output
=
hdmi
-
output
-
9
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
priority
=
6
direction
=
output
[
Mapping
hdmi
-
stereo
-
extra10
]
description
=
Digital
Stereo
(
HDMI
11
)
device
-
strings
=
hdmi
:%
f
,
10
paths
-
output
=
hdmi
-
output
-
10
channel
-
map
=
left
,
right
priority
=
7
direction
=
output
[
Mapping
hdmi
-
surround
-
extra10
]
description
=
Digital
Surround
5
.
1
(
HDMI
11
)
device
-
strings
=
hdmi
:%
f
,
10
paths
-
output
=
hdmi
-
output
-
10
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
priority
=
6
direction
=
output
[
Mapping
hdmi
-
surround71
-
extra10
]
description
=
Digital
Surround
7
.
1
(
HDMI
11
)
device
-
strings
=
hdmi
:%
f
,
10
paths
-
output
=
hdmi
-
output
-
10
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
,
side
-
left
,
side
-
right
priority
=
6
direction
=
output
[
Mapping
hdmi
-
dts
-
surround
-
extra10
]
description
=
Digital
Surround
5
.
1
(
HDMI
11
/
DTS
)
device
-
strings
=
dcahdmi
:%
f
,
10
paths
-
output
=
hdmi
-
output
-
10
channel
-
map
=
front
-
left
,
front
-
right
,
rear
-
left
,
rear
-
right
,
front
-
center
,
lfe
priority
=
6
direction
=
output
[
Mapping
multichannel
-
output
]
device
-
strings
=
hw
:%
f
channel
-
map
=
left
,
right
,
rear
-
left
,
rear
-
right
...
...
Write
Preview