This file is indexed.

/usr/include/tse3/ins/Instrument.h is in libtse3-dev 0.3.1-4.3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
/*
 * @(#)ins/Instrument.h 3.00 23 August 1999
 *
 * Copyright (c) 2000 Pete Goodliffe (pete@cthree.org)
 *
 * This file is part of TSE3 - the Trax Sequencer Engine version 3.00.
 *
 * This library is modifiable/redistributable under the terms of the GNU
 * General Public License.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; see the file COPYING. If not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */

#ifndef TSE3_INS_INSTRUMENT_H
#define TSE3_INS_INSTRUMENT_H

#include <list>
#include <utility>
#include <vector>
#include <string>
#include <iosfwd>

namespace TSE3
{
    class Progress;

    /**
     * The @p Ins namespace contains classes that implement the Cakewalk
     * instrument file parsing routines and provide name lookup for bank/patch
     * and controller numbers.
     *
     * The facilities offered here are utilities that an application may use,
     * and are not part of the core @ref TSE3 functionality.
     *
     * The @ref TSE3::Ins::CakewalkInstrumentFile class is the main entrance
     * onto @p Ins facilities.
     *
     * You can get Cakewalk instrument definition files for practically
     * every piece of MIDI hardware in existence, which is why they have been
     * adopted by the TSE3 library. They are most easily obtained from the
     * @p www.cakewalk.com website; follow the "Download" link and select
     * "Instrument Definitions".
     *
     * @short   Utility classes for MIDI instrument definitions
     * @author  Pete Goodliffe
     * @version 3.00
     * @see     TSE3
     */
    namespace Ins
    {
        class PatchData;
        class ControlData;
        class RpnData;
        class NrpnData;
        class NoteData;

        /**
         * Bank select values can be expressed as single 14 bit numbers
         * (Cakewalk instrument files use this format) or as separate LSB and
         * MSBs (the MIDI format uses this format).
         *
         * This function converts a 14 bit bank number into the LSB portion.
         * If @p bank is -1, returns -1.
         *
         * @param  bank 14 bit bank select number
         * @return LSB value
         * @see    bankMSB
         * @see    bankFromBytes
         */
        inline int bankToLSB(int bank)
        {
            return (bank < 0) ? bank : bank & 0x7f;
        }

        /**
         * Bank select values can be expressed as single 14 bit numbers
         * (Cakewalk instrument files use this format) or as separate LSB and
         * MSBs (the MIDI format uses this format).
         *
         * This function converts a 14 bit bank number into the MSB portion.
         * If @p bank is -1, returns -1.
         *
         * @param  bank 14 bit bank select number
         * @return MSB value
         * @see    bankLSB
         * @see    bankFromBytes
         */
        inline int bankToMSB(int bank)
        {
            return (bank < 0) ? bank : bank >> 7;
        }

        /**
         * Bank select values can be expressed as single 14 bit numbers
         * (Cakewalk instrument files use this format) or as separate LSB and
         * MSBs (the MIDI format uses this format).
         *
         * This function converts a bank LSB and MSB into a 14 bit bank number.
         * If @p bank is -1, returns -1.
         *
         * @param  bankLSB Bank LSB value
         * @param  bankMSB Bank MSB value
         * @return bank 14 bit bank select number
         * @see    bankLSB
         * @see    bankMSB
         */
        inline int bankFromBytes(int bankLSB, int bankMSB)
        {
            return (bankLSB < 0 || bankMSB < 0) ? -1 : (bankMSB<<7) | bankLSB;
        }

        /**
         * A Voice struct holds information about a voice - the bank and patch
         * values. It is based on pair<int,int> where the first in is the
         * bank value and the second int is the patch value.
         *
         * Bank values are defined to be (MSB<<7)+LSB.
         *
         * The value -1 denotes a wildcard - it matches any bank/patch.
         *
         * This is a value type.
         *
         * @short   Instrument voice definition
         * @author  Pete Goodliffe
         * @version 3.00
         */
        struct Voice : public std::pair<int, int>
        {
            /**
             * Creates a Voice with the given bank and patch values.
             *
             * @param bank  New bank value in the form (MSB<<7)+LSB
             * @param patch New patch value
             */
            Voice(int bank, int patch);

            /**
             * Creates a Voice with the given bank and patch values.
             *
             * @param bankMSB Bank select MSB
             * @param bankLSB Bank select LSB
             * @param patch   New patch value
             */
            Voice(int bankMSB, int bankLSB, int patch);

            /**
             * Returns the bank value in the form (bankMSB<<7)+bankLSB.
             */
            int bank() const { return first; }

            /**
             * Returns the bank MSB value.
             */
            int bankMSB()  const { return first >> 7; }

            /**
             * Returns the bank LSB value.
             */
            int bankLSB()  const { return first & 0x7f; }

            /**
             * Returns the patch value.
             */
            int patch() const { return second; }

            /**
             * Comparison operator. Compares banks first, then patches.
             */
            int operator <(const Voice &v) const;
        };

        /**
         * The Instrument class holds information about a specific MIDI
         * instrument. This includes the voices it provides, control commands
         * it understands, drum note names and so on.
         *
         * The Instrument class is based on the instrument definitions supplied
         * in Cakewalk .ins instrument definition files.
         *
         * @short   MIDI Instrument definition
         * @author  Pete Goodliffe
         * @version 3.00
         */
        class Instrument
        {
            public:

                /**
                 * Creates an instrument with the given name from information
                 * contained in the given file. This file will be a
                 * Cakewalk .ins file.
                 *
                 * Whilst the file is being loaded, the progess can be reported
                 * via the @ref TSE3::Progess interface.
                 *
                 * @param title   The title of this instrument
                 * @param file    The file to take input from
                 * @param progess @ref TSE3::Progress callback, or zero for
                 *                no callback
                 */
                Instrument(const std::string &title,
                           const std::string &filename,
                           TSE3::Progress    *progess = 0);

                /**
                 * Returns the title of this instrument.
                 *
                 * @return Title of this instrument
                 */
                const std::string &title() const { return _title; }

                /**
                 * Returns the filename of the source of the instrument
                 * definition.
                 *
                 * @return Filename of this instrument's definition
                 */
                const std::string &filename() const { return _filename; }

                /**
                 * Sets the title.
                 *
                 * @param title New instrument title
                 */
                void setTitle(const std::string &title);

                /**
                 * Returns the BankSelMethod, the values for this are defined
                 * as the BankSelMethod_XXX constants.
                 *
                 * @return Bank select method
                 */
                int bankSelMethod() const { return _bankSelMethod; }

                /**
                 * Sets the BankSelMethod.
                 *
                 * @param b New bank select method
                 */
                void setBankSelMethod(int b);

                /**
                 * An enum type defining the Instrument's bank select method.
                 * It has the following values
                 * @li @p BankSelMethod_Normal
                 *     For normal instruments: uses LSB, MSB and patch.
                 * @li @p BankSelMethod_MSB
                 *     For instruments that only use MSB and patch.
                 * @li @p BankSelMethod_LSB
                 *     For instruments that only use LSB and patch.
                 * @li @p BankSelMethod_Patch
                 *     For instruments that only use patch.
                 */
                enum BankSelMethod
                {
                    BankSelMethod_Normal = 0,
                    BankSelMethod_MSB    = 1,
                    BankSelMethod_LSB    = 2,
                    BankSelMethod_Patch  = 3
                };

                /**
                 * Returns the UseNotesAsControllers value.
                 *
                 * @return Whenther to use notes as controllers
                 */
                bool useNotesAsController() const
                {
                    return _useNotesAsControllers;
                }

                /**
                 * Sets the UseNotesAsControllers value.
                 *
                 * @param u New use notes as controllers value
                 */
                void setUseNotesAsControllers(bool u);

                /**
                 * Returns the number of banks of patch data defined
                 * by this instrument.
                 *
                 * @return Number of banks of patches
                 */
                size_t numBanks() const { return banks.size(); }

                /**
                 * Returns the bank number in the form:
                 * <pre>
                 *      bankLSB + (bankMSB<<7)
                 * </pre>
                 * for the bank with index @p index.
                 *
                 * If you call this method with an invalid parameter, the
                 * result is undefined.
                 *
                 * @return Bank change values for bank with given index
                 */
                int bank(int index) const { return banks[index]; }

                /**
                 * Returns the bank number in the form:
                 * <pre>
                 *      bankLSB + (bankMSB<<7)
                 * </pre>
                 * for the bank for @ref Voice @p voice. If there is no such
                 * @ref Voice defined, then -2 will be returned.
                 *
                 * @return Bank change values for bank with given index
                 */
                int bank(const Voice &voice) const;

                /**
                 * Returns the bank LSB for the set of patches with index
                 * @p index.
                 *
                 * If you call this method with an invalid parameter, the
                 * result is undefined.
                 *
                 * @return Bank LSB value for bank with given index
                 * @see    bankMSB
                 */
                int bankLSB(int index) const;

                /**
                 * Returns the bank MSB for the set of patches with index
                 * @p index.
                 *
                 * If you call this method with an invalid parameter, the
                 * result is undefined.
                 *
                 * @return Bank MSB value for bank with given index
                 * @see    bankLSB
                 */
                int bankMSB(int index) const;

                /**
                 * Returns the @ref PatchData object for the given bank.
                 *
                 * @param  index Bank index
                 * @return Pointer to @ref PatchData for bank, or 0
                 */
                PatchData *patch(int index) const { return patches[index]; }

                /**
                 * Returns the @ref PatchData object for the given bank, or 0
                 * if there is none.
                 *
                 * Note that this function takes the bank change number (as
                 * read from @ref bank()), not the bank index.
                 *
                 * If there is no PatchData for this bank, then zero is
                 * returned.
                 *
                 * You can specify @p bank as -1 to find the 'catch all' bank,
                 * and if your bank number is undefined, but there is a
                 * ctach all patch set, that will be returned.
                 *
                 * @param  bank Bank number
                 * @return Pointer to @ref PatchData for bank, or 0
                 */
                PatchData *patchForBank(int bank) const;

                /**
                 * Like the @ref patchForBank(int) above, but takes the
                 * LSB and MSB parameters separately. This function actually
                 * fowards responsibility onto the other version. It is
                 * provided as a convenience.
                 *
                 * If either of the LSB or MSB parameters are -1, then the
                 * overal bank value passed on is -1.
                 *
                 * @param  bankLSB Bank number LSB
                 * @param  bankMSB Bank number MSB
                 * @return Pointer to @ref PatchData for bank, or 0
                 */
                PatchData *patchForBank(int bankLSB, int bankMSB) const;

                /**
                 * Returns the number of sets of @ref NoteData defined
                 * by this instrument.
                 *
                 * @return Number of patches @ref NoteData objects
                 */
                size_t numKeys() const { return keys.size(); }

                /**
                 * Returns the @ref NoteData with the given @p index.
                 *
                 * If you call this method with an invalid parameter, the
                 * result is undefined.
                 *
                 * @return @ref NoteData for index
                 */
                NoteData *key(size_t index) const { return keys[index].second; }

                /**
                 * Returns the @ref NoteData for the given @ref Voice.
                 *
                 * If there is no such @ref Voice, then zero is returned.
                 *
                 * @return @ref NoteData for index
                 */
                NoteData *keyForVoice(const Voice &voice) const;

                /**
                 * Returns the number of drum statuses defined by this
                 * instrument.
                 *
                 * @return Number of drum statuses
                 */
                size_t numDrums() const { return drumFlags.size(); }

                /**
                 * Returns the drum @ref Voice with the given @p index.
                 *
                 * If you call this method with an invalid parameter, the
                 * result is undefined.
                 *
                 * @return @ref Voice for index
                 */
                Voice drum(size_t index) const { return drumFlags[index]; }

                /**
                 * Returns whether the specified @p voice is defined to be
                 * a drum sound or not (this implies that note data should
                 * be opened in a "drum" editor).
                 *
                 * @return Whether voice is a drum sound
                 */
                bool isDrum(const Voice &voice) const;

                /**
                 * Returns the @ref ControlData for this Instrument, if there
                 * is any defined, or zero if there is none.
                 *
                 * @return ControlData for this instrument
                 */
                ControlData *control() const { return _control; }

                /**
                 * Returns the @ref RpnData for this Instrument, if there
                 * is any defined, or zero if there is none.
                 *
                 * @return RpnData for this instrument
                 */
                RpnData *rpn() const { return _rpn; }

                /**
                 * Returns the @ref NrpnData for this Instrument, if there
                 * is any defined, or zero if there is none.
                 *
                 * @return NrpnData for this instrument
                 */
                NrpnData *nrpn() const { return _nrpn; }

                /**
                 * Write the minimal .ins file for this instrument.
                 *
                 * @param out ostream to write output to
                 */
                void write(std::ostream &out);

            private:

                /**
                 * Loads the instrument from the given .ins file.
                 * Pre: title has been set up already. Other values have
                 * defaults.
                 */
                void load(std::istream &in, TSE3::Progress *progress);

                /**
                 * Parses a line of the instrument definition.
                 * The istream is not used, but may be passed onto child
                 * objects.
                 */
                void parseLine(const std::string &line, std::istream &in);

                std::string _title;
                std::string _filename;
                int         _bankSelMethod;
                bool        _useNotesAsControllers;

                std::vector<PatchData *>                    patches;
                std::vector<int>                            banks;

                std::vector<std::pair<Voice, NoteData *> >  keys;
                std::vector<Voice>                          drumFlags;

                ControlData                                *_control;
                RpnData                                    *_rpn;
                NrpnData                                   *_nrpn;
        };

        /**
         * A base class for instrument data: many .ins file sections are based
         * on simple lists of 0..127 values. This is a base class for such
         * lists.
         *
         * @short   Instrument data container class
         * @author  Pete Goodliffe
         * @version 3.00
         */
        class InstrumentData
        {
            public:

                /**
                 * Returns the title of this data group.
                 *
                 * @return Title of the data group
                 */
                const std::string &title() const { return _title; }

                /**
                 * Returns the name of the item with the given @p index.
                 * the index value must be between 0 and 127, or the results
                 * are undefined.
                 *
                 * If no name has been defined for this element, returns
                 * an empty string.
                 *
                 * @return Name of the data element
                 */
                const std::string &name(size_t index) const
                {
                    std::string *s = _names[index];
                    return s ? *s : empty;
                }

                /**
                 * Write the .ins file subsection.
                 *
                 * @param out ostream to write output to
                 */
                void write(std::ostream &out) const;

            protected:

                /**
                 * Contructor is private since this is a base class.
                 */
                InstrumentData(std::string const &title,
                               std::string const &insHeading,
                               std::istream      &in);

                /**
                 * The .ins file heading for this section type. Derived classes
                 * <b>MUST</b> override this for load) to work.
                 *
                 * @see load
                 */
                const std::string insHeading;

                /**
                 * Loads the subsection 'secname' from the .ins section
                 * 'insHeading'.
                 * Pre: title and insHeading have been set up.
                 */
                void load(const std::string &secname, std::istream &in);

                std::string  _title;
                std::string *_names[128];

                static std::string empty;
        };

        /**
         * This class represents a group of related patches - they will have
         * the same bank select values.
         *
         * @short   Instrument patch data group
         * @author  Pete Goodliffe
         * @version 3.00
         */
        class PatchData : public InstrumentData
        {
            public:
                PatchData(std::string const &title, std::istream &in)
                    : InstrumentData(title, ".Patch Names", in) {}
        };

        /**
         * This class represents a group of note names.
         *
         * @short   Instrument note data group
         * @author  Pete Goodliffe
         * @version 3.00
         */
        class NoteData : public InstrumentData
        {
            public:
                NoteData(std::string const &title, std::istream &in)
                    : InstrumentData(title, ".Note Names", in) {}
        };

        /**
         * This class represents a group of MIDI control change defintions.
         *
         * @short   Instrument MIDI controller data group
         * @author  Pete Goodliffe
         * @version 3.00
         */
        class ControlData : public InstrumentData
        {
            public:
                ControlData(std::string const &title, std::istream &in)
                    : InstrumentData(title, ".Controller Names", in) {}
        };

        /**
         * This class represents a group of NRPN defintions.
         *
         * @short   Instrument NRPN data group
         * @author  Pete Goodliffe
         * @version 3.00
         */
        class NrpnData : public InstrumentData
        {
            public:
                NrpnData(std::string const &title, std::istream &in)
                    : InstrumentData(title, ".NRPN Names", in) {}
        };

        /**
         * This class represents a group of RPN defintions.
         *
         * @short   Instrument RPN data group
         * @author  Pete Goodliffe
         * @version 3.00
         */
        class RpnData : public InstrumentData
        {
            public:
                RpnData(std::string const &title, std::istream &in)
                    : InstrumentData(title, ".RPN Names", in) {}
        };

        /**
         * The class represents a Cakewalk .ins file.
         *
         * It provides a mechanism for listing all instruments provided by a
         * particular .ins file, and for creating an Instrument object from it.
         *
         * The .ins file format is not documented. However, the documentation
         * that ships with the TSE3 library contains a description of this
         * format.
         *
         * @short   Cakewalk .ins file parser
         * @author  Pete Goodliffe
         * @version 3.00
         * @see     Instrument
         */
        class CakewalkInstrumentFile
        {
            public:

                /**
                 * Create an object for the given file.
                 *
                 * @param filename The name of the Cakewalk .ins file
                 */
                CakewalkInstrumentFile(const std::string &filename);

                /**
                 * Returns a set of the instrument titles in the .ins file.
                 *
                 * The first time you call this method, the file will be
                 * searched. Whilst this is being done you can be informted
                 * of progress via the @ref TSE3::Progress interface.
                 *
                 * @param  progress @ref TSE3::Progess callback, or zero for no
                 *                  callback
                 * @return List of instrument titles in the .ins file
                 */
                const std::list<std::string>
                    &instruments(TSE3::Progress *progress = 0);

                /**
                 * Factory method that creates an Instrument object for the
                 * given instrument title from this CakewalkInstrumentFile.
                 *
                 * You can supply a @ref TSE3::Progess interface to be informed
                 * of progress.
                 *
                 * @param  title    The title of the instrument to create
                 * @param  progress @ref TSE3::Progess callback, or zero for no
                 *                  callback
                 * @return New instrument object - you must delete this object
                 */
                Instrument *instrument(const std::string &title,
                                       TSE3::Progress *progress = 0);

            private:

                std::string            filename;
                bool                   searched_yet;
                std::list<std::string> ins;
        };
    }
}

#endif