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