1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: route.h,v 1.5.2.1 2008/05/21 00:28:52 terminator356 Exp $
5 //
6 //  (C) Copyright 2001 Werner Schweer (ws@seh.de)
7 //  (C) Copyright 2011, 2015 Tim E. Real (terminator356 on sourceforge)
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
11 //  as published by the Free Software Foundation; version 2 of
12 //  the License, or (at your option) any later version.
13 //
14 //  This program is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 //  GNU General Public License for more details.
18 //
19 //  You should have received a copy of the GNU General Public License
20 //  along with this program; if not, write to the Free Software
21 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 //
23 //=========================================================
24 
25 #ifndef __ROUTE_H__
26 #define __ROUTE_H__
27 
28 #include <QMetaType>
29 #include <QString>
30 
31 #include <vector>
32 #include "globaldefs.h"
33 
34 #define ROUTE_PERSISTENT_NAME_SIZE 256    // Size of char array Route::persistentName, including the terminating null character.
35 
36 class QPixmap;
37 
38 namespace MusECore {
39 
40 
41 // Forward declarations:
42 class MidiDevice;
43 class Track;
44 class Xml;
45 
46 
47 struct RouteChannelsDescriptor
48 {
49   // Independent of _inChannels/_outChannels. Typically represents 'Omni' for objects
50   //  which have channels, otherwise it just means the object itself is routable.
51   bool _inRoutable;
52   bool _outRoutable;
53 
54   int _inChannels;
55   int _outChannels;
56 
RouteChannelsDescriptorRouteChannelsDescriptor57   RouteChannelsDescriptor() : _inRoutable(false),
58                               _outRoutable(false),
59                               _inChannels(0),
60                               _outChannels(0) { }
RouteChannelsDescriptorRouteChannelsDescriptor61   RouteChannelsDescriptor(bool inRoutable,
62                           bool outRoutable,
63                           int inChannels,
64                           int outChannels)
65                       : _inRoutable(inRoutable),
66                         _outRoutable(outRoutable),
67                         _inChannels(inChannels),
68                         _outChannels(outChannels) { }
69 };
70 typedef RouteChannelsDescriptor TrackRouteDescriptor;
71 typedef RouteChannelsDescriptor JackRouteDescriptor;
72 typedef RouteChannelsDescriptor MidiDeviceRouteDescriptor;
73 typedef RouteChannelsDescriptor MidiPortRouteDescriptor;
74 
75 struct RouteCapabilitiesStruct
76 {
77   TrackRouteDescriptor _trackChannels;
78   JackRouteDescriptor _jackChannels;
79   MidiDeviceRouteDescriptor _midiDeviceChannels;
80   MidiPortRouteDescriptor _midiPortChannels;
81 
RouteCapabilitiesStructRouteCapabilitiesStruct82   RouteCapabilitiesStruct() : _trackChannels(TrackRouteDescriptor()),
83                               _jackChannels(JackRouteDescriptor()),
84                               _midiDeviceChannels(MidiDeviceRouteDescriptor()),
85                               _midiPortChannels(MidiPortRouteDescriptor()) { }
86 
RouteCapabilitiesStructRouteCapabilitiesStruct87   RouteCapabilitiesStruct(const TrackRouteDescriptor& trackChannels,
88                           const JackRouteDescriptor& jackChannels,
89                           const MidiDeviceRouteDescriptor& midiDeviceChannels,
90                           const MidiPortRouteDescriptor& midiPortChannels) :
91                           _trackChannels(trackChannels),
92                           _jackChannels(jackChannels),
93                           _midiDeviceChannels(midiDeviceChannels),
94                           _midiPortChannels(midiPortChannels) { }
95 };
96 
97 //---------------------------------------------------------
98 //   Route
99 //---------------------------------------------------------
100 
101 class Route {
102   public:
103       enum RouteType { TRACK_ROUTE=0, JACK_ROUTE=1, MIDI_DEVICE_ROUTE=2, MIDI_PORT_ROUTE=3 };
104 
105       union {
106             Track* track;
107             MidiDevice* device;
108             void* jackPort;
109 	    void* voidPointer;
110             };
111 
112       int midiPort;              // Midi port number. Best not to put this in the union to avoid problems?
113 
114       //snd_seq_addr_t alsaAdr;  // TODO
115 
116       // Midi channel, or starting audio source channel (of the owner of this route).
117       // Normally zero for mono or stereo audio tracks, higher for multi-channel audio tracks.
118       int channel;
119       // Number of (audio) channels being routed.
120       int channels;
121       // Starting (audio) destination channel of the remote object (pointed to by the union or port etc.).
122       int remoteChannel;
123 
124       RouteType type;
125 
126       // Always same as the port name. When connection disappears, this holds on to the name.
127       char persistentJackPortName[ROUTE_PERSISTENT_NAME_SIZE];
128 
129       //--------------------------------------------------------
130       // Temporary variables used during latency calculations:
131       // Holds the output latency of this node, so that it can be compared with others.
132       float audioLatencyOut;
133       //--------------------------------------------------------
134 
135       Route(void* t, int ch=-1);
136       Route(Track* t, int ch = -1, int chans = -1);
137       Route(MidiDevice* d, int ch = -1);
138       Route(int port, int ch = -1);
139       Route(const QString&, bool dst, int ch, int rtype = -1);
140       Route();
141       Route(const Route&); // Copy constructor
142       // Useful for generic complete construction.
143       Route(RouteType type_, int midi_port_num_, void* void_pointer_, int channel_, int channels_, int remote_channel_, const char* name_);
144 
145       // Returns a suitable icon for the route based on type, track type etc.
146       // isSource determines whether to return an in-facing icon or an out-facing icon.
147       // isMidi determines whether to return an audio or midi themed icon.
148       QIcon *icon(bool isSource = true, bool isMidi = false) const;
149       // Create string name representation.
150       // preferred_name_or_alias (mainly for Jack routes): -1: No preference 0: Prefer canonical name 1: Prefer 1st alias 2: Prefer 2nd alias.
151       QString name(int preferred_name_or_alias = -1) const;
152       // Fill and return str char name representation.
153       // preferred_name_or_alias (mainly for Jack routes): -1: No preference 0: Prefer canonical name 1: Prefer 1st alias 2: Prefer 2nd alias.
154       char* name(char* str, int str_size, int preferred_name_or_alias = -1) const;
155       // Returns a name suitable for display like "1:Track 5" where the number is the track's index in the track list.
156       // This is useful because in the case of importing a midi file we allow duplicate, often blank, names.
157       // This display string will help identify them. Like "1:", "2:" etc.
158       // preferred_name_or_alias (mainly for Jack routes): -1: No preference 0: Prefer canonical name 1: Prefer 1st alias 2: Prefer 2nd alias.
159       QString displayName(int preferred_name_or_alias = -1) const;
160       bool operator==(const Route&) const;
161       // If the routes support channels, if the given route's channel is -1 meaning all channels, compare matches ONLY if this channel == -1,
162       //  and if the given route's channel is >= 0, compare matches on ANY channel. Useful for example finding router treeview items.
163       bool compare(const Route&) const;
164       bool exists() const;
165       Route& operator=(const Route&);
isValid()166       bool isValid() const {
167             return ((type == TRACK_ROUTE) && (track != 0)) ||
168                    (type == JACK_ROUTE) ||  // For persistent Jack routes: A NULL jackPort is actually valid.
169                    ((type == MIDI_DEVICE_ROUTE) && (device != 0)) ||
170                    ((type == MIDI_PORT_ROUTE) && (midiPort >= 0) && (midiPort < MusECore::MIDI_PORTS));
171             }
172       void read(Xml& xml);
173       void dump() const;
174       };
175 
176 //---------------------------------------------------------
177 //   RouteList
178 //---------------------------------------------------------
179 
180 class RouteList : public std::vector <Route> {
181   public:
find(const Route & r)182       iterator find(const Route& r)             { return std::find(begin(), end(), r); }
find(const Route & r)183       const_iterator find(const Route& r) const { return std::find(begin(), end(), r); }
contains(const Route & r)184       bool contains(const Route& r) const         { return std::find(begin(), end(), r) != end(); }
removeRoute(const Route & r)185       bool removeRoute(const Route& r) {
186         iterator i = std::find(begin(), end(), r);
187         if(i == end())
188           return false;
189         erase(i);
190         return true;
191       }
192       };
193 
194 typedef RouteList::iterator iRoute;
195 typedef RouteList::const_iterator ciRoute;
196 
197 // Returns true if something changed.
198 extern bool addRoute(Route src, Route dst);
199 // Returns true if something changed.
200 extern bool removeRoute(Route src, Route dst);
201 extern void removeAllRoutes(Route src, Route dst);
202 extern Route name2route(const QString&, bool dst, int rtype = -1);
203 // Returns true if the routes are found and they are connected.
204 extern bool routeCanDisconnect(const Route& src, const Route& dst);
205 // Returns true if the routes are found and they are not connected and CAN be connected.
206 extern bool routeCanConnect(const Route& src, const Route& dst);
207 // Returns true if the routes are found and they CAN be connected (even if they are already connected).
208 // If check_types_only is true, it only compares route types.
209 // Otherwise other parameters such as channels are also compared.
210 extern bool routesCompatible(const Route& src, const Route& dst, bool check_types_only = false);
211 
212 } // namespace MusECore
213 
214 // Allow Routes to be a QVariant
215 Q_DECLARE_METATYPE(MusECore::Route)
216 
217 #endif
218 
219