/usr/include/tse3/ins/Instrument.h is in libtse3-dev 0.3.1-4.3ubuntu1.
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
|