snd_mixer_elem_t *me;
snd_mixer_selem_channel_id_t c;
pa_channel_position_mask_t mask = 0;
+ pa_volume_t max_channel_volume = PA_VOLUME_MUTED;
unsigned k;
pa_assert(m);
f = from_alsa_volume(value, e->min_volume, e->max_volume);
}
+ if (f > max_channel_volume)
+ max_channel_volume = f;
+
for (k = 0; k < cm->channels; k++)
if (e->masks[c][e->n_channels-1] & PA_CHANNEL_POSITION_MASK(cm->map[k]))
if (v->values[k] < f)
for (k = 0; k < cm->channels; k++)
if (!(mask & PA_CHANNEL_POSITION_MASK(cm->map[k])))
- v->values[k] = PA_VOLUME_NORM;
+ v->values[k] = max_channel_volume;
return 0;
}
snd_mixer_elem_t *me;
snd_mixer_selem_channel_id_t c;
pa_channel_position_mask_t mask = 0;
+ pa_volume_t max_channel_volume = PA_VOLUME_MUTED;
unsigned k;
pa_assert(m);
for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
int r;
pa_volume_t f = PA_VOLUME_MUTED;
+ pa_bool_t found = FALSE;
for (k = 0; k < cm->channels; k++)
- if (e->masks[c][e->n_channels-1] & PA_CHANNEL_POSITION_MASK(cm->map[k]))
+ if (e->masks[c][e->n_channels-1] & PA_CHANNEL_POSITION_MASK(cm->map[k])) {
+ found = TRUE;
if (v->values[k] > f)
f = v->values[k];
+ }
+
+ if (!found) {
+ /* Hmm, so this channel does not exist in the volume
+ * struct, so let's bind it to the overall max of the
+ * volume. */
+ f = pa_cvolume_max(v);
+ }
if (e->has_dB) {
long value = to_alsa_dB(f);
f = from_alsa_volume(value, e->min_volume, e->max_volume);
}
+ if (f > max_channel_volume)
+ max_channel_volume = f;
+
for (k = 0; k < cm->channels; k++)
if (e->masks[c][e->n_channels-1] & PA_CHANNEL_POSITION_MASK(cm->map[k]))
if (rv.values[k] < f)
for (k = 0; k < cm->channels; k++)
if (!(mask & PA_CHANNEL_POSITION_MASK(cm->map[k])))
- rv.values[k] = PA_VOLUME_NORM;
+ rv.values[k] = max_channel_volume;
*v = rv;
return 0;
int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) {
pa_alsa_element *e;
- int r;
+ int r = 0;
pa_assert(m);
pa_assert(p);
PA_LLIST_FOREACH(e, p->elements) {
switch (e->switch_use) {
- case PA_ALSA_SWITCH_MUTE:
case PA_ALSA_SWITCH_OFF:
r = element_set_switch(e, m, FALSE);
break;
r = element_set_switch(e, m, TRUE);
break;
+ case PA_ALSA_SWITCH_MUTE:
case PA_ALSA_SWITCH_IGNORE:
case PA_ALSA_SWITCH_SELECT:
r = 0;
switch (e->volume_use) {
case PA_ALSA_VOLUME_OFF:
- case PA_ALSA_VOLUME_MERGE:
r = element_mute_volume(e, m);
break;
r = element_zero_volume(e, m);
break;
+ case PA_ALSA_VOLUME_MERGE:
case PA_ALSA_VOLUME_IGNORE:
r = 0;
break;
items[1].data = &p->description;
items[2].data = &p->name;
- fn = pa_maybe_prefix_path(fname, PA_ALSA_PATHS_DIR);
+ fn = pa_maybe_prefix_path(fname,
+#if defined(__linux__) && !defined(__OPTIMIZE__)
+ pa_run_from_build_tree() ? PA_BUILDDIR "/modules/alsa/mixer/paths/" :
+#endif
+ PA_ALSA_PATHS_DIR);
+
r = pa_config_parse(fn, NULL, items, p);
pa_xfree(fn);
if (bonus) {
if (pa_channel_map_equal(&m->channel_map, bonus))
- m->priority += 5000;
+ m->priority += 50;
else if (m->channel_map.channels == bonus->channels)
- m->priority += 4000;
+ m->priority += 30;
}
return 0;
else
name = pa_sprintf_malloc("input:%s", n->name);
- if ((p = pa_hashmap_get(ps->profiles, name))) {
+ if (pa_hashmap_get(ps->profiles, name)) {
pa_xfree(name);
return;
}
char **in;
pa_bool_t duplicate = FALSE;
- for (in = p->output_mapping_names; *in; in++)
+ for (in = name + 1; *in; in++)
if (pa_streq(*name, *in)) {
duplicate = TRUE;
break;
}
pa_idxset_put(p->output_mappings, m, NULL);
+
+ if (p->supported)
+ m->supported++;
}
pa_xstrfreev(p->output_mapping_names);
char **in;
pa_bool_t duplicate = FALSE;
- for (in = p->input_mapping_names; *in; in++)
+ for (in = name + 1; *in; in++)
if (pa_streq(*name, *in)) {
duplicate = TRUE;
break;
}
pa_idxset_put(p->input_mappings, m, NULL);
+
+ if (p->supported)
+ m->supported++;
}
pa_xstrfreev(p->input_mapping_names);
if (!fname)
fname = "default.conf";
- fn = pa_maybe_prefix_path(fname, PA_ALSA_PROFILE_SETS_DIR);
+ fn = pa_maybe_prefix_path(fname,
+#if defined(__linux__) && !defined(__OPTIMIZE__)
+ pa_run_from_build_tree() ? PA_BUILDDIR "/modules/alsa/mixer/profile-sets/" :
+#endif
+ PA_ALSA_PROFILE_SETS_DIR);
+
r = pa_config_parse(fn, NULL, items, ps);
pa_xfree(fn);
return NULL;
}
-void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss) {
+void pa_alsa_profile_set_probe(
+ pa_alsa_profile_set *ps,
+ const char *dev_id,
+ const pa_sample_spec *ss,
+ unsigned default_n_fragments,
+ unsigned default_fragment_size_msec) {
+
void *state;
pa_alsa_profile *p, *last = NULL;
pa_alsa_mapping *m;
PA_HASHMAP_FOREACH(p, ps->profiles, state) {
pa_sample_spec try_ss;
pa_channel_map try_map;
+ snd_pcm_uframes_t try_period_size, try_buffer_size;
uint32_t idx;
/* Is this already marked that it is supported? (i.e. from the config file) */
try_ss = *ss;
try_ss.channels = try_map.channels;
+ try_period_size =
+ pa_usec_to_bytes(default_fragment_size_msec * PA_USEC_PER_MSEC, &try_ss) /
+ pa_frame_size(&try_ss);
+ try_buffer_size = default_n_fragments * try_period_size;
+
if (!(m ->output_pcm = pa_alsa_open_by_template(
m->device_strings,
dev_id,
NULL,
&try_ss, &try_map,
SND_PCM_STREAM_PLAYBACK,
- NULL, NULL, 0, NULL, NULL,
+ &try_period_size, &try_buffer_size, 0, NULL, NULL,
TRUE))) {
p->supported = FALSE;
break;
try_ss = *ss;
try_ss.channels = try_map.channels;
+ try_period_size =
+ pa_usec_to_bytes(default_fragment_size_msec*PA_USEC_PER_MSEC, &try_ss) /
+ pa_frame_size(&try_ss);
+ try_buffer_size = default_n_fragments * try_period_size;
+
if (!(m ->input_pcm = pa_alsa_open_by_template(
m->device_strings,
dev_id,
NULL,
&try_ss, &try_map,
SND_PCM_STREAM_CAPTURE,
- NULL, NULL, 0, NULL, NULL,
+ &try_period_size, &try_buffer_size, 0, NULL, NULL,
TRUE))) {
p->supported = FALSE;
break;