common: Update config structures.
Match xml format style.
This commit is contained in:
parent
40c320bc07
commit
9e4c6fa8f1
2 changed files with 336 additions and 208 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2018 Jolla Ltd.
|
||||
* Copyright (C) 2013-2022 Jolla Ltd.
|
||||
*
|
||||
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
|
||||
*
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
#include "droid/version.h"
|
||||
#include "droid/droid-config.h"
|
||||
#include "droid/sllist.h"
|
||||
#include "config-parser-xml.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -36,35 +37,13 @@
|
|||
#include <valgrind/memcheck.h>
|
||||
#endif
|
||||
|
||||
#include <pulse/rtclock.h>
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/volume.h>
|
||||
#include <pulse/xmalloc.h>
|
||||
|
||||
#include <pulsecore/core.h>
|
||||
#include <pulsecore/core-error.h>
|
||||
#include <pulsecore/i18n.h>
|
||||
#include <pulsecore/module.h>
|
||||
#include <pulsecore/memchunk.h>
|
||||
#include <pulsecore/sink.h>
|
||||
#include <pulsecore/modargs.h>
|
||||
#include <pulsecore/core-rtclock.h>
|
||||
#include <pulsecore/core-util.h>
|
||||
#include <pulsecore/sample-util.h>
|
||||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/thread.h>
|
||||
#include <pulsecore/thread-mq.h>
|
||||
#include <pulsecore/rtpoll.h>
|
||||
#include <pulsecore/time-smoother.h>
|
||||
#include <pulsecore/refcnt.h>
|
||||
#include <pulsecore/shared.h>
|
||||
#include <pulsecore/mutex.h>
|
||||
#include <pulsecore/strlist.h>
|
||||
#include <pulsecore/atomic.h>
|
||||
#include <pulsecore/modargs.h>
|
||||
|
||||
#include <hardware/audio.h>
|
||||
#include <hardware_legacy/audio_policy_conf.h>
|
||||
|
||||
#define ODM_AUDIO_POLICY_CONFIG_XML_FILE "/odm/etc/audio_policy_configuration.xml"
|
||||
#define VENDOR_AUDIO_AUDIO_POLICY_CONFIG_XML_FILE "/vendor/etc/audio/audio_policy_configuration.xml"
|
||||
|
|
@ -72,16 +51,14 @@
|
|||
#define SYSTEM_AUDIO_POLICY_CONFIG_XML_FILE "/system/etc/audio_policy_configuration.xml"
|
||||
|
||||
|
||||
pa_droid_config_audio *pa_droid_config_load(pa_modargs *ma) {
|
||||
pa_droid_config_audio *config = NULL;
|
||||
dm_config_device *dm_config_load(pa_modargs *ma) {
|
||||
dm_config_device *config = NULL;
|
||||
const char *manual_config;
|
||||
const char *config_location[] = {
|
||||
ODM_AUDIO_POLICY_CONFIG_XML_FILE,
|
||||
VENDOR_AUDIO_AUDIO_POLICY_CONFIG_XML_FILE,
|
||||
VENDOR_AUDIO_POLICY_CONFIG_XML_FILE,
|
||||
AUDIO_POLICY_VENDOR_CONFIG_FILE,
|
||||
SYSTEM_AUDIO_POLICY_CONFIG_XML_FILE,
|
||||
AUDIO_POLICY_CONFIG_FILE,
|
||||
NULL};
|
||||
|
||||
pa_assert(ma);
|
||||
|
|
@ -106,92 +83,210 @@ pa_droid_config_audio *pa_droid_config_load(pa_modargs *ma) {
|
|||
return config;
|
||||
}
|
||||
|
||||
pa_droid_config_audio *pa_droid_config_dup(const pa_droid_config_audio *config) {
|
||||
pa_droid_config_audio *config_copy;
|
||||
pa_droid_config_hw_module *module, *module_copy;
|
||||
pa_droid_config_device *device, *device_copy;
|
||||
static dm_config_profile *config_profile_dup(const dm_config_profile *profile) {
|
||||
dm_config_profile *copy = pa_xnew0(dm_config_profile, 1);
|
||||
|
||||
copy->name = pa_xstrdup(profile->name);
|
||||
copy->format = profile->format;
|
||||
memcpy(copy->sampling_rates,
|
||||
profile->sampling_rates,
|
||||
sizeof(profile->sampling_rates));
|
||||
memcpy(copy->channel_masks,
|
||||
profile->channel_masks,
|
||||
sizeof(profile->channel_masks));
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static dm_config_port *config_port_dup(const dm_config_port *port, dm_config_module *module) {
|
||||
dm_config_port *copy = pa_xnew0(dm_config_port, 1);
|
||||
const dm_list_entry *i;
|
||||
|
||||
copy->module = module;
|
||||
copy->port_type = port->port_type;
|
||||
copy->name = pa_xstrdup(port->name);
|
||||
copy->role = port->role;
|
||||
copy->profiles = dm_list_new();
|
||||
|
||||
DM_LIST_FOREACH(i, port->profiles)
|
||||
dm_list_push_back(copy->profiles, config_profile_dup(i->data));
|
||||
|
||||
if (port->port_type == DM_CONFIG_TYPE_DEVICE_PORT) {
|
||||
copy->type = port->type;
|
||||
copy->address = pa_xstrdup(port->address);
|
||||
}
|
||||
|
||||
if (port->port_type == DM_CONFIG_TYPE_MIX_PORT) {
|
||||
copy->flags = port->flags;
|
||||
copy->max_open_count = port->max_open_count;
|
||||
copy->max_active_count = port->max_active_count;
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static dm_config_route *config_route_dup(const dm_config_route *route, dm_list *ports) {
|
||||
dm_config_route *copy = pa_xnew0(dm_config_route, 1);
|
||||
dm_config_port *port_copy, *port;
|
||||
void *state, *state2;
|
||||
|
||||
copy->type = route->type;
|
||||
copy->sources = dm_list_new();
|
||||
|
||||
DM_LIST_FOREACH_DATA(port, route->sources, state) {
|
||||
DM_LIST_FOREACH_DATA(port_copy, ports, state2) {
|
||||
if (dm_config_port_equal(port, port_copy)) {
|
||||
dm_list_push_back(copy->sources, port_copy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DM_LIST_FOREACH_DATA(port_copy, ports, state) {
|
||||
if (dm_config_port_equal(port_copy, route->sink)) {
|
||||
copy->sink = port_copy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static dm_config_module *config_module_dup(const dm_config_module *module) {
|
||||
dm_config_module *copy = pa_xnew0(dm_config_module, 1);
|
||||
dm_config_port *device_port, *attached_device, *mix_port;
|
||||
dm_config_route *route;
|
||||
void *state, *state2;
|
||||
|
||||
copy = pa_xnew0(dm_config_module, 1);
|
||||
copy->name = pa_xstrdup(module->name);
|
||||
copy->version_major = module->version_major;
|
||||
copy->version_minor = module->version_minor;
|
||||
copy->attached_devices = dm_list_new();
|
||||
copy->default_output_device = NULL;
|
||||
copy->mix_ports = dm_list_new();
|
||||
copy->device_ports = dm_list_new();
|
||||
copy->ports = dm_list_new();
|
||||
copy->routes = dm_list_new();
|
||||
|
||||
DM_LIST_FOREACH_DATA(device_port, module->device_ports, state) {
|
||||
dm_config_port *device_port_copy = config_port_dup(device_port, copy);
|
||||
dm_list_push_back(copy->device_ports, device_port_copy);
|
||||
dm_list_push_back(copy->ports, device_port_copy);
|
||||
if (module->default_output_device == device_port)
|
||||
copy->default_output_device = device_port_copy;
|
||||
DM_LIST_FOREACH_DATA(attached_device, module->attached_devices, state2) {
|
||||
if (attached_device == device_port) {
|
||||
dm_list_push_back(copy->attached_devices, device_port_copy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DM_LIST_FOREACH_DATA(mix_port, module->mix_ports, state) {
|
||||
dm_config_port *mix_port_copy = config_port_dup(mix_port, copy);
|
||||
dm_list_push_back(copy->mix_ports, mix_port_copy);
|
||||
dm_list_push_back(copy->ports, mix_port_copy);
|
||||
}
|
||||
|
||||
DM_LIST_FOREACH_DATA(route, module->routes, state)
|
||||
dm_list_push_back(copy->routes, config_route_dup(route, copy->ports));
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
dm_config_device *dm_config_dup(const dm_config_device *config) {
|
||||
dm_config_device *copy;
|
||||
dm_config_module *module;
|
||||
void *state;
|
||||
|
||||
pa_assert(config);
|
||||
|
||||
config_copy = pa_xnew0(pa_droid_config_audio, 1);
|
||||
copy = pa_xnew0(dm_config_device, 1);
|
||||
copy->global_config = dm_list_new();
|
||||
copy->modules = dm_list_new();
|
||||
|
||||
if (config->global_config)
|
||||
config_copy->global_config = pa_xmemdup(config->global_config, sizeof(*config->global_config));
|
||||
if (config->global_config) {
|
||||
dm_config_global *global, *global_copy;
|
||||
|
||||
SLLIST_FOREACH(module, config->hw_modules) {
|
||||
module_copy = pa_droid_config_hw_module_new(config_copy, module->name);
|
||||
if (module->global_config)
|
||||
module_copy->global_config = pa_xmemdup(module->global_config, sizeof(*module->global_config));
|
||||
|
||||
SLLIST_FOREACH(device, module->outputs) {
|
||||
device_copy = pa_xmemdup(device, sizeof(*device));
|
||||
device_copy->module = module_copy;
|
||||
device_copy->name = pa_xstrdup(device->name);
|
||||
SLLIST_APPEND(pa_droid_config_device, module_copy->outputs, device_copy);
|
||||
DM_LIST_FOREACH_DATA(global, config->global_config, state) {
|
||||
global_copy = pa_xnew0(dm_config_global, 1);
|
||||
global_copy->key = pa_xstrdup(global->key);
|
||||
global_copy->value = pa_xstrdup(global->value);
|
||||
dm_list_push_back(copy->global_config, global_copy);
|
||||
}
|
||||
}
|
||||
|
||||
SLLIST_FOREACH(device, module->inputs) {
|
||||
device_copy = pa_xmemdup(device, sizeof(*device));
|
||||
device_copy->module = module_copy;
|
||||
device_copy->name = pa_xstrdup(device->name);
|
||||
SLLIST_APPEND(pa_droid_config_device, module_copy->inputs, device_copy);
|
||||
DM_LIST_FOREACH_DATA(module, config->modules, state)
|
||||
dm_list_push_back(copy->modules, config_module_dup(module));
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
SLLIST_APPEND(pa_droid_config_hw_module, config_copy->hw_modules, module_copy);
|
||||
}
|
||||
|
||||
return config_copy;
|
||||
}
|
||||
|
||||
pa_droid_config_audio *pa_parse_droid_audio_config(const char *filename) {
|
||||
const char *suffix;
|
||||
|
||||
pa_assert(filename);
|
||||
|
||||
if ((suffix = rindex(filename, '.'))) {
|
||||
if (strlen(suffix) == 4 && pa_streq(suffix, ".xml"))
|
||||
dm_config_device *pa_parse_droid_audio_config(const char *filename) {
|
||||
return pa_parse_droid_audio_config_xml(filename);
|
||||
else if (strlen(suffix) == 5 && pa_streq(suffix, ".conf"))
|
||||
return pa_parse_droid_audio_config_legacy(filename);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
static void config_global_free(void *data) {
|
||||
dm_config_global *global = data;
|
||||
|
||||
pa_xfree(global->key);
|
||||
pa_xfree(global->value);
|
||||
pa_xfree(global);
|
||||
}
|
||||
|
||||
void pa_droid_config_free(pa_droid_config_audio *config) {
|
||||
pa_droid_config_hw_module *module;
|
||||
pa_droid_config_device *device;
|
||||
static void config_profile_free(void *data) {
|
||||
dm_config_profile *profile = data;
|
||||
|
||||
pa_xfree(profile->name);
|
||||
pa_xfree(profile);
|
||||
}
|
||||
|
||||
static void config_port_free(void *data) {
|
||||
dm_config_port *port = data;
|
||||
|
||||
pa_xfree(port->name);
|
||||
pa_xfree(port->address);
|
||||
dm_list_free(port->profiles, config_profile_free);
|
||||
pa_xfree(port);
|
||||
}
|
||||
|
||||
static void config_route_free(void *data) {
|
||||
dm_config_route *route = data;
|
||||
|
||||
dm_list_free(route->sources, NULL);
|
||||
pa_xfree(route);
|
||||
}
|
||||
|
||||
static void config_module_free(void *data) {
|
||||
dm_config_module *module = data;
|
||||
|
||||
pa_xfree(module->name);
|
||||
dm_list_free(module->attached_devices, NULL);
|
||||
dm_list_free(module->ports, config_port_free);
|
||||
dm_list_free(module->device_ports, NULL);
|
||||
dm_list_free(module->mix_ports, NULL);
|
||||
dm_list_free(module->routes, config_route_free);
|
||||
pa_xfree(module);
|
||||
}
|
||||
|
||||
void dm_config_free(dm_config_device *config) {
|
||||
if (!config)
|
||||
return;
|
||||
|
||||
while (config->hw_modules) {
|
||||
SLLIST_STEAL_FIRST(module, config->hw_modules);
|
||||
|
||||
while (module->outputs) {
|
||||
SLLIST_STEAL_FIRST(device, module->outputs);
|
||||
pa_droid_config_device_free(device);
|
||||
}
|
||||
|
||||
while (module->inputs) {
|
||||
SLLIST_STEAL_FIRST(device, module->inputs);
|
||||
pa_droid_config_device_free(device);
|
||||
}
|
||||
|
||||
pa_droid_config_hw_module_free(module);
|
||||
}
|
||||
|
||||
pa_xfree(config->global_config);
|
||||
dm_list_free(config->global_config, config_global_free);
|
||||
dm_list_free(config->modules, config_module_free);
|
||||
pa_xfree(config);
|
||||
}
|
||||
|
||||
const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_config_audio *config, const char* module_id) {
|
||||
pa_droid_config_hw_module *module;
|
||||
dm_config_module *dm_config_find_module(dm_config_device *config, const char* module_id) {
|
||||
dm_config_module *module;
|
||||
void *state;
|
||||
|
||||
pa_assert(config);
|
||||
pa_assert(module_id);
|
||||
|
||||
SLLIST_FOREACH(module, config->hw_modules) {
|
||||
DM_LIST_FOREACH_DATA(module, config->modules, state) {
|
||||
if (pa_streq(module_id, module->name))
|
||||
return module;
|
||||
}
|
||||
|
|
@ -199,71 +294,73 @@ const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_conf
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const pa_droid_config_device *find_device(const pa_droid_config_hw_module *module, bool output, const char* device_name) {
|
||||
pa_droid_config_device *device;
|
||||
dm_config_port *dm_config_find_port(dm_config_module *module, const char* name) {
|
||||
dm_config_port *port;
|
||||
void *state;
|
||||
|
||||
pa_assert(module);
|
||||
pa_assert(device_name);
|
||||
pa_assert(name);
|
||||
|
||||
SLLIST_FOREACH(device, output ? module->outputs : module->inputs) {
|
||||
if (pa_streq(device_name, device->name))
|
||||
return device;
|
||||
DM_LIST_FOREACH_DATA(port, module->ports, state) {
|
||||
if (pa_streq(name, port->name))
|
||||
return port;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const pa_droid_config_device *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char* output_name) {
|
||||
return find_device(module, true, output_name);
|
||||
}
|
||||
|
||||
const pa_droid_config_device *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char* input_name) {
|
||||
return find_device(module, false, input_name);
|
||||
}
|
||||
|
||||
pa_droid_config_hw_module *pa_droid_config_hw_module_new(const pa_droid_config_audio *config, const char *name) {
|
||||
pa_droid_config_hw_module *hw_module;
|
||||
|
||||
pa_assert(config);
|
||||
pa_assert(name);
|
||||
|
||||
hw_module = pa_xnew0(pa_droid_config_hw_module, 1);
|
||||
hw_module->config = config;
|
||||
hw_module->name = pa_xstrndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN);
|
||||
|
||||
return hw_module;
|
||||
}
|
||||
|
||||
void pa_droid_config_hw_module_free(pa_droid_config_hw_module *hw_module) {
|
||||
if (!hw_module)
|
||||
return;
|
||||
|
||||
pa_xfree(hw_module->name);
|
||||
pa_xfree(hw_module->global_config);
|
||||
pa_xfree(hw_module);
|
||||
}
|
||||
|
||||
pa_droid_config_device *pa_droid_config_device_new(const pa_droid_config_hw_module *module,
|
||||
pa_direction_t direction,
|
||||
const char *name) {
|
||||
pa_droid_config_device *device;
|
||||
|
||||
dm_config_port *dm_config_default_output_device(dm_config_module *module) {
|
||||
pa_assert(module);
|
||||
pa_assert(direction == PA_DIRECTION_OUTPUT || direction == PA_DIRECTION_INPUT);
|
||||
pa_assert(name);
|
||||
|
||||
device = pa_xnew0(pa_droid_config_device, 1);
|
||||
device->module = module;
|
||||
device->direction = direction;
|
||||
device->name = pa_replace(name, " ", "_");
|
||||
|
||||
return device;
|
||||
if (module->default_output_device)
|
||||
return module->default_output_device;
|
||||
else {
|
||||
pa_log("Module %s doesn't have default output device.", module->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void pa_droid_config_device_free(pa_droid_config_device *device) {
|
||||
if (!device)
|
||||
return;
|
||||
char *dm_config_escape_string(const char *string) {
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
pa_xfree(device->name);
|
||||
pa_xfree(device);
|
||||
/* Just replace whitespace with underscores for now. */
|
||||
|
||||
return pa_replace(string, " ", "_");
|
||||
}
|
||||
|
||||
dm_config_port *dm_config_find_device_port(dm_config_port *port, audio_devices_t device) {
|
||||
dm_config_port *device_port;
|
||||
void *state;
|
||||
|
||||
pa_assert(port);
|
||||
|
||||
DM_LIST_FOREACH_DATA(device_port, port->module->device_ports, state) {
|
||||
if (device_port->type == device)
|
||||
return device_port;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool dm_config_port_equal(const dm_config_port *a, const dm_config_port *b) {
|
||||
if ((!a && b) || (a && !b))
|
||||
return false;
|
||||
|
||||
else if (!a && !b)
|
||||
return true;
|
||||
|
||||
return (pa_streq(a->name, b->name) && a->type == b->type);
|
||||
}
|
||||
|
||||
dm_config_port *dm_config_find_mix_port(dm_config_module *module, const char *name) {
|
||||
dm_config_port *mix_port = NULL;
|
||||
void *state;
|
||||
|
||||
DM_LIST_FOREACH_DATA(mix_port, module->mix_ports, state) {
|
||||
if (pa_streq(mix_port->name, name))
|
||||
return mix_port;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define foodroidconfigfoo
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Jolla Ltd.
|
||||
* Copyright (C) 2018-2022 Jolla Ltd.
|
||||
*
|
||||
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
|
||||
*
|
||||
|
|
@ -30,75 +30,106 @@
|
|||
#include <android-config.h>
|
||||
#include <hardware/audio.h>
|
||||
|
||||
#include <droid/sllist.h>
|
||||
#include <droid/version.h>
|
||||
|
||||
typedef struct pa_droid_config_audio pa_droid_config_audio;
|
||||
typedef struct pa_droid_config_hw_module pa_droid_config_hw_module;
|
||||
|
||||
#define AUDIO_MAX_SAMPLING_RATES (32)
|
||||
#define AUDIO_MAX_CHANNEL_MASKS (32)
|
||||
|
||||
typedef struct pa_droid_config_global {
|
||||
uint32_t audio_hal_version;
|
||||
audio_devices_t attached_output_devices;
|
||||
audio_devices_t default_output_device;
|
||||
audio_devices_t attached_input_devices;
|
||||
} pa_droid_config_global;
|
||||
typedef struct dm_config_global dm_config_global;
|
||||
typedef struct dm_config_port dm_config_port;
|
||||
typedef struct dm_config_route dm_config_route;
|
||||
typedef struct dm_config_module dm_config_module;
|
||||
typedef struct dm_config_device dm_config_device;
|
||||
typedef struct dm_config_profile dm_config_profile;
|
||||
|
||||
typedef struct pa_droid_config_device {
|
||||
const pa_droid_config_hw_module *module;
|
||||
|
||||
char *name;
|
||||
uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES]; /* (uint32_t) -1 -> dynamic */
|
||||
audio_channel_mask_t channel_masks; /* 0 -> dynamic */
|
||||
audio_format_t formats; /* 0 -> dynamic */
|
||||
audio_devices_t devices;
|
||||
/* Instead of using audio_output_flags_t and audio_input_flags_t
|
||||
* unify the flags as uint32_t so that we can have single struct for both
|
||||
* output and input configurations.
|
||||
* audio_input_flags_t was introduced in APIs 2 & 3, depending on adaptation,
|
||||
* so having input flags as uint32_t is simpler from input implementation
|
||||
* point of view as well. */
|
||||
uint32_t flags;
|
||||
pa_direction_t direction;
|
||||
|
||||
struct pa_droid_config_device *next;
|
||||
} pa_droid_config_device;
|
||||
|
||||
struct pa_droid_config_hw_module {
|
||||
const pa_droid_config_audio *config;
|
||||
|
||||
char *name;
|
||||
/* If global config is not defined for module, use root global config. */
|
||||
pa_droid_config_global *global_config;
|
||||
pa_droid_config_device *outputs;
|
||||
pa_droid_config_device *inputs;
|
||||
|
||||
struct pa_droid_config_hw_module *next;
|
||||
struct dm_config_global {
|
||||
char *key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
struct pa_droid_config_audio {
|
||||
pa_droid_config_global *global_config;
|
||||
pa_droid_config_hw_module *hw_modules;
|
||||
struct dm_config_profile {
|
||||
char *name;
|
||||
audio_format_t format; /* 0 -> dynamic TODO check that this is still true */
|
||||
uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES]; /* sampling_rates[0] == 0 -> dynamic, otherwise 0 terminates list */
|
||||
audio_channel_mask_t channel_masks[AUDIO_MAX_CHANNEL_MASKS]; /* channel_masks[0] == 0 -> dynamic */
|
||||
};
|
||||
|
||||
typedef enum dm_config_role {
|
||||
DM_CONFIG_ROLE_SINK,
|
||||
DM_CONFIG_ROLE_SOURCE,
|
||||
} dm_config_role_t;
|
||||
|
||||
typedef enum dm_config_type {
|
||||
DM_CONFIG_TYPE_MIX,
|
||||
DM_CONFIG_TYPE_DEVICE_PORT,
|
||||
DM_CONFIG_TYPE_MIX_PORT,
|
||||
} dm_config_type_t;
|
||||
|
||||
struct dm_config_port {
|
||||
dm_config_module *module;
|
||||
|
||||
/* common values */
|
||||
|
||||
dm_config_type_t port_type; /* either mixPort or devicePort */
|
||||
char *name;
|
||||
dm_config_role_t role;
|
||||
dm_list *profiles; /* dm_config_profile* */
|
||||
|
||||
/* devicePort specific values */
|
||||
|
||||
audio_devices_t type;
|
||||
char *address;
|
||||
|
||||
/* mixPort specific values */
|
||||
|
||||
uint32_t flags; /* audio_output_flag_t or audio_input_flag_t */
|
||||
int max_open_count; /* 0 == not defined */
|
||||
int max_active_count; /* 0 == not defined */
|
||||
};
|
||||
|
||||
struct dm_config_route {
|
||||
dm_config_type_t type;
|
||||
dm_config_port *sink;
|
||||
dm_list *sources; /* dm_config_port* */
|
||||
};
|
||||
|
||||
struct dm_config_module {
|
||||
dm_config_device *config;
|
||||
|
||||
char *name;
|
||||
int version_major;
|
||||
int version_minor;
|
||||
|
||||
dm_list *attached_devices; /* dm_config_port* owned by device_ports list below */
|
||||
dm_config_port *default_output_device; /* owned by device_ports list below */
|
||||
dm_list *ports; /* dm_config_port* - for convenience port types are filtered to two lists below: */
|
||||
dm_list *mix_ports; /* dm_config_port* */
|
||||
dm_list *device_ports; /* dm_config_port* */
|
||||
dm_list *routes; /* dm_config_route* */
|
||||
};
|
||||
|
||||
struct dm_config_device {
|
||||
dm_list *global_config; /* dm_config_global* */
|
||||
dm_list *modules; /* dm_config_module* */
|
||||
};
|
||||
|
||||
|
||||
/* Config parser */
|
||||
pa_droid_config_audio *pa_droid_config_load(pa_modargs *ma);
|
||||
pa_droid_config_audio *pa_droid_config_dup(const pa_droid_config_audio *config);
|
||||
void pa_droid_config_free(pa_droid_config_audio *config);
|
||||
pa_droid_config_audio *pa_parse_droid_audio_config_legacy(const char *filename);
|
||||
pa_droid_config_audio *pa_parse_droid_audio_config_xml(const char *filename);
|
||||
dm_config_device *dm_config_load(pa_modargs *ma);
|
||||
dm_config_device *dm_config_dup(const dm_config_device *config);
|
||||
void dm_config_free(dm_config_device *config);
|
||||
/* autodetect config type from filename and parse */
|
||||
pa_droid_config_audio *pa_parse_droid_audio_config(const char *filename);
|
||||
dm_config_device *pa_parse_droid_audio_config(const char *filename);
|
||||
|
||||
const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_config_audio *config, const char* module_id);
|
||||
const pa_droid_config_device *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char* output_name);
|
||||
const pa_droid_config_device *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char* input_name);
|
||||
dm_config_module *dm_config_find_module(dm_config_device *config, const char* module_id);
|
||||
dm_config_port *dm_config_find_port(dm_config_module *module, const char* name);
|
||||
dm_config_port *dm_config_default_output_device(dm_config_module *module);
|
||||
dm_config_port *dm_config_find_device_port(dm_config_port *port, audio_devices_t device);
|
||||
char *dm_config_escape_string(const char *string);
|
||||
|
||||
pa_droid_config_hw_module *pa_droid_config_hw_module_new(const pa_droid_config_audio *config, const char *name);
|
||||
void pa_droid_config_hw_module_free(pa_droid_config_hw_module *hw_module);
|
||||
pa_droid_config_device *pa_droid_config_device_new(const pa_droid_config_hw_module *module,
|
||||
pa_direction_t direction,
|
||||
const char *name);
|
||||
void pa_droid_config_device_free(pa_droid_config_device *device);
|
||||
bool dm_config_port_equal(const dm_config_port *a, const dm_config_port *b);
|
||||
|
||||
dm_config_port *dm_config_find_mix_port(dm_config_module *module, const char *name);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue