00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "alsaqueue.h"
00021 #include "alsaclient.h"
00022
00028 namespace drumstick {
00029
00056 PortInfo::PortInfo()
00057 {
00058 snd_seq_port_info_malloc(&m_Info);
00059 }
00060
00065 PortInfo::PortInfo(const PortInfo& other)
00066 {
00067 snd_seq_port_info_malloc(&m_Info);
00068 snd_seq_port_info_copy(m_Info, other.m_Info);
00069 m_ReadSubscribers = other.m_ReadSubscribers;
00070 m_WriteSubscribers = other.m_WriteSubscribers;
00071 m_ClientName = other.m_ClientName;
00072 }
00073
00078 PortInfo::PortInfo(snd_seq_port_info_t* other)
00079 {
00080 snd_seq_port_info_malloc(&m_Info);
00081 snd_seq_port_info_copy(m_Info, other);
00082 }
00083
00090 PortInfo::PortInfo(MidiClient* seq, const int client, const int port)
00091 {
00092 snd_seq_port_info_malloc(&m_Info);
00093 CHECK_WARNING(snd_seq_get_any_port_info(seq->getHandle(), client, port, m_Info));
00094 }
00095
00101 PortInfo::PortInfo(MidiClient* seq, const int port)
00102 {
00103 snd_seq_port_info_malloc(&m_Info);
00104 CHECK_WARNING(snd_seq_get_port_info(seq->getHandle(), port, m_Info));
00105 }
00106
00110 PortInfo::~PortInfo()
00111 {
00112 snd_seq_port_info_free(m_Info);
00113 freeSubscribers();
00114 }
00115
00120 PortInfo* PortInfo::clone()
00121 {
00122 return new PortInfo(m_Info);
00123 }
00124
00130 PortInfo& PortInfo::operator=(const PortInfo& other)
00131 {
00132 snd_seq_port_info_copy(m_Info, other.m_Info);
00133 m_ReadSubscribers = other.m_ReadSubscribers;
00134 m_WriteSubscribers = other.m_WriteSubscribers;
00135 m_ClientName = other.m_ClientName;
00136 return *this;
00137 }
00138
00144 int
00145 PortInfo::getClient()
00146 {
00147 return snd_seq_port_info_get_client(m_Info);
00148 }
00149
00155 int
00156 PortInfo::getPort()
00157 {
00158 return snd_seq_port_info_get_port(m_Info);
00159 }
00160
00166 const snd_seq_addr_t*
00167 PortInfo::getAddr()
00168 {
00169 return snd_seq_port_info_get_addr(m_Info);
00170 }
00171
00177 QString
00178 PortInfo::getName()
00179 {
00180 return QString(snd_seq_port_info_get_name(m_Info));
00181 }
00182
00188 unsigned int
00189 PortInfo::getCapability()
00190 {
00191 return snd_seq_port_info_get_capability(m_Info);
00192 }
00193
00199 unsigned int
00200 PortInfo::getType()
00201 {
00202 return snd_seq_port_info_get_type(m_Info);
00203 }
00204
00210 int
00211 PortInfo::getMidiChannels()
00212 {
00213 return snd_seq_port_info_get_midi_channels(m_Info);
00214 }
00215
00221 int
00222 PortInfo::getMidiVoices()
00223 {
00224 return snd_seq_port_info_get_midi_voices(m_Info);
00225 }
00226
00232 int
00233 PortInfo::getSynthVoices()
00234 {
00235 return snd_seq_port_info_get_synth_voices(m_Info);
00236 }
00237
00242 int
00243 PortInfo::getReadUse()
00244 {
00245 return snd_seq_port_info_get_read_use(m_Info);
00246 }
00247
00252 int
00253 PortInfo::getWriteUse()
00254 {
00255 return snd_seq_port_info_get_write_use(m_Info);
00256 }
00257
00263 int
00264 PortInfo::getPortSpecified()
00265 {
00266 return snd_seq_port_info_get_port_specified(m_Info);
00267 }
00268
00274 void
00275 PortInfo::setClient(int client)
00276 {
00277 snd_seq_port_info_set_client(m_Info, client);
00278 }
00279
00285 void
00286 PortInfo::setPort(int port)
00287 {
00288 snd_seq_port_info_set_port(m_Info, port);
00289 }
00290
00296 void
00297 PortInfo::setAddr(const snd_seq_addr_t* addr)
00298 {
00299 snd_seq_port_info_set_addr(m_Info, addr);
00300 }
00301
00307 void
00308 PortInfo::setName(QString const& name)
00309 {
00310 snd_seq_port_info_set_name(m_Info, name.toLocal8Bit().data());
00311 }
00312
00329 void
00330 PortInfo::setCapability(unsigned int capability)
00331 {
00332 snd_seq_port_info_set_capability(m_Info, capability);
00333 }
00334
00356 void
00357 PortInfo::setType(unsigned int type)
00358 {
00359 snd_seq_port_info_set_type(m_Info, type);
00360 }
00361
00367 void
00368 PortInfo::setMidiChannels(int channels)
00369 {
00370 snd_seq_port_info_set_midi_channels(m_Info, channels);
00371 }
00372
00378 void
00379 PortInfo::setMidiVoices(int voices)
00380 {
00381 snd_seq_port_info_set_midi_voices(m_Info, voices);
00382 }
00383
00389 void
00390 PortInfo::setSynthVoices(int voices)
00391 {
00392 snd_seq_port_info_set_synth_voices(m_Info, voices);
00393 }
00394
00400 void
00401 PortInfo::setPortSpecified(int val)
00402 {
00403 snd_seq_port_info_set_port_specified(m_Info, val);
00404 }
00405
00410 SubscribersList
00411 PortInfo::getReadSubscribers() const
00412 {
00413 return m_ReadSubscribers;
00414 }
00415
00420 SubscribersList
00421 PortInfo::getWriteSubscribers() const
00422 {
00423 return m_WriteSubscribers;
00424 }
00425
00430 void
00431 PortInfo::readSubscribers(MidiClient* seq)
00432 {
00433 Subscriber subs;
00434 snd_seq_addr_t tmp;
00435 freeSubscribers();
00436 tmp.client = getClient();
00437 tmp.port = getPort();
00438
00439 subs.setType(SND_SEQ_QUERY_SUBS_READ);
00440 subs.setIndex(0);
00441 subs.setRoot(&tmp);
00442 while (snd_seq_query_port_subscribers(seq->getHandle(), subs.m_Info) >= 0)
00443 {
00444 m_ReadSubscribers.append(subs);
00445 subs.setIndex(subs.getIndex() + 1);
00446 }
00447
00448 subs.setType(SND_SEQ_QUERY_SUBS_WRITE);
00449 subs.setIndex(0);
00450 subs.setRoot(&tmp);
00451 while (snd_seq_query_port_subscribers(seq->getHandle(), subs.m_Info) >= 0)
00452 {
00453 m_WriteSubscribers.append(subs);
00454 subs.setIndex(subs.getIndex() + 1);
00455 }
00456 }
00457
00461 void
00462 PortInfo::freeSubscribers()
00463 {
00464 m_ReadSubscribers.clear();
00465 m_WriteSubscribers.clear();
00466 }
00467
00472 int
00473 PortInfo::getSizeOfInfo() const
00474 {
00475 return snd_seq_port_info_sizeof();
00476 }
00477
00483 bool
00484 PortInfo::getTimestamping()
00485 {
00486 return (snd_seq_port_info_get_timestamping(m_Info) == 1);
00487 }
00488
00494 bool
00495 PortInfo::getTimestampReal()
00496 {
00497 return (snd_seq_port_info_get_timestamp_real(m_Info) == 1);
00498 }
00499
00505 int
00506 PortInfo::getTimestampQueue()
00507 {
00508 return snd_seq_port_info_get_timestamp_queue(m_Info);
00509 }
00510
00516 void
00517 PortInfo::setTimestamping(bool value)
00518 {
00519 snd_seq_port_info_set_timestamping(m_Info, value?1:0);
00520 }
00521
00527 void
00528 PortInfo::setTimestampReal(bool value)
00529 {
00530 snd_seq_port_info_set_timestamp_real(m_Info, value?1:0);
00531 }
00532
00538 void
00539 PortInfo::setTimestampQueue(int queueId)
00540 {
00541 snd_seq_port_info_set_timestamp_queue(m_Info, queueId);
00542 }
00543
00544
00549 MidiPort::MidiPort( QObject* parent ) :
00550 QObject( parent ),
00551 m_MidiClient( NULL ),
00552 m_Attached( false )
00553 {}
00554
00560 MidiPort::~MidiPort()
00561 {
00562 unsubscribeAll();
00563 detach();
00564 freeSubscriptions();
00565 }
00566
00570 PortInfo*
00571 MidiPort::getPortInfo()
00572 {
00573 return &m_Info;
00574 }
00575
00580 SubscriptionsList
00581 MidiPort::getSubscriptions() const
00582 {
00583 return m_Subscriptions;
00584 }
00585
00589 void
00590 MidiPort::freeSubscriptions()
00591 {
00592 m_Subscriptions.clear();
00593 }
00594
00599 void
00600 MidiPort::setMidiClient( MidiClient* seq )
00601 {
00602 if (m_MidiClient != seq)
00603 {
00604 m_MidiClient = seq;
00605 emit midiClientChanged( this, m_MidiClient );
00606 applyPortInfo();
00607 }
00608 }
00609
00614 void
00615 MidiPort::subscribe(Subscription* subs)
00616 {
00617 subs->subscribe(m_MidiClient);
00618 m_Subscriptions.append(*subs);
00619 emit subscribed(this, subs);
00620 }
00621
00626 void
00627 MidiPort::unsubscribe( Subscription* subs )
00628 {
00629 Subscription subs2;
00630 if (m_MidiClient == NULL)
00631 {
00632 return;
00633 }
00634 subs->unsubscribe(m_MidiClient);
00635 SubscriptionsList::iterator it;
00636 for(it = m_Subscriptions.begin(); it != m_Subscriptions.end(); ++it)
00637 {
00638 subs2 = (*it);
00639 if ((subs2.getSender()->client == subs->getSender()->client) &&
00640 (subs2.getSender()->port == subs->getSender()->port) &&
00641 (subs2.getDest()->client == subs->getDest()->client) &&
00642 (subs2.getDest()->port == subs->getDest()->port))
00643 {
00644 m_Subscriptions.erase(it);
00645 break;
00646 }
00647 }
00648 }
00649
00654 void
00655 MidiPort::subscribeTo( PortInfo* info )
00656 {
00657 Subscription subs;
00658 subs.setSender(m_Info.getAddr());
00659 subs.setDest(info->getAddr());
00660 subscribe(&subs);
00661 }
00662
00668 void
00669 MidiPort::subscribeTo( int client, int port )
00670 {
00671 Subscription subs;
00672 snd_seq_addr addr;
00673 addr.client = client;
00674 addr.port = port;
00675 subs.setSender(m_Info.getAddr());
00676 subs.setDest(&addr);
00677 subscribe(&subs);
00678 }
00679
00684 void
00685 MidiPort::subscribeTo( QString const& name )
00686 {
00687 Subscription subs;
00688 snd_seq_addr addr;
00689 if ((m_MidiClient != NULL) && (m_MidiClient->getHandle() != NULL))
00690 {
00691 subs.setSender(m_Info.getAddr());
00692 if (m_MidiClient->parseAddress(name, addr)) {
00693 subs.setDest(&addr);
00694 subscribe(&subs);
00695 }
00696 }
00697 }
00698
00703 void
00704 MidiPort::unsubscribeTo( QString const& name )
00705 {
00706 Subscription subs;
00707 snd_seq_addr addr;
00708 if ((m_MidiClient != NULL) && (m_MidiClient->getHandle() != NULL))
00709 {
00710 subs.setSender(m_Info.getAddr());
00711 if (m_MidiClient->parseAddress(name, addr)) {
00712 subs.setDest(&addr);
00713 unsubscribe(&subs);
00714 }
00715 }
00716 }
00717
00722 void
00723 MidiPort::unsubscribeTo( PortInfo* port )
00724 {
00725 Subscription subs;
00726 if ((m_MidiClient != NULL) && (m_MidiClient->getHandle() != NULL))
00727 {
00728 subs.setSender(m_Info.getAddr());
00729 subs.setDest(port->getAddr());
00730 unsubscribe(&subs);
00731 }
00732 }
00733
00738 void
00739 MidiPort::unsubscribeTo( const snd_seq_addr_t* addr )
00740 {
00741 Subscription subs;
00742 if ((m_MidiClient != NULL) && (m_MidiClient->getHandle() != NULL))
00743 {
00744 subs.setSender(m_Info.getAddr());
00745 subs.setDest(addr);
00746 unsubscribe(&subs);
00747 }
00748 }
00749
00754 void
00755 MidiPort::subscribeFrom( PortInfo* port )
00756 {
00757 Subscription subs;
00758 subs.setSender( port->getAddr() );
00759 subs.setDest( m_Info.getAddr() );
00760 subscribe(&subs);
00761 }
00762
00768 void
00769 MidiPort::subscribeFrom( int client, int port )
00770 {
00771 Subscription subs;
00772 snd_seq_addr addr;
00773 addr.client = client;
00774 addr.port = port;
00775 subs.setSender(&addr);
00776 subs.setDest(m_Info.getAddr());
00777 subscribe(&subs);
00778 }
00779
00784 void
00785 MidiPort::subscribeFrom( QString const& name )
00786 {
00787 Subscription subs;
00788 snd_seq_addr addr;
00789 if ((m_MidiClient != NULL) && (m_MidiClient->getHandle() != NULL))
00790 {
00791 if (m_MidiClient->parseAddress(name, addr)) {
00792 subs.setSender(&addr);
00793 subs.setDest(m_Info.getAddr());
00794 subscribe(&subs);
00795 }
00796 }
00797 }
00798
00803 void
00804 MidiPort::unsubscribeFrom( QString const& name )
00805 {
00806 Subscription subs;
00807 snd_seq_addr addr;
00808 if ((m_MidiClient != NULL) && (m_MidiClient->getHandle() != NULL))
00809 {
00810 if (m_MidiClient->parseAddress(name, addr)) {
00811 subs.setSender(&addr);
00812 subs.setDest(m_Info.getAddr());
00813 unsubscribe(&subs);
00814 }
00815 }
00816 }
00817
00822 void
00823 MidiPort::unsubscribeFrom( PortInfo* port )
00824 {
00825 Subscription subs;
00826 if ((m_MidiClient != NULL) && (m_MidiClient->getHandle() != NULL))
00827 {
00828 subs.setSender(port->getAddr());
00829 subs.setDest(m_Info.getAddr());
00830 unsubscribe(&subs);
00831 }
00832 }
00833
00838 void
00839 MidiPort::unsubscribeFrom( const snd_seq_addr_t* addr )
00840 {
00841 Subscription subs;
00842 if ((m_MidiClient != NULL) && (m_MidiClient->getHandle() != NULL))
00843 {
00844 subs.setSender(addr);
00845 subs.setDest(m_Info.getAddr());
00846 unsubscribe(&subs);
00847 }
00848 }
00849
00853 void
00854 MidiPort::subscribeFromAnnounce()
00855 {
00856 subscribeFrom(SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE);
00857 }
00858
00862 void
00863 MidiPort::unsubscribeAll()
00864 {
00865 if (m_MidiClient == NULL) {
00866 return;
00867 }
00868 SubscriptionsList::Iterator it;
00869 for( it = m_Subscriptions.begin(); it != m_Subscriptions.end(); ++it) {
00870 Subscription s = (*it);
00871 s.unsubscribe(m_MidiClient);
00872 }
00873 m_Subscriptions.clear();
00874 }
00875
00879 void
00880 MidiPort::applyPortInfo()
00881 {
00882 if (m_Attached && (m_MidiClient != NULL) && (m_MidiClient->isOpened()))
00883 {
00884 CHECK_WARNING(snd_seq_set_port_info( m_MidiClient->getHandle(),
00885 m_Info.getPort(), m_Info.m_Info ));
00886 }
00887 }
00888
00893 QString
00894 MidiPort::getPortName()
00895 {
00896 return m_Info.getName();
00897 }
00898
00903 void
00904 MidiPort::setPortName( QString const& newName )
00905 {
00906 m_Info.setName(newName);
00907 applyPortInfo();
00908 }
00909
00914 int
00915 MidiPort::getPortId()
00916 {
00917 return m_Info.getPort();
00918 }
00919
00925 unsigned int
00926 MidiPort::getCapability()
00927 {
00928 return m_Info.getCapability();
00929 }
00930
00936 void
00937 MidiPort::setCapability(unsigned int newValue)
00938 {
00939 m_Info.setCapability(newValue);
00940 applyPortInfo();
00941 }
00942
00948 unsigned int
00949 MidiPort::getPortType()
00950 {
00951 return m_Info.getType();
00952 }
00953
00959 void
00960 MidiPort::setPortType( unsigned int newValue)
00961 {
00962 m_Info.setType( newValue );
00963 applyPortInfo();
00964 }
00965
00970 int
00971 MidiPort::getMidiChannels()
00972 {
00973 return m_Info.getMidiChannels();
00974 }
00975
00980 void
00981 MidiPort::setMidiChannels(int newValue)
00982 {
00983 m_Info.setMidiChannels( newValue );
00984 applyPortInfo();
00985 }
00986
00991 int
00992 MidiPort::getMidiVoices()
00993 {
00994 return m_Info.getMidiVoices();
00995 }
00996
01001 void
01002 MidiPort::setMidiVoices(int newValue)
01003 {
01004 m_Info.setMidiVoices( newValue );
01005 applyPortInfo();
01006 }
01007
01012 int
01013 MidiPort::getSynthVoices()
01014 {
01015 return m_Info.getSynthVoices();
01016 }
01017
01022 void
01023 MidiPort::setSynthVoices(int newValue)
01024 {
01025 m_Info.setSynthVoices( newValue );
01026 applyPortInfo();
01027 }
01028
01033 bool
01034 MidiPort::getTimestamping()
01035 {
01036 return m_Info.getTimestamping();
01037 }
01038
01043 bool
01044 MidiPort::getTimestampReal()
01045 {
01046 return m_Info.getTimestampReal();
01047 }
01048
01053 int
01054 MidiPort::getTimestampQueue()
01055 {
01056 return m_Info.getTimestampQueue();
01057 }
01058
01063 void
01064 MidiPort::setTimestamping(bool value)
01065 {
01066 m_Info.setTimestamping(value);
01067 applyPortInfo();
01068 }
01069
01074 void
01075 MidiPort::setTimestampReal(bool value)
01076 {
01077 m_Info.setTimestampReal(value);
01078 applyPortInfo();
01079 }
01080
01085 void
01086 MidiPort::setTimestampQueue(int queueId)
01087 {
01088 m_Info.setTimestampQueue(queueId);
01089 applyPortInfo();
01090 }
01091
01096 void
01097 MidiPort::attach( MidiClient* seq )
01098 {
01099 if (!m_Attached && (seq != NULL)) {
01100 m_MidiClient = seq;
01101 m_MidiClient->portAttach(this);
01102 m_Attached = true;
01103 emit attached(this);
01104 }
01105 }
01106
01110 void
01111 MidiPort::detach()
01112 {
01113 if (m_Attached && (m_MidiClient != NULL)) {
01114 m_MidiClient->portDetach(this);
01115 m_Attached = false;
01116 emit detached(this);
01117 }
01118 }
01119
01123 void
01124 MidiPort::updateSubscribers()
01125 {
01126 m_Info.readSubscribers(m_MidiClient);
01127 }
01128
01133 PortInfoList
01134 MidiPort::getReadSubscribers()
01135 {
01136 const SubscribersList subs(m_Info.getReadSubscribers());
01137 PortInfoList lst;
01138 SubscribersList::ConstIterator it;
01139 for(it = subs.constBegin(); it != subs.constEnd(); ++it) {
01140 Subscriber s = *it;
01141 int client = s.getAddr()->client;
01142 if ((client != SND_SEQ_CLIENT_SYSTEM) && (client != m_Info.getClient())) {
01143 int port = s.getAddr()->port;
01144 PortInfo p(m_MidiClient, client, port);
01145 if ((p.getCapability() & SND_SEQ_PORT_CAP_NO_EXPORT) == 0) {
01146 p.setClientName(m_MidiClient->getClientName(client));
01147 lst << p;
01148 }
01149 }
01150 }
01151 return lst;
01152 }
01153
01158 PortInfoList
01159 MidiPort::getWriteSubscribers()
01160 {
01161 const SubscribersList subs(m_Info.getWriteSubscribers());
01162 PortInfoList lst;
01163 SubscribersList::ConstIterator it;
01164 for(it = subs.constBegin(); it != subs.constEnd(); ++it) {
01165 Subscriber s = *it;
01166 int client = s.getAddr()->client;
01167 if ((client != SND_SEQ_CLIENT_SYSTEM) && (client != m_Info.getClient())) {
01168 int port = s.getAddr()->port;
01169 PortInfo p(m_MidiClient, client, port);
01170 if ((p.getCapability() & SND_SEQ_PORT_CAP_NO_EXPORT) == 0) {
01171 p.setClientName(m_MidiClient->getClientName(client));
01172 lst << p;
01173 }
01174 }
01175 }
01176 return lst;
01177 }
01178
01185 bool
01186 MidiPort::containsAddress(const snd_seq_addr_t* addr, const PortInfoList& lst)
01187 {
01188 PortInfoList::ConstIterator i;
01189 for( i = lst.begin(); i != lst.end(); ++i) {
01190 PortInfo p = *i;
01191 if ((p.getAddr()->client == addr->client) &&
01192 (p.getAddr()->port == addr->port)) {
01193 return true;
01194 }
01195 }
01196 return false;
01197 }
01198
01203 void
01204 MidiPort::updateConnectionsTo(const PortInfoList& ports)
01205 {
01206 PortInfoList subs(getReadSubscribers());
01207 PortInfoList::ConstIterator i;
01208 for (i = subs.constBegin(); i != subs.constEnd(); ++i) {
01209 PortInfo s = *i;
01210 if (!containsAddress(s.getAddr(), ports)) {
01211 unsubscribeTo(s.getAddr());
01212 }
01213 }
01214 for (i = ports.constBegin(); i != ports.constEnd(); ++i) {
01215 PortInfo p = *i;
01216 if (!containsAddress(p.getAddr(), subs)) {
01217 subscribeTo(&p);
01218 }
01219 }
01220 }
01221
01226 void
01227 MidiPort::updateConnectionsFrom(const PortInfoList& ports)
01228 {
01229 PortInfoList subs(getWriteSubscribers());
01230 PortInfoList::ConstIterator i;
01231 for (i = subs.constBegin(); i != subs.constEnd(); ++i) {
01232 PortInfo s = *i;
01233 if (!containsAddress(s.getAddr(), ports)) {
01234 unsubscribeFrom(s.getAddr());
01235 }
01236 }
01237 for (i = ports.constBegin(); i != ports.constEnd(); ++i) {
01238 PortInfo p = *i;
01239 if (!containsAddress(p.getAddr(), subs)) {
01240 subscribeFrom(&p);
01241 }
01242 }
01243 }
01244
01245 }