1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 3 /* mallctl_bool_get(const char * name,bool expected,const char * func,int line)4 Rosegarden 5 A sequencer and musical notation editor. 6 Copyright 2000-2021 the Rosegarden development team. 7 See the AUTHORS file for more details. 8 9 This program is free software; you can redistribute it and/or 10 modify it under the terms of the GNU General Public License as 11 published by the Free Software Foundation; either version 2 of the 12 License, or (at your option) any later version. See the file 13 COPYING included with this distribution for more information. 14 */ 15 16 #define RG_MODULE_STRING "[MappedStudio]" 17 18 19 #include "MappedStudio.h" 20 #include "SoundDriver.h" 21 #include "PluginFactory.h" 22 #include "misc/Strings.h" 23 #include "misc/Debug.h" 24 25 #include <pthread.h> // for mutex 26 27 // #define DEBUG_MAPPEDSTUDIO 1 28 29 namespace Rosegarden 30 { 31 32 static pthread_mutex_t mappedObjectContainerLock; 33 34 #ifdef DEBUG_MAPPEDSTUDIO 35 static int approxLockCount = 0; 36 #endif 37 38 static inline void getLock(const char *file, int line) 39 { 40 #ifdef DEBUG_MAPPEDSTUDIO 41 std::cerr << "Acquiring MappedStudio container lock at " << file << ":" << line << ": count " << approxLockCount++ << std::endl; 42 #else 43 (void)file; (void)line; 44 #endif 45 46 pthread_mutex_lock(&mappedObjectContainerLock); 47 } 48 49 static inline void releaseLock(const char *file, int line) 50 { 51 pthread_mutex_unlock(&mappedObjectContainerLock); 52 #ifdef DEBUG_MAPPEDSTUDIO 53 54 std::cerr << "Released container lock at " << file << ":" << line << ": count " << --approxLockCount << std::endl; 55 #else 56 (void)file; (void)line; 57 #endif 58 } 59 60 #define GET_LOCK getLock(__FILE__,__LINE__) 61 #define RELEASE_LOCK releaseLock(__FILE__,__LINE__) 62 63 // These stream functions are stolen and adapted from Qt3 QVector 64 // 65 // ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. 66 // 67 QDataStream& operator>>(QDataStream& s, MappedObjectIdList& v) 68 { 69 v.clear(); 70 quint32 c; 71 s >> c; 72 v.resize(c); 73 for (quint32 i = 0; i < c; ++i) { 74 MappedObjectId t; 75 s >> t; 76 v[i] = t; 77 } 78 return s; 79 } 80 81 QDataStream& operator<<(QDataStream& s, const MappedObjectIdList& v) 82 { 83 s << (quint32)v.size(); 84 MappedObjectIdList::const_iterator it = v.begin(); 85 for ( ; it != v.end(); ++it ) 86 s << *it; 87 return s; 88 } 89 90 QDataStream& operator>>(QDataStream& s, MappedObjectPropertyList& v) 91 { 92 v.clear(); 93 quint32 c; 94 s >> c; 95 v.resize(c); 96 for (quint32 i = 0; i < c; ++i) { 97 MappedObjectProperty t; 98 s >> t; 99 v[i] = t; 100 } 101 return s; 102 } 103 104 QDataStream& operator<<(QDataStream& s, const MappedObjectPropertyList& v) 105 { 106 s << (quint32)v.size(); 107 MappedObjectPropertyList::const_iterator it = v.begin(); 108 for ( ; it != v.end(); ++it ) 109 s << *it; 110 return s; 111 } 112 113 QDataStream& operator>>(QDataStream& s, MappedObjectValueList& v) 114 { 115 v.clear(); 116 quint32 c; 117 s >> c; 118 v.resize(c); 119 for (quint32 i = 0; i < c; ++i) { 120 MappedObjectValue t; 121 s >> t; 122 v[i] = t; 123 } 124 return s; 125 } 126 127 QDataStream& operator<<(QDataStream& s, const MappedObjectValueList& v) 128 { 129 s << (quint32)v.size(); 130 MappedObjectValueList::const_iterator it = v.begin(); 131 for ( ; it != v.end(); ++it ) 132 s << *it; 133 return s; 134 } 135 136 // Define our object properties - these can be queried and set. 137 // 138 139 // General things 140 // 141 const MappedObjectProperty MappedObject::Name = "name"; 142 const MappedObjectProperty MappedObject::Instrument = "instrument"; 143 const MappedObjectProperty MappedObject::Position = "position"; 144 145 const MappedObjectProperty MappedConnectableObject::ConnectionsIn = "connectionsIn"; 146 const MappedObjectProperty MappedConnectableObject::ConnectionsOut = "connectionsOut"; 147 148 const MappedObjectProperty MappedAudioFader::Channels = "channels"; 149 const MappedObjectProperty MappedAudioFader::FaderLevel = "faderLevel"; 150 const MappedObjectProperty MappedAudioFader::FaderRecordLevel = "faderRecordLevel"; 151 const MappedObjectProperty MappedAudioFader::Pan = "pan"; 152 const MappedObjectProperty MappedAudioFader::InputChannel = "inputChannel"; 153 154 const MappedObjectProperty MappedAudioBuss::BussId = "bussId"; 155 const MappedObjectProperty MappedAudioBuss::Level = "level"; 156 const MappedObjectProperty MappedAudioBuss::Pan = "pan"; 157 158 const MappedObjectProperty MappedAudioInput::InputNumber = "inputNumber"; 159 160 const MappedObjectProperty MappedPluginSlot::Identifier = "identifier"; 161 const MappedObjectProperty MappedPluginSlot::PluginName = "pluginname"; 162 const MappedObjectProperty MappedPluginSlot::Label = "label"; 163 const MappedObjectProperty MappedPluginSlot::Author = "author"; 164 const MappedObjectProperty MappedPluginSlot::Copyright = "copyright"; 165 const MappedObjectProperty MappedPluginSlot::Category = "category"; 166 const MappedObjectProperty MappedPluginSlot::PortCount = "portcount"; 167 const MappedObjectProperty MappedPluginSlot::Ports = "ports"; 168 const MappedObjectProperty MappedPluginSlot::Instrument = "instrument"; 169 const MappedObjectProperty MappedPluginSlot::Position = "position"; 170 const MappedObjectProperty MappedPluginSlot::Bypassed = "bypassed"; 171 const MappedObjectProperty MappedPluginSlot::Programs = "programs"; 172 const MappedObjectProperty MappedPluginSlot::Program = "program"; 173 const MappedObjectProperty MappedPluginSlot::Configuration = "configuration"; 174 175 const MappedObjectProperty MappedPluginPort::PortNumber = "portnumber"; 176 const MappedObjectProperty MappedPluginPort::Name = "name"; 177 const MappedObjectProperty MappedPluginPort::Minimum = "minimum"; 178 const MappedObjectProperty MappedPluginPort::Maximum = "maximum"; 179 const MappedObjectProperty MappedPluginPort::Default = "default"; 180 const MappedObjectProperty MappedPluginPort::DisplayHint = "displayhint"; 181 const MappedObjectProperty MappedPluginPort::Value = "value"; 182 183 // --------- MappedObject --------- 184 // 185 186 void 187 MappedObject::addChild(MappedObject *object) 188 { 189 std::vector<MappedObject*>::iterator it = m_children.begin(); 190 for (; it != m_children.end(); ++it) 191 if ((*it) == object) 192 return ; 193 194 m_children.push_back(object); 195 } 196 197 void 198 MappedObject::removeChild(MappedObject *object) 199 { 200 std::vector<MappedObject*>::iterator it = m_children.begin(); 201 for (; it != m_children.end(); ++it) { 202 if ((*it) == object) { 203 m_children.erase(it); 204 return ; 205 } 206 } 207 } 208 209 // Return all child ids 210 // 211 MappedObjectPropertyList 212 MappedObject::getChildren() 213 { 214 MappedObjectPropertyList list; 215 std::vector<MappedObject*>::iterator it = m_children.begin(); 216 for (; it != m_children.end(); ++it) 217 list.push_back(QString("%1").arg((*it)->getId())); 218 219 return list; 220 } 221 222 223 // Return all child ids of a certain type 224 // 225 MappedObjectPropertyList 226 MappedObject::getChildren(MappedObjectType type) 227 { 228 MappedObjectPropertyList list; 229 std::vector<MappedObject*>::iterator it = m_children.begin(); 230 for (; it != m_children.end(); ++it) { 231 if ((*it)->getType() == type) 232 list.push_back(QString("%1").arg((*it)->getId())); 233 } 234 235 return list; 236 } 237 238 void 239 MappedObject::destroyChildren() 240 { 241 // remove references from the studio as well as from the object 242 MappedObject *studioObject = getParent(); 243 while (!dynamic_cast<MappedStudio*>(studioObject)) 244 studioObject = studioObject->getParent(); 245 246 // see note in destroy() below 247 248 std::vector<MappedObject *> children = m_children; 249 m_children.clear(); 250 251 std::vector<MappedObject *>::iterator it = children.begin(); 252 for (; it != children.end(); ++it) 253 (*it)->destroy(); // remove from studio and destroy 254 } 255 256 // Destroy this object and remove it from the studio and 257 // do the same for all its children. 258 // 259 void 260 MappedObject::destroy() 261 { 262 MappedObject *studioObject = getParent(); 263 while (!dynamic_cast<MappedStudio*>(studioObject)) 264 studioObject = studioObject->getParent(); 265 266 MappedStudio *studio = dynamic_cast<MappedStudio*>(studioObject); 267 268 // The destroy method on each child calls studio->clearObject, 269 // which calls back on the parent (in this case us) to remove the 270 // child. (That's necessary for the case of destroying a plugin, 271 // where we need to remove it from its plugin manager -- etc.) So 272 // we don't want to be iterating over m_children here, as it will 273 // change from under us. 274 275 std::vector<MappedObject *> children = m_children; 276 m_children.clear(); 277 278 std::vector<MappedObject *>::iterator it = children.begin(); 279 for (; it != children.end(); ++it) { 280 (*it)->destroy(); 281 } 282 283 (void)studio->clearObject(m_id); 284 delete this; 285 } 286 287 288 // ------- MappedStudio ------- 289 // 290 291 MappedStudio::MappedStudio() : 292 MappedObject(nullptr, 293 "MappedStudio", 294 Studio, 295 0), 296 m_runningObjectId(1) 297 { 298 pthread_mutexattr_t attr; 299 pthread_mutexattr_init(&attr); 300 #ifdef HAVE_PTHREAD_MUTEX_RECURSIVE 301 302 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 303 #else 304 #if defined(PTHREAD_MUTEX_RECURSIVE) || defined(__FreeBSD__) 305 306 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 307 #else 308 309 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); 310 #endif 311 #endif 312 313 pthread_mutex_init(&mappedObjectContainerLock, &attr); 314 } 315 316 MappedStudio::~MappedStudio() 317 { 318 #ifdef DEBUG_MAPPEDSTUDIO 319 std::cout << "MappedStudio::~MappedStudio" << std::endl; 320 #endif 321 322 clear(); 323 } 324 325 326 // Object factory 327 // 328 MappedObject* 329 MappedStudio::createObject(MappedObjectType type) 330 { 331 GET_LOCK; 332 333 MappedObject *mO = nullptr; 334 335 // Ensure we've got an empty slot 336 // 337 while (getObjectById(m_runningObjectId)) m_runningObjectId++; 338 339 mO = createObject(type, m_runningObjectId); 340 341 // If we've got a new object increase the running id 342 // 343 if (mO) m_runningObjectId++; 344 345 RELEASE_LOCK; 346 return mO; 347 } 348 349 MappedObject* 350 MappedStudio::createObject(MappedObjectType type, 351 MappedObjectId id) 352 { 353 GET_LOCK; 354 355 // fail if the object already exists and it's not zero 356 if (id != 0 && getObjectById(id)) { 357 RELEASE_LOCK; 358 return nullptr; 359 } 360 361 MappedObject *mO = nullptr; 362 363 if (type == MappedObject::AudioFader) { 364 mO = new MappedAudioFader(this, 365 id, 366 2); // channels 367 368 // push to the studio's child stack 369 addChild(mO); 370 } else if (type == MappedObject::AudioBuss) { 371 mO = new MappedAudioBuss(this, 372 id); 373 374 // push to the studio's child stack 375 addChild(mO); 376 } else if (type == MappedObject::AudioInput) { 377 mO = new MappedAudioInput(this, 378 id); 379 380 // push to the studio's child stack 381 addChild(mO); 382 } else if (type == MappedObject::PluginSlot) { 383 mO = new MappedPluginSlot(this, 384 id); 385 addChild(mO); 386 } else if (type == MappedObject::PluginPort) { 387 mO = new MappedPluginPort(this, 388 id); 389 // reset the port's parent after creation outside this method 390 } 391 392 // Insert 393 if (mO) { 394 #ifdef DEBUG_MAPPEDSTUDIO 395 std::cerr << "Adding object " << id << " to category " << type << std::endl; 396 #endif 397 398 m_objects[type][id] = mO; 399 } 400 401 RELEASE_LOCK; 402 403 return mO; 404 } 405 406 MappedObject* 407 MappedStudio::getObjectOfType(MappedObjectType type) 408 { 409 MappedObject *rv = nullptr; 410 411 GET_LOCK; 412 413 MappedObjectCategory &category = m_objects[type]; 414 if (!category.empty()) 415 rv = category.begin()->second; 416 417 RELEASE_LOCK; 418 419 return rv; 420 } 421 422 std::vector<MappedObject *> 423 MappedStudio::getObjectsOfType(MappedObjectType type) 424 { 425 std::vector<MappedObject *> rv; 426 427 GET_LOCK; 428 429 MappedObjectCategory &category = m_objects[type]; 430 431 for (MappedObjectCategory::iterator i = category.begin(); 432 i != category.end(); ++i) { 433 rv.push_back(i->second); 434 } 435 436 RELEASE_LOCK; 437 438 return rv; 439 } 440 441 unsigned int 442 MappedStudio::getObjectCount(MappedObjectType type) 443 { 444 unsigned int count = 0; 445 446 GET_LOCK; 447 448 MappedObjectCategory &category = m_objects[type]; 449 count = (unsigned int)category.size(); 450 451 RELEASE_LOCK; 452 453 return count; 454 } 455 456 457 bool 458 MappedStudio::destroyObject(MappedObjectId id) 459 { 460 GET_LOCK; 461 462 MappedObject *obj = getObjectById(id); 463 464 bool rv = false; 465 466 if (obj) { 467 obj->destroy(); 468 rv = true; 469 } 470 471 RELEASE_LOCK; 472 473 return rv; 474 } 475 476 bool 477 MappedStudio::connectObjects(MappedObjectId mId1, MappedObjectId mId2) 478 { 479 GET_LOCK; 480 481 bool rv = false; 482 483 // objects must exist and be of connectable types 484 MappedConnectableObject *obj1 = 485 dynamic_cast<MappedConnectableObject *>(getObjectById(mId1)); 486 MappedConnectableObject *obj2 = 487 dynamic_cast<MappedConnectableObject *>(getObjectById(mId2)); 488 489 if (obj1 && obj2) { 490 obj1->addConnection(MappedConnectableObject::Out, mId2); 491 obj2->addConnection(MappedConnectableObject::In, mId1); 492 rv = true; 493 } 494 495 RELEASE_LOCK; 496 497 return rv; 498 } 499 500 bool 501 MappedStudio::disconnectObjects(MappedObjectId mId1, MappedObjectId mId2) 502 { 503 GET_LOCK; 504 505 bool rv = false; 506 507 // objects must exist and be of connectable types 508 MappedConnectableObject *obj1 = 509 dynamic_cast<MappedConnectableObject *>(getObjectById(mId1)); 510 MappedConnectableObject *obj2 = 511 dynamic_cast<MappedConnectableObject *>(getObjectById(mId2)); 512 513 if (obj1 && obj2) { 514 obj1->removeConnection(MappedConnectableObject::Out, mId2); 515 obj2->removeConnection(MappedConnectableObject::In, mId1); 516 rv = true; 517 } 518 519 RELEASE_LOCK; 520 521 return rv; 522 } 523 524 bool 525 MappedStudio::disconnectObject(MappedObjectId mId) 526 { 527 GET_LOCK; 528 529 bool rv = false; 530 531 MappedConnectableObject *obj = 532 dynamic_cast<MappedConnectableObject *>(getObjectById(mId)); 533 534 if (obj) { 535 while (1) { 536 MappedObjectValueList list = 537 obj->getConnections(MappedConnectableObject::In); 538 if (list.empty()) 539 break; 540 MappedObjectId otherId = MappedObjectId(*list.begin()); 541 disconnectObjects(otherId, mId); 542 } 543 while (1) { 544 MappedObjectValueList list = 545 obj->getConnections(MappedConnectableObject::Out); 546 if (list.empty()) 547 break; 548 MappedObjectId otherId = MappedObjectId(*list.begin()); 549 disconnectObjects(mId, otherId); 550 } 551 } 552 553 rv = true; 554 555 RELEASE_LOCK; 556 557 return rv; 558 } 559 560 561 562 // Clear down the whole studio 563 // 564 void 565 MappedStudio::clear() 566 { 567 GET_LOCK; 568 569 for (MappedObjectMap::iterator i = m_objects.begin(); 570 i != m_objects.end(); ++i) { 571 572 for (MappedObjectCategory::iterator j = i->second.begin(); 573 j != i->second.end(); ++j) { 574 575 delete j->second; 576 } 577 } 578 579 m_objects.clear(); 580 581 // reset running object id 582 m_runningObjectId = 1; 583 584 RELEASE_LOCK; 585 } 586 587 bool 588 MappedStudio::clearObject(MappedObjectId id) 589 { 590 bool rv = false; 591 592 GET_LOCK; 593 594 for (MappedObjectMap::iterator i = m_objects.begin(); 595 i != m_objects.end(); ++i) { 596 597 MappedObjectCategory::iterator j = i->second.find(id); 598 if (j != i->second.end()) { 599 // if the object has a parent other than the studio, 600 // persuade that parent to abandon it 601 MappedObject *parent = j->second->getParent(); 602 if (parent && !dynamic_cast<MappedStudio *>(parent)) { 603 parent->removeChild(j->second); 604 } 605 606 i->second.erase(j); 607 rv = true; 608 break; 609 } 610 } 611 612 RELEASE_LOCK; 613 614 return rv; 615 } 616 617 618 MappedObjectPropertyList 619 MappedStudio::getPropertyList(const MappedObjectProperty &property) 620 { 621 MappedObjectPropertyList list; 622 623 if (property == "") { 624 // something 625 } 626 627 return list; 628 } 629 630 bool 631 MappedStudio::getProperty(const MappedObjectProperty &, 632 MappedObjectValue &) 633 { 634 return false; 635 } 636 637 MappedObject* 638 MappedStudio::getObjectById(MappedObjectId id) 639 { 640 GET_LOCK; 641 MappedObject *rv = nullptr; 642 643 for (MappedObjectMap::iterator i = m_objects.begin(); 644 i != m_objects.end(); ++i) { 645 646 MappedObjectCategory::iterator j = i->second.find(id); 647 if (j != i->second.end()) { 648 rv = j->second; 649 break; 650 } 651 } 652 653 RELEASE_LOCK; 654 return rv; 655 } 656 657 MappedObject* 658 MappedStudio::getObjectByIdAndType(MappedObjectId id, MappedObjectType type) 659 { 660 GET_LOCK; 661 MappedObject *rv = nullptr; 662 663 MappedObjectCategory &category = m_objects[type]; 664 MappedObjectCategory::iterator i = category.find(id); 665 if (i != category.end()) { 666 rv = i->second; 667 } 668 669 RELEASE_LOCK; 670 return rv; 671 } 672 673 MappedObject* 674 MappedStudio::getFirst(MappedObjectType type) 675 { 676 return getObjectOfType(type); 677 } 678 679 MappedObject* 680 MappedStudio::getNext(MappedObject *object) 681 { 682 GET_LOCK; 683 684 MappedObjectCategory &category = m_objects[object->getType()]; 685 686 bool next = false; 687 MappedObject *rv = nullptr; 688 689 for (MappedObjectCategory::iterator i = category.begin(); 690 i != category.end(); ++i) { 691 if (i->second->getId() == object->getId()) 692 next = true; 693 else if (next) { 694 rv = i->second; 695 break; 696 } 697 } 698 699 RELEASE_LOCK; 700 return rv; 701 } 702 703 void 704 MappedStudio::setProperty(const MappedObjectProperty &property, 705 MappedObjectValue /*value*/) 706 { 707 if (property == "") {} 708 709 } 710 711 MappedAudioFader * 712 MappedStudio::getAudioFader(InstrumentId id) 713 { 714 GET_LOCK; 715 716 MappedObjectCategory &category = m_objects[AudioFader]; 717 MappedAudioFader *rv = nullptr; 718 719 for (MappedObjectCategory::iterator i = category.begin(); 720 i != category.end(); ++i) { 721 MappedAudioFader *fader = dynamic_cast<MappedAudioFader *>(i->second); 722 if (fader && (fader->getInstrument() == id)) { 723 rv = fader; 724 break; 725 } 726 } 727 728 RELEASE_LOCK; 729 return rv; 730 } 731 732 MappedAudioBuss * 733 MappedStudio::getAudioBuss(int bussNumber) 734 { 735 GET_LOCK; 736 737 MappedObjectCategory &category = m_objects[AudioBuss]; 738 MappedAudioBuss *rv = nullptr; 739 740 for (MappedObjectCategory::iterator i = category.begin(); 741 i != category.end(); ++i) { 742 MappedAudioBuss *buss = dynamic_cast<MappedAudioBuss *>(i->second); 743 if (buss && (buss->getBussId() == bussNumber)) { 744 rv = buss; 745 break; 746 } 747 } 748 749 RELEASE_LOCK; 750 return rv; 751 } 752 753 MappedAudioInput * 754 MappedStudio::getAudioInput(int inputNumber) 755 { 756 GET_LOCK; 757 758 MappedObjectCategory &category = m_objects[AudioInput]; 759 MappedAudioInput *rv = nullptr; 760 761 for (MappedObjectCategory::iterator i = category.begin(); 762 i != category.end(); ++i) { 763 MappedAudioInput *input = dynamic_cast<MappedAudioInput *>(i->second); 764 if (input && (input->getInputNumber() == inputNumber)) { 765 rv = input; 766 break; 767 } 768 } 769 770 RELEASE_LOCK; 771 return rv; 772 } 773 774 775 // -------------- MappedConnectableObject ----------------- 776 // 777 // 778 MappedConnectableObject::MappedConnectableObject(MappedObject *parent, 779 const std::string &name, 780 MappedObjectType type, 781 MappedObjectId id): 782 MappedObject(parent, 783 name, 784 type, 785 id) 786 {} 787 788 MappedConnectableObject::~MappedConnectableObject() 789 {} 790 791 void 792 MappedConnectableObject::setConnections(ConnectionDirection dir, 793 MappedObjectValueList conns) 794 { 795 if (dir == In) 796 m_connectionsIn = conns; 797 else 798 m_connectionsOut = conns; 799 } 800 801 void 802 MappedConnectableObject::addConnection(ConnectionDirection dir, 803 MappedObjectId id) 804 { 805 MappedObjectValueList &list = 806 (dir == In ? m_connectionsIn : m_connectionsOut); 807 808 for (MappedObjectValueList::iterator i = list.begin(); i != list.end(); ++i) { 809 if (*i == id) { 810 return ; 811 } 812 } 813 814 list.push_back(MappedObjectValue(id)); 815 } 816 817 void 818 MappedConnectableObject::removeConnection(ConnectionDirection dir, 819 MappedObjectId id) 820 { 821 MappedObjectValueList &list = 822 (dir == In ? m_connectionsIn : m_connectionsOut); 823 824 for (MappedObjectValueList::iterator i = list.begin(); i != list.end(); ++i) { 825 if (*i == id) { 826 list.erase(i); 827 return ; 828 } 829 } 830 } 831 832 MappedObjectValueList 833 MappedConnectableObject::getConnections(ConnectionDirection dir) 834 { 835 if (dir == In) 836 return m_connectionsIn; 837 else 838 return m_connectionsOut; 839 } 840 841 842 // ------------ MappedAudioFader ---------------- 843 // 844 MappedAudioFader::MappedAudioFader(MappedObject *parent, 845 MappedObjectId id, 846 MappedObjectValue channels): 847 MappedConnectableObject(parent, 848 "MappedAudioFader", 849 AudioFader, 850 id), 851 m_level(0.0), // dB 852 m_recordLevel(0.0), 853 m_instrumentId(0), 854 m_pan(0), 855 m_channels(channels), 856 m_inputChannel(0) 857 {} 858 859 MappedAudioFader::~MappedAudioFader() 860 {} 861 862 863 MappedObjectPropertyList 864 MappedAudioFader::getPropertyList(const MappedObjectProperty &property) 865 { 866 MappedObjectPropertyList list; 867 868 if (property == "") { 869 list.push_back(MappedAudioFader::FaderLevel); 870 list.push_back(MappedAudioFader::FaderRecordLevel); 871 list.push_back(MappedObject::Instrument); 872 list.push_back(MappedAudioFader::Pan); 873 list.push_back(MappedAudioFader::Channels); 874 list.push_back(MappedConnectableObject::ConnectionsIn); 875 list.push_back(MappedConnectableObject::ConnectionsOut); 876 } else if (property == MappedObject::Instrument) { 877 list.push_back(MappedObjectProperty("%1").arg(m_instrumentId)); 878 } else if (property == MappedAudioFader::FaderLevel) { 879 list.push_back(MappedObjectProperty("%1").arg(m_level)); 880 } else if (property == MappedAudioFader::FaderRecordLevel) { 881 list.push_back(MappedObjectProperty("%1").arg(m_recordLevel)); 882 } else if (property == MappedAudioFader::Channels) { 883 list.push_back(MappedObjectProperty("%1").arg(m_channels)); 884 } else if (property == MappedAudioFader::InputChannel) { 885 list.push_back(MappedObjectProperty("%1").arg(m_inputChannel)); 886 } else if (property == MappedAudioFader::Pan) { 887 list.push_back(MappedObjectProperty("%1").arg(m_pan)); 888 } else if (property == MappedConnectableObject::ConnectionsIn) { 889 MappedObjectValueList::const_iterator 890 it = m_connectionsIn.begin(); 891 892 for ( ; it != m_connectionsIn.end(); ++it) { 893 list.push_back(QString("%1").arg(*it)); 894 } 895 } else if (property == MappedConnectableObject::ConnectionsOut) { 896 MappedObjectValueList::const_iterator 897 it = m_connectionsOut.begin(); 898 899 for ( ; it != m_connectionsOut.end(); ++it) { 900 list.push_back(QString("%1").arg(*it)); 901 } 902 } 903 904 return list; 905 } 906 907 bool 908 MappedAudioFader::getProperty(const MappedObjectProperty &property, 909 MappedObjectValue &value) 910 { 911 if (property == FaderLevel) { 912 value = m_level; 913 } else if (property == Instrument) { 914 value = m_instrumentId; 915 } else if (property == FaderRecordLevel) { 916 value = m_recordLevel; 917 } else if (property == Channels) { 918 value = m_channels; 919 } else if (property == InputChannel) { 920 value = m_inputChannel; 921 } else if (property == Pan) { 922 value = m_pan; 923 } else { 924 #ifdef DEBUG_MAPPEDSTUDIO 925 std::cerr << "MappedAudioFader::getProperty - " 926 << "unsupported or non-scalar property" << std::endl; 927 #endif 928 929 return false; 930 } 931 return true; 932 } 933 934 void 935 MappedAudioFader::setProperty(const MappedObjectProperty &property, 936 MappedObjectValue value) 937 { 938 bool updateLevels = false; 939 940 if (property == MappedAudioFader::FaderLevel) { 941 m_level = value; 942 updateLevels = true; 943 } else if (property == MappedObject::Instrument) { 944 m_instrumentId = InstrumentId(value); 945 updateLevels = true; 946 } else if (property == MappedAudioFader::FaderRecordLevel) { 947 m_recordLevel = value; 948 } else if (property == MappedAudioFader::Channels) { 949 m_channels = value; 950 } else if (property == MappedAudioFader::InputChannel) { 951 m_inputChannel = value; 952 } else if (property == MappedAudioFader::Pan) { 953 m_pan = value; 954 updateLevels = true; 955 } else if (property == MappedConnectableObject::ConnectionsIn) { 956 m_connectionsIn.clear(); 957 m_connectionsIn.push_back(value); 958 } else if (property == MappedConnectableObject::ConnectionsOut) { 959 m_connectionsOut.clear(); 960 m_connectionsOut.push_back(value); 961 } else { 962 #ifdef DEBUG_MAPPEDSTUDIO 963 std::cerr << "MappedAudioFader::setProperty - " 964 << "unsupported property" << std::endl; 965 #endif 966 967 return ; 968 } 969 970 /* 971 std::cout << "MappedAudioFader::setProperty - " 972 << property << " = " << value << std::endl; 973 */ 974 975 if (updateLevels) { 976 MappedStudio *studio = 977 dynamic_cast<MappedStudio*>(getParent()); 978 979 if (studio) { 980 studio->getSoundDriver()->setAudioInstrumentLevels 981 (m_instrumentId, m_level, m_pan); 982 } 983 } 984 } 985 986 // ---------------- MappedAudioBuss ------------------- 987 // 988 // 989 MappedAudioBuss::MappedAudioBuss(MappedObject *parent, 990 MappedObjectId id) : 991 MappedConnectableObject(parent, 992 "MappedAudioBuss", 993 AudioBuss, 994 id), 995 m_bussId(0), 996 m_level(0), 997 m_pan(0) 998 {} 999 1000 MappedAudioBuss::~MappedAudioBuss() 1001 {} 1002 1003 MappedObjectPropertyList 1004 MappedAudioBuss::getPropertyList(const MappedObjectProperty &property) 1005 { 1006 MappedObjectPropertyList list; 1007 1008 if (property == "") { 1009 list.push_back(MappedAudioBuss::BussId); 1010 list.push_back(MappedAudioBuss::Level); 1011 list.push_back(MappedAudioBuss::Pan); 1012 list.push_back(MappedConnectableObject::ConnectionsIn); 1013 list.push_back(MappedConnectableObject::ConnectionsOut); 1014 } else if (property == BussId) { 1015 list.push_back(MappedObjectProperty("%1").arg(m_bussId)); 1016 } else if (property == Level) { 1017 list.push_back(MappedObjectProperty("%1").arg(m_level)); 1018 } else if (property == MappedConnectableObject::ConnectionsIn) { 1019 MappedObjectValueList::const_iterator 1020 it = m_connectionsIn.begin(); 1021 1022 for ( ; it != m_connectionsIn.end(); ++it) { 1023 list.push_back(QString("%1").arg(*it)); 1024 } 1025 } else if (property == MappedConnectableObject::ConnectionsOut) { 1026 MappedObjectValueList::const_iterator 1027 it = m_connectionsOut.begin(); 1028 1029 for ( ; it != m_connectionsOut.end(); ++it) { 1030 list.push_back(QString("%1").arg(*it)); 1031 } 1032 } 1033 1034 return list; 1035 } 1036 1037 bool 1038 MappedAudioBuss::getProperty(const MappedObjectProperty &property, 1039 MappedObjectValue &value) 1040 { 1041 if (property == BussId) { 1042 value = m_bussId; 1043 } else if (property == Level) { 1044 value = m_level; 1045 } else if (property == Pan) { 1046 value = m_pan; 1047 } else { 1048 #ifdef DEBUG_MAPPEDSTUDIO 1049 std::cerr << "MappedAudioBuss::getProperty - " 1050 << "unsupported or non-scalar property" << std::endl; 1051 #endif 1052 1053 return false; 1054 } 1055 return true; 1056 } 1057 1058 void 1059 MappedAudioBuss::setProperty(const MappedObjectProperty &property, 1060 MappedObjectValue value) 1061 { 1062 bool updateLevels = false; 1063 1064 if (property == MappedAudioBuss::BussId) { 1065 m_bussId = (int)value; 1066 updateLevels = true; 1067 } else if (property == MappedAudioBuss::Level) { 1068 m_level = value; 1069 updateLevels = true; 1070 } else if (property == MappedAudioBuss::Pan) { 1071 m_pan = value; 1072 updateLevels = true; 1073 } else if (property == MappedConnectableObject::ConnectionsIn) { 1074 m_connectionsIn.clear(); 1075 m_connectionsIn.push_back(value); 1076 } else if (property == MappedConnectableObject::ConnectionsOut) { 1077 m_connectionsOut.clear(); 1078 m_connectionsOut.push_back(value); 1079 } else { 1080 #ifdef DEBUG_MAPPEDSTUDIO 1081 std::cerr << "MappedAudioBuss::setProperty - " 1082 << "unsupported property" << std::endl; 1083 #endif 1084 1085 return ; 1086 } 1087 1088 if (updateLevels) { 1089 MappedStudio *studio = 1090 dynamic_cast<MappedStudio*>(getParent()); 1091 1092 if (studio) { 1093 studio->getSoundDriver()->setAudioBussLevels 1094 (m_bussId, m_level, m_pan); 1095 } 1096 } 1097 } 1098 1099 std::vector<InstrumentId> 1100 MappedAudioBuss::getInstruments() 1101 { 1102 std::vector<InstrumentId> rv; 1103 1104 GET_LOCK; 1105 1106 MappedObject *studioObject = getParent(); 1107 while (!dynamic_cast<MappedStudio *>(studioObject)) 1108 studioObject = studioObject->getParent(); 1109 1110 std::vector<MappedObject *> objects = 1111 static_cast<MappedStudio *>(studioObject)-> 1112 getObjectsOfType(MappedObject::AudioFader); 1113 1114 for (std::vector<MappedObject *>::iterator i = objects.begin(); 1115 i != objects.end(); ++i) { 1116 MappedAudioFader *fader = dynamic_cast<MappedAudioFader *>(*i); 1117 if (fader) { 1118 MappedObjectValueList connections = fader->getConnections 1119 (MappedConnectableObject::Out); 1120 if (!connections.empty() && (*connections.begin() == getId())) { 1121 rv.push_back(fader->getInstrument()); 1122 } 1123 } 1124 } 1125 1126 RELEASE_LOCK; 1127 1128 return rv; 1129 } 1130 1131 1132 // ---------------- MappedAudioInput ------------------- 1133 // 1134 // 1135 MappedAudioInput::MappedAudioInput(MappedObject *parent, 1136 MappedObjectId id) : 1137 MappedConnectableObject(parent, 1138 "MappedAudioInput", 1139 AudioInput, 1140 id) 1141 {} 1142 1143 MappedAudioInput::~MappedAudioInput() 1144 {} 1145 1146 MappedObjectPropertyList 1147 MappedAudioInput::getPropertyList(const MappedObjectProperty &property) 1148 { 1149 MappedObjectPropertyList list; 1150 1151 if (property == "") { 1152 list.push_back(MappedAudioInput::InputNumber); 1153 } else if (property == InputNumber) { 1154 list.push_back(MappedObjectProperty("%1").arg(m_inputNumber)); 1155 } 1156 1157 return list; 1158 } 1159 1160 bool 1161 MappedAudioInput::getProperty(const MappedObjectProperty &property, 1162 MappedObjectValue &value) 1163 { 1164 if (property == InputNumber) { 1165 value = m_inputNumber; 1166 } else { 1167 #ifdef DEBUG_MAPPEDSTUDIO 1168 std::cerr << "MappedAudioInput::getProperty - " 1169 << "no properties available" << std::endl; 1170 #endif 1171 1172 } 1173 return false; 1174 } 1175 1176 void 1177 MappedAudioInput::setProperty(const MappedObjectProperty &property, 1178 MappedObjectValue value) 1179 { 1180 if (property == InputNumber) { 1181 m_inputNumber = value; 1182 } else { 1183 #ifdef DEBUG_MAPPEDSTUDIO 1184 std::cerr << "MappedAudioInput::setProperty - " 1185 << "no properties available" << std::endl; 1186 #endif 1187 1188 } 1189 return ; 1190 } 1191 1192 1193 MappedPluginSlot::MappedPluginSlot(MappedObject *parent, MappedObjectId id) : 1194 MappedObject(parent, "MappedPluginSlot", PluginSlot, id) 1195 { 1196 #ifdef DEBUG_MAPPEDSTUDIO 1197 std::cerr << "MappedPluginSlot::MappedPluginSlot: id = " << id << std::endl; 1198 #endif 1199 } 1200 1201 MappedPluginSlot::~MappedPluginSlot() 1202 { 1203 #ifdef DEBUG_MAPPEDSTUDIO 1204 std::cerr << "MappedPluginSlot::~MappedPluginSlot: id = " << getId() << ", identifier = " << m_identifier << std::endl; 1205 #endif 1206 1207 if (m_identifier != "") { 1208 1209 // shut down and remove the plugin instance we have running 1210 1211 MappedStudio *studio = 1212 dynamic_cast<MappedStudio*>(getParent()); 1213 1214 if (studio) { 1215 SoundDriver *drv = studio->getSoundDriver(); 1216 1217 if (drv) { 1218 drv->removePluginInstance(m_instrument, m_position); 1219 } 1220 } 1221 } 1222 } 1223 1224 MappedObjectPropertyList 1225 MappedPluginSlot::getPropertyList(const MappedObjectProperty &property) 1226 { 1227 MappedObjectPropertyList list; 1228 1229 if (property == "") { 1230 list.push_back(PortCount); 1231 list.push_back(Instrument); 1232 list.push_back(Bypassed); 1233 list.push_back(PluginName); 1234 list.push_back(Label); 1235 list.push_back(Author); 1236 list.push_back(Copyright); 1237 list.push_back(Category); 1238 } else if (property == Programs) { 1239 1240 // The set of available programs is dynamic -- it can change 1241 // while a plugin is instantiated. So we query it on demand 1242 // each time. 1243 1244 MappedStudio *studio = 1245 dynamic_cast<MappedStudio*>(getParent()); 1246 1247 if (studio) { 1248 QStringList programs = 1249 studio->getSoundDriver()->getPluginInstancePrograms(m_instrument, 1250 m_position); 1251 1252 for (int i = 0; i < int(programs.count()); ++i) { 1253 list.push_back(programs[i]); 1254 } 1255 } 1256 1257 } else { 1258 std::cerr << "MappedPluginSlot::getPropertyList: not a list property" 1259 << std::endl; 1260 } 1261 1262 return list; 1263 } 1264 1265 bool 1266 MappedPluginSlot::getProperty(const MappedObjectProperty &property, 1267 MappedObjectValue &value) 1268 { 1269 if (property == PortCount) { 1270 value = m_portCount; 1271 } else if (property == Instrument) { 1272 value = m_instrument; 1273 } else if (property == Position) { 1274 value = m_position; 1275 } else if (property == Bypassed) { 1276 value = m_bypassed; 1277 } else { 1278 #ifdef DEBUG_MAPPEDSTUDIO 1279 std::cerr << "MappedPluginSlot::getProperty - " 1280 << "unsupported or non-scalar property" << std::endl; 1281 #endif 1282 1283 return false; 1284 } 1285 return true; 1286 } 1287 1288 bool 1289 MappedPluginSlot::getStringProperty(const MappedObjectProperty &property, 1290 QString &value) 1291 { 1292 if (property == Identifier) { 1293 value = m_identifier; 1294 } else if (property == PluginName) { 1295 value = m_name; 1296 } else if (property == Label) { 1297 value = m_label; 1298 } else if (property == Author) { 1299 value = m_author; 1300 } else if (property == Copyright) { 1301 value = m_copyright; 1302 } else if (property == Category) { 1303 value = m_category; 1304 } else if (property == Program) { 1305 1306 MappedStudio *studio = 1307 dynamic_cast<MappedStudio*>(getParent()); 1308 1309 if (studio) { 1310 value = studio->getSoundDriver()->getPluginInstanceProgram(m_instrument, 1311 m_position); 1312 } 1313 } else { 1314 #ifdef DEBUG_MAPPEDSTUDIO 1315 std::cerr << "MappedPluginSlot::getProperty - " 1316 << "unsupported or non-scalar property" << std::endl; 1317 #endif 1318 1319 return false; 1320 } 1321 return true; 1322 } 1323 1324 QString 1325 MappedPluginSlot::getProgram(int bank, int program) 1326 { 1327 MappedStudio *studio = 1328 dynamic_cast<MappedStudio*>(getParent()); 1329 1330 if (studio) { 1331 return 1332 studio->getSoundDriver()->getPluginInstanceProgram(m_instrument, 1333 m_position, 1334 bank, 1335 program); 1336 } 1337 1338 return QString(); 1339 } 1340 1341 unsigned long 1342 MappedPluginSlot::getProgram(QString name) 1343 { 1344 MappedStudio *studio = 1345 dynamic_cast<MappedStudio*>(getParent()); 1346 1347 if (studio) { 1348 return 1349 studio->getSoundDriver()->getPluginInstanceProgram(m_instrument, 1350 m_position, 1351 name); 1352 } 1353 1354 return 0; 1355 } 1356 1357 void 1358 MappedPluginSlot::setProperty(const MappedObjectProperty &property, 1359 MappedObjectValue value) 1360 { 1361 if (property == Instrument) { 1362 m_instrument = InstrumentId(value); 1363 } else if (property == PortCount) { 1364 m_portCount = int(value); 1365 } else if (property == Position) { 1366 m_position = int(value); 1367 } else if (property == Bypassed) { 1368 m_bypassed = bool(value); 1369 1370 MappedStudio *studio = 1371 dynamic_cast<MappedStudio*>(getParent()); 1372 1373 if (studio) { 1374 studio->getSoundDriver()->setPluginInstanceBypass(m_instrument, 1375 m_position, 1376 m_bypassed); 1377 } 1378 } 1379 } 1380 1381 void 1382 MappedPluginSlot::setStringProperty(const MappedObjectProperty &property, 1383 QString value) 1384 { 1385 RG_DEBUG << "MappedPluginSlot::setStringProperty: " 1386 << property << " -> " << value; 1387 1388 if (property == Identifier) { 1389 1390 if (m_identifier == value) 1391 return ; 1392 1393 // shut down and remove the plugin instance we have running 1394 1395 MappedStudio *studio = 1396 dynamic_cast<MappedStudio*>(getParent()); 1397 1398 if (studio) { 1399 SoundDriver *drv = studio->getSoundDriver(); 1400 1401 if (drv) { 1402 1403 // We don't call drv->removePluginInstance at this 1404 // point: the sequencer will deal with that when we 1405 // call setPluginInstance below. If we removed the 1406 // instance here, we might cause the library we want 1407 // for the new plugin instance to be unloaded and then 1408 // loaded again, which is hardly the most efficient. 1409 1410 m_identifier = value; 1411 1412 // populate myself and my ports 1413 PluginFactory *factory = PluginFactory::instanceFor(m_identifier); 1414 if (!factory) { 1415 std::cerr << "WARNING: MappedPluginSlot::setProperty(identifier): No plugin factory for identifier " << m_identifier << "!" << std::endl; 1416 m_identifier = ""; 1417 return ; 1418 } 1419 1420 factory->populatePluginSlot(m_identifier, *this); 1421 1422 // now create the new instance 1423 drv->setPluginInstance(m_instrument, 1424 m_identifier, 1425 m_position); 1426 } 1427 } 1428 1429 m_configuration.clear(); 1430 1431 } else if (property == PluginName) { 1432 m_name = value; 1433 } else if (property == Label) { 1434 m_label = value; 1435 } else if (property == Author) { 1436 m_author = value; 1437 } else if (property == Copyright) { 1438 m_copyright = value; 1439 } else if (property == Category) { 1440 m_category = value; 1441 } else if (property == Program) { 1442 1443 MappedStudio *studio = 1444 dynamic_cast<MappedStudio*>(getParent()); 1445 1446 if (studio) { 1447 studio->getSoundDriver()->setPluginInstanceProgram(m_instrument, 1448 m_position, 1449 value); 1450 } 1451 } else { 1452 1453 #ifdef DEBUG_MAPPEDSTUDIO 1454 std::cerr << "MappedPluginSlot::setProperty - " 1455 << "unsupported or non-scalar property" << std::endl; 1456 #endif 1457 1458 } 1459 } 1460 1461 void 1462 MappedPluginSlot::setPropertyList(const MappedObjectProperty &property, 1463 const MappedObjectPropertyList &values) 1464 { 1465 if (property == Configuration) { 1466 1467 #ifdef DEBUG_MAPPEDSTUDIO 1468 std::cerr << "MappedPluginSlot::setPropertyList(configuration): configuration is:" << std::endl; 1469 #endif 1470 1471 MappedStudio *studio = 1472 dynamic_cast<MappedStudio*>(getParent()); 1473 1474 for (MappedObjectPropertyList::const_iterator i = values.begin(); 1475 i != values.end(); ++i) { 1476 1477 QString key = *i; 1478 QString value = *++i; 1479 1480 #ifdef DEBUG_MAPPEDSTUDIO 1481 std::cerr << key << " = " << value << std::endl; 1482 #endif 1483 1484 if (m_configuration.find(key) != m_configuration.end() && 1485 m_configuration[key] == value) { 1486 continue; 1487 } 1488 1489 if (studio) { 1490 QString rv = 1491 studio->getSoundDriver()->configurePlugin(m_instrument, 1492 m_position, 1493 key, value); 1494 if (!rv.isEmpty()) { 1495 throw(rv); 1496 } 1497 } 1498 } 1499 1500 m_configuration.clear(); 1501 1502 for (MappedObjectPropertyList::const_iterator i = values.begin(); 1503 i != values.end(); ++i) { 1504 1505 QString key = *i; 1506 QString value = *++i; 1507 1508 m_configuration[key] = value; 1509 } 1510 } else { 1511 1512 #ifdef DEBUG_MAPPEDSTUDIO 1513 std::cerr << "MappedPluginSlot::setPropertyList - " 1514 << "not a list property" << std::endl; 1515 #endif 1516 1517 } 1518 } 1519 1520 void 1521 MappedPluginSlot::setPort(unsigned long portNumber, float value) 1522 { 1523 std::vector<MappedObject*> ports = getChildObjects(); 1524 std::vector<MappedObject*>::iterator it = ports.begin(); 1525 MappedPluginPort *port = nullptr; 1526 1527 for (; it != ports.end(); ++it) { 1528 port = dynamic_cast<MappedPluginPort *>(*it); 1529 if (port && (unsigned long)port->getPortNumber() == portNumber) { 1530 port->setValue(value); 1531 } 1532 } 1533 } 1534 1535 float 1536 MappedPluginSlot::getPort(unsigned long portNumber) 1537 { 1538 std::vector<MappedObject*> ports = getChildObjects(); 1539 std::vector<MappedObject*>::iterator it = ports.begin(); 1540 MappedPluginPort *port = nullptr; 1541 1542 for (; it != ports.end(); ++it) { 1543 port = dynamic_cast<MappedPluginPort *>(*it); 1544 if (port && (unsigned long)port->getPortNumber() == portNumber) { 1545 return port->getValue(); 1546 } 1547 } 1548 1549 return 0; 1550 } 1551 1552 1553 MappedPluginPort::MappedPluginPort(MappedObject *parent, MappedObjectId id) : 1554 MappedObject(parent, "MappedPluginPort", PluginPort, id) 1555 {} 1556 1557 MappedPluginPort::~MappedPluginPort() 1558 {} 1559 1560 MappedObjectPropertyList 1561 MappedPluginPort::getPropertyList(const MappedObjectProperty &property) 1562 { 1563 MappedObjectPropertyList list; 1564 1565 if (property == "") { 1566 list.push_back(PortNumber); 1567 list.push_back(Minimum); 1568 list.push_back(Maximum); 1569 list.push_back(Default); 1570 list.push_back(DisplayHint); 1571 list.push_back(Value); 1572 list.push_back(Name); 1573 } else { 1574 std::cerr << "MappedPluginSlot::getPropertyList: not a list property" 1575 << std::endl; 1576 } 1577 1578 return list; 1579 } 1580 1581 bool 1582 MappedPluginPort::getProperty(const MappedObjectProperty &property, 1583 MappedObjectValue &value) 1584 { 1585 if (property == PortNumber) { 1586 value = m_portNumber; 1587 } else if (property == Minimum) { 1588 value = m_minimum; 1589 } else if (property == Maximum) { 1590 value = m_maximum; 1591 } else if (property == Default) { 1592 value = m_default; 1593 } else if (property == DisplayHint) { 1594 value = m_displayHint; 1595 } else if (property == Value) { 1596 return getValue(); 1597 } else { 1598 #ifdef DEBUG_MAPPEDSTUDIO 1599 std::cerr << "MappedPluginPort::getProperty - " 1600 << "unsupported or non-scalar property" << std::endl; 1601 #endif 1602 1603 return false; 1604 } 1605 return true; 1606 } 1607 1608 bool 1609 MappedPluginPort::getStringProperty(const MappedObjectProperty &property, 1610 QString &value) 1611 { 1612 if (property == Name) { 1613 value = m_name; 1614 } else { 1615 1616 #ifdef DEBUG_MAPPEDSTUDIO 1617 std::cerr << "MappedPluginPort::getProperty - " 1618 << "unsupported or non-scalar property" << std::endl; 1619 #endif 1620 1621 return false; 1622 } 1623 return true; 1624 } 1625 1626 void 1627 MappedPluginPort::setValue(MappedObjectValue value) 1628 { 1629 MappedPluginSlot *slot = 1630 dynamic_cast<MappedPluginSlot *>(getParent()); 1631 1632 if (slot) { 1633 1634 MappedStudio *studio = 1635 dynamic_cast<MappedStudio *>(slot->getParent()); 1636 1637 if (studio) { 1638 SoundDriver *drv = studio->getSoundDriver(); 1639 1640 if (drv) { 1641 drv->setPluginInstancePortValue(slot->getInstrument(), 1642 slot->getPosition(), 1643 m_portNumber, value); 1644 } 1645 } 1646 } 1647 } 1648 1649 float 1650 MappedPluginPort::getValue() const 1651 { 1652 const MappedPluginSlot *slot = 1653 dynamic_cast<const MappedPluginSlot *>(getParent()); 1654 1655 if (slot) { 1656 1657 const MappedStudio *studio = 1658 dynamic_cast<const MappedStudio *>(slot->getParent()); 1659 1660 if (studio) { 1661 SoundDriver *drv = 1662 const_cast<SoundDriver *>(studio->getSoundDriver()); 1663 1664 if (drv) { 1665 return drv->getPluginInstancePortValue(slot->getInstrument(), 1666 slot->getPosition(), 1667 m_portNumber); 1668 } 1669 } 1670 } 1671 1672 return 0; 1673 } 1674 1675 void 1676 MappedPluginPort::setProperty(const MappedObjectProperty &property, 1677 MappedObjectValue value) 1678 { 1679 if (property == PortNumber) { 1680 m_portNumber = int(value); 1681 } else if (property == Minimum) { 1682 m_minimum = value; 1683 } else if (property == Maximum) { 1684 m_maximum = value; 1685 } else if (property == Default) { 1686 m_default = value; 1687 } else if (property == DisplayHint) { 1688 m_displayHint = PluginPort::PortDisplayHint(value); 1689 } else if (property == Value) { 1690 setValue(value); 1691 } else { 1692 #ifdef DEBUG_MAPPEDSTUDIO 1693 std::cerr << "MappedPluginPort::setProperty - " 1694 << "unsupported or non-scalar property" << std::endl; 1695 #endif 1696 1697 } 1698 } 1699 1700 1701 void 1702 MappedPluginPort::setStringProperty(const MappedObjectProperty &property, 1703 QString value) 1704 { 1705 if (property == Name) { 1706 m_name = value; 1707 } else { 1708 1709 #ifdef DEBUG_MAPPEDSTUDIO 1710 std::cerr << "MappedPluginPort::setProperty - " 1711 << "unsupported or non-scalar property" << std::endl; 1712 #endif 1713 1714 } 1715 } 1716 1717 1718 } 1719 1720 1721 1722