1 /*************************************************************************** 2 * * 3 * LinuxSampler - modular, streaming capable sampler * 4 * * 5 * Copyright (C) 2010 Andreas Persson * 6 * * 7 * This program is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU General Public License as published by * 9 * the Free Software Foundation; either version 2 of the License, or * 10 * (at your option) any later version. * 11 * * 12 * This program is distributed in the hope that it will be useful, * 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 15 * GNU General Public License for more details. * 16 * * 17 * You should have received a copy of the GNU General Public License * 18 * along with this program; if not, write to the Free Software * 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, * 20 * MA 02110-1301 USA * 21 ***************************************************************************/ 22 23 #ifndef SFZ_LOOKUPTABLE_H 24 #define SFZ_LOOKUPTABLE_H 25 26 #include <vector> 27 28 #include "sfz.h" 29 #include "../../common/ArrayList.h" 30 31 namespace sfz { 32 33 /** 34 * Lookup table for fast access to regions in an sfz instrument. 35 * 36 * The table is organized in two levels. First, the values of the 37 * dimensions actually in use by the instrument (could be key, 38 * velocity, controller values, etc) are used as indexes in a set 39 * of integer arrays. The resulting integers are then added 40 * together and the sum is used as an index in an array of lists 41 * of regions. 42 * 43 * The first level is used to make the second array smaller. An 44 * instrument with three key zones and two velocity zones will 45 * have two integer arrays, each of size 128, one for key number, 46 * one for velocity. The region array only needs to be six items 47 * big, as there are only 2 * 3 possible zone variations. 48 */ 49 class LookupTable { 50 public: 51 /** 52 * Constructs a lookup table for the instrument. If triggercc 53 * is specified, the lookup table is made for regions 54 * triggered by the MIDI controller, otherwise the table is 55 * made for ordinary note-on triggered regions. 56 * 57 * @param instrument - instrument 58 * @param triggercc - controller number or -1 59 */ 60 LookupTable(const Instrument* instrument, int triggercc = -1); 61 62 ~LookupTable(); 63 64 /** 65 * Performs a lookup in the table of regions. 66 * 67 * @param q - query with constraints on key, velocity, etc. 68 * @returns list of regions matching the query 69 */ 70 LinuxSampler::ArrayList<Region*>& query(const Query& q) const; 71 72 private: 73 struct DimDef; 74 75 static const DimDef dimDefs[]; // list of possible dimensions 76 std::vector<int> dims; // dimensions used by the instrument 77 78 // control change dimensions used by the instrument 79 std::vector<int> ccs; 80 81 // arrays mapping dimension values to regionArr offsets 82 int** mapArr; 83 84 // second level array with lists of regions 85 LinuxSampler::ArrayList<Region*>* regionArr; 86 87 // pointers to used dimension arguments in the Query object 88 const uint8_t Query::** qargs; 89 90 // array with CCs used by the instrument 91 int* ccargs; 92 93 94 // helper functions for the constructor 95 static int fillMapArr(const std::vector<Region*>& regions, 96 const int Definition::* lo, 97 const int Definition::* hi, 98 int min, int max, int* a); 99 static int fillMapArr(const std::vector<Region*>& regions, 100 int cc, int* a, int triggercc); 101 void fillRegionArr(const int* len, Region* region, 102 std::vector<int>::size_type dim, int j, 103 int triggercc); 104 }; 105 } 106 107 #endif 108