32 |
|
|
33 |
typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits; |
typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits; |
34 |
|
|
35 |
|
typedef std::map<gig::DimensionRegion*, DimensionZones> VelocityZones; |
36 |
|
|
37 |
/////////////////////////////////////////////////////////////////////////// |
/////////////////////////////////////////////////////////////////////////// |
38 |
// private functions |
// private functions |
39 |
|
|
265 |
static DimensionRegionUpperLimits getDimensionRegionUpperLimits(gig::DimensionRegion* dimRgn) { |
static DimensionRegionUpperLimits getDimensionRegionUpperLimits(gig::DimensionRegion* dimRgn) { |
266 |
DimensionRegionUpperLimits limits; |
DimensionRegionUpperLimits limits; |
267 |
gig::Region* rgn = dimRgn->GetParent(); |
gig::Region* rgn = dimRgn->GetParent(); |
268 |
for (int d = 0; d < rgn->Dimensions; ++d) { |
for (uint d = 0; d < rgn->Dimensions; ++d) { |
269 |
const gig::dimension_def_t& def = rgn->pDimensionDefinitions[d]; |
const gig::dimension_def_t& def = rgn->pDimensionDefinitions[d]; |
270 |
limits[def.dimension] = dimRgn->DimensionUpperLimits[d]; |
limits[def.dimension] = dimRgn->DimensionUpperLimits[d]; |
271 |
} |
} |
293 |
*/ |
*/ |
294 |
inline int baseBits(gig::dimension_t type, gig::Region* rgn) { |
inline int baseBits(gig::dimension_t type, gig::Region* rgn) { |
295 |
int previousBits = 0; |
int previousBits = 0; |
296 |
for (int i = 0; i < rgn->Dimensions; ++i) { |
for (uint i = 0; i < rgn->Dimensions; ++i) { |
297 |
if (rgn->pDimensionDefinitions[i].dimension == type) break; |
if (rgn->pDimensionDefinitions[i].dimension == type) break; |
298 |
previousBits += rgn->pDimensionDefinitions[i].bits; |
previousBits += rgn->pDimensionDefinitions[i].bits; |
299 |
} |
} |
346 |
return zones; |
return zones; |
347 |
} |
} |
348 |
|
|
349 |
|
static VelocityZones getVelocityZones(gig::Region* rgn) { |
350 |
|
VelocityZones zones; |
351 |
|
for (uint i = 0; i < rgn->DimensionRegions; ++i) { |
352 |
|
gig::DimensionRegion* dimRgn = rgn->pDimensionRegions[i]; |
353 |
|
zones[dimRgn] = preciseDimensionZonesFor(gig::dimension_velocity, dimRgn); |
354 |
|
} |
355 |
|
return zones; |
356 |
|
} |
357 |
|
|
358 |
/** @brief Copy all DimensionRegions from source Region to target Region. |
/** @brief Copy all DimensionRegions from source Region to target Region. |
359 |
* |
* |
360 |
* Copies the entire articulation informations (including sample reference of |
* Copies the entire articulation informations (including sample reference of |
375 |
* regions shall be copied to |
* regions shall be copied to |
376 |
* @param iSrcLayer - layer number of the source region where the dimension |
* @param iSrcLayer - layer number of the source region where the dimension |
377 |
* regions shall be copied from |
* regions shall be copied from |
378 |
|
* @param dstVelocityZones - all precise velocity zones for destination region |
379 |
|
* (since this information is stored on |
380 |
|
* DimensionRegion level and this function is |
381 |
|
* modifying target DimensionRegions, this |
382 |
|
* informations thus needs to be retrieved before |
383 |
|
* calling this function) |
384 |
* @param dimCase - just for internal purpose (function recursion), don't pass |
* @param dimCase - just for internal purpose (function recursion), don't pass |
385 |
* anything here, this function will call itself recursively |
* anything here, this function will call itself recursively |
386 |
* will fill this container with concrete dimension values for |
* will fill this container with concrete dimension values for |
387 |
* selecting the precise dimension regions during its task |
* selecting the precise dimension regions during its task |
388 |
*/ |
*/ |
389 |
static void copyDimensionRegions(gig::Region* outRgn, gig::Region* inRgn, Dimensions dims, int iDstLayer, int iSrcLayer, DimensionCase dimCase = DimensionCase()) { |
static void copyDimensionRegions(gig::Region* outRgn, gig::Region* inRgn, Dimensions dims, int iDstLayer, int iSrcLayer, const VelocityZones& dstVelocityZones, DimensionCase dimCase = DimensionCase()) { |
390 |
if (dims.empty()) { |
if (dims.empty()) { // finally reached end of function recursion ... |
391 |
// resolve the respective source & destination DimensionRegion ... |
// resolve the respective source & destination DimensionRegion ... |
392 |
uint srcDimValues[8] = {}; |
uint srcDimValues[8] = {}; |
393 |
uint dstDimValues[8] = {}; |
uint dstDimValues[8] = {}; |
405 |
fillDimValues(dstDimValues, dstDimCase, outRgn, true); |
fillDimValues(dstDimValues, dstDimCase, outRgn, true); |
406 |
gig::DimensionRegion* srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues); |
gig::DimensionRegion* srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues); |
407 |
gig::DimensionRegion* dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues); |
gig::DimensionRegion* dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues); |
408 |
|
#if DEBUG_COMBINE_INSTRUMENTS |
409 |
|
printf("srcDimRgn=%lx dstDimRgn=%lx\n", (uint64_t)srcDimRgn, (uint64_t)dstDimRgn); |
410 |
|
#endif |
411 |
|
|
412 |
// now that we have access to the precise velocity split zone upper |
// now that we have access to the precise velocity split zone upper |
413 |
// limits, we can select the actual source & destination dimension |
// limits, we can select the actual source & destination dimension |
415 |
// a velocity dimension) |
// a velocity dimension) |
416 |
if (outRgn->GetDimensionDefinition(gig::dimension_velocity)) { |
if (outRgn->GetDimensionDefinition(gig::dimension_velocity)) { |
417 |
// re-select target dimension region |
// re-select target dimension region |
418 |
DimensionZones zones = preciseDimensionZonesFor(gig::dimension_velocity, dstDimRgn); |
assert(dstVelocityZones.find(dstDimRgn) != dstVelocityZones.end()); |
419 |
assert(zones.size() > 1); |
DimensionZones dstZones = dstVelocityZones.find(dstDimRgn)->second; |
420 |
const int iZoneIndex = dstDimCase[gig::dimension_velocity]; |
assert(dstZones.size() > 1); |
421 |
assert(iZoneIndex <= zones.size()); |
int iZoneIndex = dstDimCase[gig::dimension_velocity]; |
422 |
dstDimCase[gig::dimension_velocity] = zones[iZoneIndex].low; // arbitrary value between low and high |
#if DEBUG_COMBINE_INSTRUMENTS |
423 |
|
printf("dst velocity zone: %d/%d\n", iZoneIndex, dstZones.size()); |
424 |
|
#endif |
425 |
|
assert(iZoneIndex < dstZones.size()); |
426 |
|
dstDimCase[gig::dimension_velocity] = dstZones[iZoneIndex].low; // arbitrary value between low and high |
427 |
|
#if DEBUG_COMBINE_INSTRUMENTS |
428 |
|
printf("dst velocity value = %d\n", dstDimCase[gig::dimension_velocity]); |
429 |
|
#endif |
430 |
fillDimValues(dstDimValues, dstDimCase, outRgn, true); |
fillDimValues(dstDimValues, dstDimCase, outRgn, true); |
431 |
dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues); |
dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues); |
432 |
|
#if DEBUG_COMBINE_INSTRUMENTS |
433 |
|
printf("reselected dstDimRgn=%lx\n", (uint64_t)dstDimRgn); |
434 |
|
#endif |
435 |
|
|
436 |
// re-select source dimension region |
// re-select source dimension region |
437 |
// (if it has a velocity dimension) |
// (if it has a velocity dimension) |
438 |
if (inRgn->GetDimensionDefinition(gig::dimension_velocity)) { |
if (inRgn->GetDimensionDefinition(gig::dimension_velocity)) { |
439 |
srcDimCase[gig::dimension_velocity] = zones[iZoneIndex].low; // same value as used above for target dimension region |
DimensionZones srcZones = preciseDimensionZonesFor(gig::dimension_velocity, srcDimRgn); |
440 |
|
assert(srcZones.size() > 1); |
441 |
|
if (iZoneIndex >= srcZones.size()) |
442 |
|
iZoneIndex = srcZones.size(); |
443 |
|
srcDimCase[gig::dimension_velocity] = srcZones[iZoneIndex].low; // same zone as used above for target dimension region (no matter what the precise zone ranges are) |
444 |
fillDimValues(srcDimValues, srcDimCase, inRgn, false); |
fillDimValues(srcDimValues, srcDimCase, inRgn, false); |
445 |
srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues); |
srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues); |
446 |
|
#if DEBUG_COMBINE_INSTRUMENTS |
447 |
|
printf("reselected srcDimRgn=%lx\n", (uint64_t)srcDimRgn); |
448 |
|
#endif |
449 |
} |
} |
450 |
} |
} |
451 |
|
|
473 |
return; // end of recursion |
return; // end of recursion |
474 |
} |
} |
475 |
|
|
476 |
|
// Copying n dimensions requires n nested loops. That's why this function |
477 |
|
// is calling itself recursively to provide the required amount of nested |
478 |
|
// loops. With each call it pops from argument 'dims' and pushes to |
479 |
|
// argument 'dimCase'. |
480 |
|
|
481 |
Dimensions::iterator itDimension = dims.begin(); |
Dimensions::iterator itDimension = dims.begin(); |
482 |
|
|
483 |
gig::dimension_t type = itDimension->first; |
gig::dimension_t type = itDimension->first; |
493 |
gig::dimension_def_t* def = outRgn->GetDimensionDefinition(type); |
gig::dimension_def_t* def = outRgn->GetDimensionDefinition(type); |
494 |
dimCase[type] = (def->split_type == gig::split_type_bit) ? iZone : zoneRange.low; |
dimCase[type] = (def->split_type == gig::split_type_bit) ? iZone : zoneRange.low; |
495 |
// recurse until 'dims' is exhausted (and dimCase filled up with concrete value) |
// recurse until 'dims' is exhausted (and dimCase filled up with concrete value) |
496 |
copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer, dimCase); |
copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer, dstVelocityZones, dimCase); |
497 |
} |
} |
498 |
} |
} |
499 |
|
|
529 |
|
|
530 |
// create a new output instrument |
// create a new output instrument |
531 |
gig::Instrument* outInstr = gig->AddInstrument(); |
gig::Instrument* outInstr = gig->AddInstrument(); |
532 |
outInstr->pInfo->Name = "NEW COMBINATION"; |
outInstr->pInfo->Name = _("NEW COMBINATION"); |
533 |
|
|
534 |
// Distinguishing in the following code block between 'horizontal' and |
// Distinguishing in the following code block between 'horizontal' and |
535 |
// 'vertical' regions. The 'horizontal' ones are meant to be the key ranges |
// 'vertical' regions. The 'horizontal' ones are meant to be the key ranges |
597 |
itRgn != itGroup->second.end(); ++itRgn) // iterate over 'vertical' / source regions ... |
itRgn != itGroup->second.end(); ++itRgn) // iterate over 'vertical' / source regions ... |
598 |
{ |
{ |
599 |
gig::Region* inRgn = itRgn->second; |
gig::Region* inRgn = itRgn->second; |
600 |
|
VelocityZones dstVelocityZones = getVelocityZones(outRgn); |
601 |
for (uint iSrcLayer = 0; iSrcLayer < inRgn->Layers; ++iSrcLayer, ++iDstLayer) { |
for (uint iSrcLayer = 0; iSrcLayer < inRgn->Layers; ++iSrcLayer, ++iDstLayer) { |
602 |
copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer); |
copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer, dstVelocityZones); |
603 |
} |
} |
604 |
} |
} |
605 |
} |
} |