32 |
#include "../../common/File.h" |
#include "../../common/File.h" |
33 |
#include "../../common/Path.h" |
#include "../../common/Path.h" |
34 |
#include "../../common/global_private.h" |
#include "../../common/global_private.h" |
35 |
|
#include "LookupTable.h" |
36 |
|
|
37 |
namespace sfz |
namespace sfz |
38 |
{ |
{ |
108 |
} |
} |
109 |
} |
} |
110 |
|
|
111 |
bool |
bool Region::OnKey(const Query& q) { |
112 |
Region::OnKey(uint8_t chan, uint8_t key, uint8_t vel, |
// As the region comes from a LookupTable search on the query, |
113 |
int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft, |
// the following parameters are not checked here: chan, key, |
114 |
uint8_t prog, float rand, trigger_t trig, uint8_t* cc, |
// vel, chanaft, polyaft, prog, sw_previous, cc. They are all |
115 |
float timer, bool* sw, uint8_t last_sw_key, uint8_t prev_sw_key) |
// handled by the lookup table. |
116 |
{ |
bool is_triggered( |
117 |
// chan (MIDI channel) |
q.bend >= lobend && q.bend <= hibend && |
118 |
// key (MIDI note) |
q.bpm >= lobpm && q.bpm < hibpm && |
119 |
// vel (MIDI velocity) |
q.rand >= lorand && q.rand < hirand && |
120 |
|
q.timer >= lotimer && q.timer <= hitimer && |
|
// bend (MIDI pitch bend) |
|
|
// bpm (host BPM) |
|
|
// chanaft (MIDI channel pressure) |
|
|
// polyaft (MIDI polyphonic aftertouch) |
|
|
// prog (MIDI program change) |
|
|
// rand (generated random number) |
|
|
// trigger (how it was triggered) |
|
|
// cc (all 128 CC values) |
|
|
|
|
|
// timer (time since previous region in the group was triggered) |
|
|
// sw (the state of region key switches, 128 possible values) |
|
|
// last_sw_key (the last key pressed in the key switch range) |
|
|
// prev_sw_key (the previous note value) |
|
|
|
|
|
bool is_triggered ( |
|
|
chan >= lochan && chan <= hichan && |
|
|
key >= lokey && key <= hikey && |
|
|
vel >= lovel && vel <= hivel && |
|
|
bend >= lobend && bend <= hibend && |
|
|
bpm >= lobpm && bpm < hibpm && |
|
|
chanaft >= lochanaft && chanaft <= hichanaft && |
|
|
polyaft >= lopolyaft && polyaft <= hipolyaft && |
|
|
prog >= loprog && prog <= hiprog && |
|
|
rand >= lorand && rand < hirand && |
|
|
timer >= lotimer && timer <= hitimer && |
|
121 |
|
|
122 |
( sw_last == -1 || |
( sw_last == -1 || |
123 |
((sw_last >= sw_lokey && sw_last <= sw_hikey) ? (last_sw_key == sw_last) : false) ) && |
((sw_last >= sw_lokey && sw_last <= sw_hikey) ? (q.last_sw_key == sw_last) : false) ) && |
124 |
|
|
125 |
( sw_down == -1 || |
( sw_down == -1 || |
126 |
((sw_down >= sw_lokey && (sw_hikey == -1 || sw_down <= sw_hikey)) ? (sw[sw_down]) : false) ) && |
((sw_down >= sw_lokey && (sw_hikey == -1 || sw_down <= sw_hikey)) ? (q.sw[sw_down]) : false) ) && |
127 |
|
|
128 |
( sw_up == -1 || |
( sw_up == -1 || |
129 |
((sw_up >= sw_lokey && (sw_hikey == -1 || sw_up <= sw_hikey)) ? (!sw[sw_up]) : true) ) && |
((sw_up >= sw_lokey && (sw_hikey == -1 || sw_up <= sw_hikey)) ? (!q.sw[sw_up]) : true) ) && |
130 |
|
|
131 |
( sw_previous == -1 || |
((trigger & q.trig) != 0) |
|
prev_sw_key == sw_previous ) && |
|
|
|
|
|
((trigger & trig) != 0) |
|
132 |
); |
); |
133 |
|
|
134 |
if (!is_triggered) |
if (!is_triggered) |
135 |
return false; |
return false; |
136 |
|
|
|
for (int i = 0; i < 128; ++i) |
|
|
{ |
|
|
if (locc[i] != -1 && hicc[i] != -1 && !(cc[i] >= locc[i] && cc[i] <= hicc[i])) |
|
|
return false; |
|
|
} |
|
|
|
|
137 |
// seq_position has to be checked last, so we know that we |
// seq_position has to be checked last, so we know that we |
138 |
// increment the right counter |
// increment the right counter |
139 |
is_triggered = (seq_counter == seq_position); |
is_triggered = (seq_counter == seq_position); |
235 |
{ |
{ |
236 |
this->name = name; |
this->name = name; |
237 |
this->pSampleManager = pSampleManager ? pSampleManager : this; |
this->pSampleManager = pSampleManager ? pSampleManager : this; |
238 |
|
pLookupTable = 0; |
239 |
} |
} |
240 |
|
|
241 |
Instrument::~Instrument() |
Instrument::~Instrument() |
242 |
{ |
{ |
243 |
for(int i = 0; i < regions.size(); i++) { |
for (int i = 0; i < regions.size(); i++) { |
244 |
delete (regions[i]); |
delete regions[i]; |
245 |
} |
} |
246 |
regions.clear(); |
delete pLookupTable; |
247 |
} |
} |
248 |
|
|
249 |
std::vector<Region*> Instrument::GetRegionsOnKey ( |
void Query::search(const Instrument* pInstrument) { |
250 |
uint8_t chan, uint8_t key, uint8_t vel, |
pRegionList = &pInstrument->pLookupTable->query(*this); |
251 |
int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft, |
regionIndex = 0; |
252 |
uint8_t prog, float rand, trigger_t trig, uint8_t* cc, |
} |
|
float timer, bool* sw, uint8_t last_sw_key, uint8_t prev_sw_key |
|
|
) { |
|
|
std::vector<Region*> v; |
|
|
for (int i = 0; i < regions.size(); i++) { |
|
|
if (regions[i]->OnKey ( |
|
|
chan, key, vel, bend, bpm, chanaft, polyaft, prog, |
|
|
rand, trig, cc, timer, sw, last_sw_key, prev_sw_key) |
|
|
) { v.push_back(regions[i]); } |
|
|
} |
|
253 |
|
|
254 |
return v; |
Region* Query::next() { |
255 |
|
for ( ; regionIndex < pRegionList->size() ; regionIndex++) { |
256 |
|
if ((*pRegionList)[regionIndex]->OnKey(*this)) { |
257 |
|
return (*pRegionList)[regionIndex++]; |
258 |
|
} |
259 |
|
} |
260 |
|
return 0; |
261 |
} |
} |
262 |
|
|
263 |
bool Instrument::DestroyRegion(Region* pRegion) { |
bool Instrument::DestroyRegion(Region* pRegion) { |
328 |
trigger = TRIGGER_ATTACK; |
trigger = TRIGGER_ATTACK; |
329 |
|
|
330 |
group = 0; |
group = 0; |
331 |
off_by.unset(); |
off_by = 0; |
332 |
off_mode = OFF_FAST; |
off_mode = OFF_FAST; |
333 |
|
|
334 |
// sample player |
// sample player |
888 |
} |
} |
889 |
} |
} |
890 |
} |
} |
891 |
|
|
892 |
|
_instrument->pLookupTable = new LookupTable(_instrument); |
893 |
} |
} |
894 |
|
|
895 |
File::~File() |
File::~File() |
1001 |
else if ("hivel" == key) pCurDef->hivel = ToInt(value); |
else if ("hivel" == key) pCurDef->hivel = ToInt(value); |
1002 |
else if ("lobend" == key) pCurDef->lobend = ToInt(value); |
else if ("lobend" == key) pCurDef->lobend = ToInt(value); |
1003 |
else if ("hibend" == key) pCurDef->hibend = ToInt(value); |
else if ("hibend" == key) pCurDef->hibend = ToInt(value); |
1004 |
else if ("lobpm" == key) pCurDef->lobpm = ToInt(value); |
else if ("lobpm" == key) pCurDef->lobpm = ToFloat(value); |
1005 |
else if ("hibpm" == key) pCurDef->hibpm = ToInt(value); |
else if ("hibpm" == key) pCurDef->hibpm = ToFloat(value); |
1006 |
else if ("lochanaft" == key) pCurDef->lochanaft = ToInt(value); |
else if ("lochanaft" == key) pCurDef->lochanaft = ToInt(value); |
1007 |
else if ("hichanaft" == key) pCurDef->hichanaft = ToInt(value); |
else if ("hichanaft" == key) pCurDef->hichanaft = ToInt(value); |
1008 |
else if ("lopolyaft" == key) pCurDef->lopolyaft = ToInt(value); |
else if ("lopolyaft" == key) pCurDef->lopolyaft = ToInt(value); |
1037 |
else if ("off_by" == key || "offby" == key) pCurDef->off_by = ToInt(value); |
else if ("off_by" == key || "offby" == key) pCurDef->off_by = ToInt(value); |
1038 |
else if ("off_mode" == key || "offmode" == key) |
else if ("off_mode" == key || "offmode" == key) |
1039 |
{ |
{ |
1040 |
if (value == "fast") _current_group->off_mode = OFF_FAST; |
if (value == "fast") pCurDef->off_mode = OFF_FAST; |
1041 |
else if (value == "normal") _current_group->off_mode = OFF_NORMAL; |
else if (value == "normal") pCurDef->off_mode = OFF_NORMAL; |
1042 |
} |
} |
1043 |
|
|
1044 |
// sample player |
// sample player |