89
89
const string ECA_CHAINSETUP::default_bmode_rt_const = "1024,true,50,true,100000,true";
90
90
const string ECA_CHAINSETUP::default_bmode_rtlowlatency_const = "256,true,50,true,100000,false";
92
static void priv_erase_object(std::vector<AUDIO_IO*>* vec, const AUDIO_IO* obj);
93
95
* Construct from a vector of options.
1311
* Helper function used by remove_audio_input() and remove_audio_output().
1313
* Helper function used by remove_audio_object().
1313
void ECA_CHAINSETUP::remove_audio_object_helper(AUDIO_IO* aio)
1315
void ECA_CHAINSETUP::remove_audio_object_proxy(AUDIO_IO* aio)
1315
1317
AUDIO_IO_DB_CLIENT* p = dynamic_cast<AUDIO_IO_DB_CLIENT*>(aio);
1317
1319
/* a proxied object */
1318
// aobj_garbage_rep.push_back(aio);
1320
1321
--db_clients_rep;
1326
* Helper function used bu remove_audio_object() to remove input
1327
* and output loop devices.
1329
void ECA_CHAINSETUP::remove_audio_object_loop(const string& label, AUDIO_IO* aio, int dir)
1331
int rdir = (dir == cs_dir_input ? cs_dir_output : cs_dir_input);
1333
/* loop devices are registered simultaneously to both input
1334
* and output object vectors, so they have to be removed
1335
* from both, but deleted only once */
1337
remove_audio_object_impl(label, rdir, false);
1339
/* we also need to remove the loop device from
1340
* the loop_map table */
1342
map<int,LOOP_DEVICE*>::iterator iter = loop_map.begin();
1343
while(iter != loop_map.end()) {
1344
if (iter->second == aio) {
1345
loop_map.erase(iter);
1325
1353
* Adds a new input object and attaches it to selected chains.
1405
1433
DBC_ENSURE(outputs.size() == outputs_direct_rep.size());
1437
* Erases an element matching 'obj' from 'vec'. At most one element
1438
* is removed. The function does not delete the referred object, just
1439
* removes it from the vector.
1441
static void priv_erase_object(std::vector<AUDIO_IO*>* vec, const AUDIO_IO* obj)
1443
vector<AUDIO_IO*>::iterator p = vec->begin();
1444
while(p != vec->end()) {
1454
* Removes the labeled audio object from this chainsetup.
1456
* @pre is_enabled() != true
1458
void ECA_CHAINSETUP::remove_audio_object_impl(const string& label, int dir, bool destroy)
1461
DBC_REQUIRE(is_enabled() != true);
1464
vector<AUDIO_IO*> *objs = (dir == cs_dir_input ? &inputs : &outputs);
1465
vector<AUDIO_IO*> *objs_dir = (dir == cs_dir_input ? &inputs_direct_rep : &outputs_direct_rep);
1466
DBC_DECLARE(size_t oldsize = objs->size());
1467
AUDIO_IO *obj_to_remove = 0, *obj_dir_to_remove = NULL;
1468
int remove_index = -1;
1471
* - objs and objs_dir vectors are always of the same size
1472
* - for non-proxied objects 'objs[n] == objs_dir[n]' for all n
1475
for(size_t n = 0; n < objs->size(); n++) {
1476
if ((*objs)[n]->label() == label) {
1477
obj_to_remove = (*objs)[n];
1478
obj_dir_to_remove = (*objs_dir)[n];
1479
remove_index = static_cast<int>(n);
1483
if (obj_to_remove) {
1484
DBC_CHECK(remove_index >= 0);
1485
ECA_LOG_MSG(ECA_LOGGER::user_objects, "Removing object " + obj_to_remove->label() + ".");
1487
/* disconnect object from chains */
1488
vector<CHAIN*>::iterator q = chains.begin();
1489
while(q != chains.end()) {
1490
if (dir == cs_dir_input) {
1491
if ((*q)->connected_input() == remove_index) {
1492
(*q)->disconnect_input();
1496
if ((*q)->connected_output() == remove_index) {
1497
(*q)->disconnect_output();
1503
/* unregister from manager (always the objs_dir object) */
1504
unregister_audio_object_from_manager((*objs_dir)[remove_index]);
1506
/* delete proxy object if any */
1507
if (obj_to_remove != obj_dir_to_remove) {
1508
remove_audio_object_proxy(obj_dir_to_remove);
1511
priv_erase_object(objs, obj_to_remove);
1512
priv_erase_object(objs_dir, obj_dir_to_remove);
1514
LOOP_DEVICE* loop_dev = dynamic_cast<LOOP_DEVICE*>(obj_dir_to_remove);
1515
if (loop_dev != 0 && destroy == true) {
1516
/* note: destroy must be true to limit recursion */
1517
remove_audio_object_loop(label, obj_dir_to_remove, dir);
1520
/* finally actually delete the object */
1521
if (destroy == true)
1522
delete obj_dir_to_remove;
1526
DBC_ENSURE(objs->size() == objs_dir->size());
1527
DBC_ENSURE(oldsize == objs->size() + 1);
1410
1532
* Removes the labeled audio input from this chainsetup.
1418
1540
DBC_DECLARE(size_t oldsize = inputs.size());
1421
for(size_t n = 0; n < inputs.size(); n++) {
1422
if (inputs[n]->label() == label) {
1423
ECA_LOG_MSG(ECA_LOGGER::user_objects, "Removing input " + label + ".");
1425
remove_audio_object_helper(inputs[n]);
1427
vector<CHAIN*>::iterator q = chains.begin();
1428
while(q != chains.end()) {
1429
if ((*q)->connected_input() == static_cast<int>(n)) (*q)->disconnect_input();
1433
unregister_audio_object_from_manager(inputs_direct_rep[n]);
1435
vector<AUDIO_IO*>::iterator p = inputs.begin();
1436
while(p != inputs.end()) {
1437
if (*p == inputs[n]) {
1444
p = inputs_direct_rep.begin();
1445
while(p != inputs_direct_rep.end()) {
1446
if (*p == inputs_direct_rep[n]) {
1448
inputs_direct_rep.erase(p);
1454
/* vectors changed; can't continue iteration */
1543
remove_audio_object_impl(label, cs_dir_input, true);
1460
1546
DBC_ENSURE(inputs.size() == inputs_direct_rep.size());
1474
1560
DBC_DECLARE(size_t oldsize = outputs.size());
1477
for(size_t n = 0; n < outputs.size(); n++) {
1478
if (outputs[n]->label() == label) {
1479
ECA_LOG_MSG(ECA_LOGGER::user_objects, "Removing output " + label + ".");
1481
remove_audio_object_helper(outputs[n]);
1483
vector<CHAIN*>::iterator q = chains.begin();
1484
while(q != chains.end()) {
1485
if ((*q)->connected_output() == static_cast<int>(n)) (*q)->disconnect_output();
1489
unregister_audio_object_from_manager(outputs_direct_rep[n]);
1491
vector<AUDIO_IO*>::iterator p = outputs.begin();
1492
while(p != outputs.end()) {
1493
if (*p == outputs[n]) {
1500
p = outputs_direct_rep.begin();
1501
while(p != outputs_direct_rep.end()) {
1502
if (*p == outputs_direct_rep[n]) {
1504
outputs_direct_rep.erase(p);
1510
/* vectors changed; can't continue iteration */
1563
remove_audio_object_impl(label, cs_dir_output, true);
1516
1566
DBC_ENSURE(outputs.size() == outputs_direct_rep.size());