}
volume_limit {
- name = "suppress",
+ name = "phone_suppress",
type = volume_limit.class,
- limit = -20;
+ limit = -20,
node_type = { node.phone },
calculate = builtin.method.volume_supress
}
+
+volume_limit {
+ name = "navi_suppress",
+ type = volume_limit.class,
+ limit = -20,
+ node_type = { node.navigator, node.phone },
+ calculate = builtin.method.volume_supress
+}
+
+volume_limit {
+ name = "navi_maxlim",
+ type = volume_limit.maximum,
+ limit = -10,
+ node_type = { node.navigator }
+}
+
+volume_limit {
+ name = "player_maxlim",
+ type = volume_limit.maximum,
+ limit = -20,
+ node_type = { node.player }
+}
+
volume_limit {
name = "video",
type = volume_limit.class,
typedef enum {
vollim_class = 1,
- vollim_generic
+ vollim_generic,
+ vollim_maximum
} vollim_type;
typedef struct {
if (!name)
luaL_error(L, "missing name field");
- if (type != vollim_class && type != vollim_generic)
+ if (type != vollim_class && type != vollim_generic && type != vollim_maximum)
luaL_error(L, "missing or invalid type");
- if (type == vollim_class && !classes)
- luaL_error(L, "missing or invalid node_type for class volume limit");
+ if ((type == vollim_class || type == vollim_maximum) && !classes)
+ luaL_error(L, "missing or invalid node_type for class/maximum limit");
if (type == vollim_generic && classes)
luaL_error(L, "can't specify node_type for generic volume limit");
if (!limit)
luaL_error(L, "missing or invalid limit");
- if (!calculate)
+ if (type != vollim_maximum && !calculate)
luaL_error(L, "missing calculate field");
- if (calculate->type == MRP_C_FUNCTION) {
+ if (type != vollim_maximum && calculate->type == MRP_C_FUNCTION) {
if (strcmp(calculate->c.signature, "odo"))
luaL_error(L, "invalid calculate field (mismatching signature)");
if (calculate->c.data == mir_volume_suppress) {
memcpy(vlim->args, &limit->value, sizeof(limit->value));
}
- if (type == vollim_generic)
+ switch (type) {
+ case vollim_generic:
mir_volume_add_generic_limit(u, vollim_calculate, vlim->args);
- else {
+ break;
+ case vollim_class:
for (i = 0; i < classes->nint; i++) {
mir_volume_add_class_limit(u, classes->ints[i], vollim_calculate,
vlim->args);
}
+ break;
+ case vollim_maximum:
+ mir_volume_add_maximum_limit(u, *(vlim->limit->value),
+ classes->nint, classes->ints);
+ break;
+ default:
+ break;
}
MRP_LUA_LEAVE(1);
static const_def_t vollim_const[] = {
{ "class" , vollim_class },
{ "generic" , vollim_generic },
+ { "maximum" , vollim_maximum },
{ NULL , 0 }
};
#define PA_RESOURCE_SET_ID_PID "pid"
+#define MIR_VOLUME_MAX_ATTENUATION -120 /* dB */
+
typedef enum pa_value_type pa_value_type;
typedef struct pa_value pa_value;
typedef struct pa_null_sink pa_null_sink;
};
struct pa_mir_volume {
- int classlen; /**< class table length */
- vlim_table *classlim; /**< class indexed table */
- vlim_table genlim; /**< generic limit */
+ int classlen; /**< class table length */
+ vlim_table *classlim; /**< class indexed table */
+ vlim_table genlim; /**< generic limit */
+ double maxlim[mir_application_class_end]; /**< per class max. limit */
};
pa_mir_volume *pa_mir_volume_init(struct userdata *u)
{
pa_mir_volume *volume = pa_xnew0(pa_mir_volume, 1);
+ int i;
(void)u;
+ for (i = 0; i < mir_application_class_end; i++)
+ volume->maxlim[i] = MIR_VOLUME_MAX_ATTENUATION;
+
return volume;
}
}
+void mir_volume_add_maximum_limit(struct userdata *u,
+ double maxlim,
+ size_t nclass,
+ int *classes)
+{
+ pa_mir_volume *volume;
+ int class;
+ size_t i;
+
+ pa_assert(u);
+ pa_assert_se((volume = u->volume));
+
+ for (i = 0; i < nclass; i++) {
+ if ((class = classes[i]) < mir_application_class_end)
+ volume->maxlim[class] = maxlim;
+ }
+}
+
+
void mir_volume_make_limiting(struct userdata *u)
{
uint32_t stamp;
double devlim, classlim;
vlim_table *tbl;
uint32_t clmask;
+ double maxlim;
pa_assert(u);
pa_assert_se((volume = u->volume));
if (class < 0 || class >= volume->classlen) {
if (class < 0 || class >= mir_application_class_end)
- attenuation = -90.0;
+ attenuation = maxlim = MIR_VOLUME_MAX_ATTENUATION;
+ else {
+ attenuation = apply_table(0.0, &volume->genlim,
+ u,class,node, "device");
+ }
}
else {
devlim = apply_table(0.0, &volume->genlim, u,class,node, "device");
pa_assert(class >= mir_application_class_begin);
pa_assert(class < mir_application_class_end);
+ maxlim = volume->maxlim[class];
clmask = (uint32_t)1 << (class - mir_application_class_begin);
-
+
if (class < volume->classlen && (tbl = volume->classlim + class))
classlim = apply_table(classlim, tbl, u, class, node, "class");
+
+ if (classlim <= MIR_VOLUME_MAX_ATTENUATION)
+ classlim = MIR_VOLUME_MAX_ATTENUATION;
+ else if (classlim < maxlim)
+ classlim = maxlim;
}
attenuation = devlim + classlim;
#include "userdata.h"
#include "list.h"
+
typedef double (*mir_volume_func_t)(struct userdata *, int, mir_node *, void*);
void mir_volume_add_class_limit(struct userdata *,int,mir_volume_func_t,void*);
void mir_volume_add_generic_limit(struct userdata *, mir_volume_func_t,void *);
+void mir_volume_add_maximum_limit(struct userdata *, double, size_t, int *);
void mir_volume_make_limiting(struct userdata *);