1 /*
2  * @(#)ins/Destination.h 3.00 21 August 2000
3  *
4  * Copyright (c) 2000 Pete Goodliffe (pete@cthree.org)
5  *
6  * This file is part of TSE3 - the Trax Sequencer Engine version 3.00.
7  *
8  * This library is modifiable/redistributable under the terms of the GNU
9  * General Public License.
10  *
11  * You should have received a copy of the GNU General Public License along
12  * with this program; see the file COPYING. If not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14  *
15  */
16 
17 #ifndef TSE3_INS_DESTINATION_H
18 #define TSE3_INS_DESTINATION_H
19 
20 #include "tse3/listen/ins/Destination.h"
21 
22 #include "tse3/Notifier.h"
23 
24 #include <string>
25 #include <cstddef>
26 
27 namespace TSE3
28 {
29     namespace Ins
30     {
31         /**
32          * The Destination class is a simple utility class that can be used to
33          * associate @ref Instrument definitions with MIDI outputs (channel/port
34          * pairs).
35          *
36          * An application can use this to remember what sort of instrument
37          * definition to use for which output; to present the correct program
38          * change information to the user, for example.
39          *
40          * For each port, you may choose one @ref Instrument for every
41          * channel, or may select a number of different @ref Instrument objects
42          * for the different individual channels.
43          *
44          * You may also leave a particular definition unspecified (as zero).
45          *
46          * The Destination class has a secondary purpose of keeping track of
47          * all the currently used @ref Instrument objects, keeping the
48          * list of desinations up to date if any @ref Instrument is removed.
49          *
50          * Since this class operates independantly of a @ref TSE3::MidiScheduler
51          * it cannot track what port numbers are currently valid, and
52          * which are not.
53          *
54          * @short   MIDI destination information utility
55          * @author  Pete Goodliffe
56          * @version 3.00
57          * @see     Instrument
58          */
59         class Destination : public TSE3::Notifier<DestinationListener>
60         {
61             public:
62 
63                 /**
64                  * Creates a Destination object.
65                  *
66                  * Initially no destinations are specified.
67                  */
68                 Destination();
69                 ~Destination();
70 
71                 /**************************************************************
72                  * Managing the list of destinations
73                  *************************************************************/
74 
75                 /**
76                  * Returns the default @ref Instrument.
77                  *
78                  * This is the instrument definition that is returned if
79                  * no other mapping has been made.
80                  *
81                  * By default, this is set to zero.
82                  *
83                  * @return The default instrument definition
84                  * @see    setDefaultInstrument
85                  */
86                 Instrument *defaultInstrument() const;
87 
88                 /**
89                  * Sets the default @ref Instrument.
90                  *
91                  * @param instrument The default definition
92                  * @see   defaultInstrument
93                  */
94                 void setDefaultInstrument(Instrument *instrument);
95 
96                 /**
97                  * Returns whether there is one @ref Instrument selected for
98                  * every channel on this port (true) or whether each channel
99                  * is been assigned separately (false).
100                  *
101                  * @param  port Port number to enquire about
102                  * @return Whether there is one @ref Instrument for every
103                  *         channel on this port
104                  * @see    setPort
105                  * @see    setChannel
106                  */
107                 bool allChannels(int port);
108 
109                 /**
110                  * Returns the @ref Instrument selected for this entire
111                  * port. This instrument is used for every channel on this
112                  * port.
113                  *
114                  * If no instrument has been specified for this @p port, then
115                  * port() returns the @ref defaultInstrument.
116                  *
117                  * If @ref allChannels is false for this @p port then zero
118                  * is returned (you have called this in error).
119                  *
120                  * @param  port Port number to enquire about
121                  * @return The @ref Instrument selected for this port, or 0
122                  *         if no @ref Instrument is specified
123                  * @see    setPort
124                  * @see    channel
125                  */
126                 Instrument *port(int port);
127 
128                 /**
129                  * Sets which instrument is used by this port. This will
130                  * have the side effect of making @ref allChannels return true.
131                  *
132                  * You may specify an @p instrument of zero to unspecify
133                  * an @ref Instrument definition.
134                  *
135                  * @param port Port number to set @ref Instrument for
136                  * @param instrument @ref Instrument to specify. Whilst it's
137                  *                   not essential that this has been added
138                  *                   with @ref addInstrument, it is advised
139                  *                   to do so.
140                  * @see   setChannel
141                  */
142                 void setPort(int port, Instrument *instrument);
143 
144                 /**
145                  * Returns the @ref Instrument selected for this channel/port
146                  * destination.
147                  *
148                  * If no instrument has been specified for this port/channel,
149                  * then @p port returns @ref defaultInstrument.
150                  *
151                  * If @ref allChannels is true for this @p port then the
152                  * @p channel value is ignored.
153                  *
154                  * @param  port    Port number to enquire about
155                  * @param  channel Channel number to enquire about
156                  * @return The @ref Instrument selected for this port, or 0
157                  *         if no @ref Instrument is specified
158                  * @see    setChannel
159                  * @see    port
160                  */
161                 Instrument *channel(int channel, int port);
162 
163                 /**
164                  * Sets which instrument is used by this channel/port pair.
165                  * This will have the side effect of making @ref allChannels
166                  * return false.
167                  *
168                  * You may specify an @p instrument of zero to unspecify
169                  * an @ref Instrument definition.
170                  *
171                  * @param port    Port number to set @ref Instrument for
172                  * @param channel Channel number to set @ref Instrument for
173                  * @param instrument @ref Instrument to specify. Whilst it's
174                  *                   not essential that this has been added
175                  *                   with @ref addInstrument, it is advised
176                  *                   to do so.
177                  * @see   setChannel
178                  */
179                 void setChannel(int channel, int port,
180                                 Instrument *instrument);
181 
182                 /**************************************************************
183                  * Managing the list of instruments
184                  *************************************************************/
185 
186                 /**
187                  * Returns the number of @ref Instrument objects currently
188                  * managed by the Destination object.
189                  */
190                 size_t numInstruments() const;
191 
192                 /**
193                  * Returns the @ref Instrument at the given index.
194                  * The list of @ref Instrument object is ordered
195                  * alphabetically.
196                  *
197                  * @param  index Index into @ref Instrument list (between
198                  *               0 and @ref noInstruments()).
199                  * @return @ref Instrument object at @p index
200                  * @see    noInstruments
201                  */
202                 Instrument *instrument(size_t index);
203 
204                 /**
205                  * Returns the @ref Instrument with the given title,
206                  * or zero if there is no such @ref Instrument.
207                  *
208                  * @param  title @ref Instrument title to search for
209                  * @return @ref Instrument object or 0
210                  */
211                 Instrument *instrument(const std::string &title);
212 
213                 /**
214                  * Adds the specified @ref Instrument to the list of
215                  * @ref Instrument objects. You can only insert a given
216                  * @ref Instrument once. The instrument is inserted into the
217                  * list in alphabetical order of title.
218                  *
219                  * The @ref Instrument object is considered to be 'owned' by
220                  * the Destination class, and will be deleted when the
221                  * Destination is.
222                  *
223                  * @param instrument New @ref Instrument object to insert
224                  * @see   removeInstrument
225                  */
226                 void addInstrument(Instrument *instrument);
227 
228                 /**
229                  * Removed the specified @ref Instrument from the list of
230                  * @ref Instrument objects. If @p instrument is being used
231                  * as a destination, then the destination link is removed.
232                  *
233                  * Once removed it is your responsibility to delete the
234                  * @ref Instrument.
235                  *
236                  * @param instrument @ref Instrument object to remove
237                  * @see   addInstrument
238                  */
239                 void removeInstrument(Instrument *instrument);
240 
241             private:
242 
243                 Destination(const Destination &);
244                 Destination &operator=(const Destination &);
245 
246                 class DestinationImpl *pimpl;
247 
index(int port,int channel)248                 size_t index(int port, int channel)
249                 {
250                     return (port*16) + channel;
251                 }
252         };
253     }
254 }
255 
256 #endif
257