/[svn]/gigedit/trunk/src/gigedit/CombineInstrumentsDialog.cpp
ViewVC logotype

Diff of /gigedit/trunk/src/gigedit/CombineInstrumentsDialog.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2549 by schoenebeck, Tue May 13 16:14:33 2014 UTC revision 2550 by schoenebeck, Wed May 14 01:31:30 2014 UTC
# Line 32  typedef std::map<gig::dimension_t,int> D Line 32  typedef std::map<gig::dimension_t,int> D
32    
33  typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits;  typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits;
34    
 typedef std::map<gig::DimensionRegion*, DimensionZones> VelocityZones;  
   
35  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
36  // private functions  // private functions
37    
# Line 253  inline int getDimensionIndex(gig::dimens Line 251  inline int getDimensionIndex(gig::dimens
251  }  }
252    
253  static void fillDimValues(uint* values/*[8]*/, DimensionCase dimCase, gig::Region* rgn, bool bShouldHaveAllDimensionsPassed) {  static void fillDimValues(uint* values/*[8]*/, DimensionCase dimCase, gig::Region* rgn, bool bShouldHaveAllDimensionsPassed) {
254        #if DEBUG_COMBINE_INSTRUMENTS
255        printf("dimvalues = { ");
256        fflush(stdout);
257        #endif
258      for (DimensionCase::iterator it = dimCase.begin(); it != dimCase.end(); ++it) {      for (DimensionCase::iterator it = dimCase.begin(); it != dimCase.end(); ++it) {
259          gig::dimension_t type = it->first;          gig::dimension_t type = it->first;
260          int iDimIndex = getDimensionIndex(type, rgn);          int iDimIndex = getDimensionIndex(type, rgn);
261          if (bShouldHaveAllDimensionsPassed) assert(iDimIndex >= 0);          if (bShouldHaveAllDimensionsPassed) assert(iDimIndex >= 0);
262          else if (iDimIndex < 0) continue;          else if (iDimIndex < 0) continue;
263          values[iDimIndex] = it->second;          values[iDimIndex] = it->second;
264            #if DEBUG_COMBINE_INSTRUMENTS
265            printf("%x=%d, ", type, it->second);
266            #endif
267      }      }
268        #if DEBUG_COMBINE_INSTRUMENTS
269        printf("\n");
270        #endif
271  }  }
272    
273  static DimensionRegionUpperLimits getDimensionRegionUpperLimits(gig::DimensionRegion* dimRgn) {  static DimensionRegionUpperLimits getDimensionRegionUpperLimits(gig::DimensionRegion* dimRgn) {
# Line 334  static DimensionZones preciseDimensionZo Line 342  static DimensionZones preciseDimensionZo
342      int iBaseBits = baseBits(type, rgn);      int iBaseBits = baseBits(type, rgn);
343      int mask = ~(((1 << def.bits) - 1) << iBaseBits);      int mask = ~(((1 << def.bits) - 1) << iBaseBits);
344    
345        #if DEBUG_COMBINE_INSTRUMENTS
346        printf("velo zones { ");
347        fflush(stdout);
348        #endif
349      int iLow = 0;      int iLow = 0;
350      for (int z = 0; z < def.zones; ++z) {      for (int z = 0; z < def.zones; ++z) {
351          gig::DimensionRegion* dimRgn2 =          gig::DimensionRegion* dimRgn2 =
352              rgn->pDimensionRegions[ (iDimRgn & mask) | ( z << iBaseBits) ];              rgn->pDimensionRegions[ (iDimRgn & mask) | ( z << iBaseBits) ];
353          int iHigh = dimRgn2->DimensionUpperLimits[iDimension];          int iHigh = dimRgn2->DimensionUpperLimits[iDimension];
354          DLS::range_t range = { iLow, iHigh};          DLS::range_t range = { iLow, iHigh};
355            #if DEBUG_COMBINE_INSTRUMENTS
356            printf("%d..%d, ", iLow, iHigh);
357            fflush(stdout);
358            #endif
359          zones.push_back(range);          zones.push_back(range);
360          iLow = iHigh + 1;          iLow = iHigh + 1;
361      }      }
362        #if DEBUG_COMBINE_INSTRUMENTS
363        printf("}\n");
364        #endif
365      return zones;      return zones;
366  }  }
367    
368  static VelocityZones getVelocityZones(gig::Region* rgn) {  struct CopyAssignSchedEntry {
369      VelocityZones zones;      gig::DimensionRegion* src;
370      for (uint i = 0; i < rgn->DimensionRegions; ++i) {      gig::DimensionRegion* dst;
371          gig::DimensionRegion* dimRgn = rgn->pDimensionRegions[i];      int velocityZone;
372          zones[dimRgn] = preciseDimensionZonesFor(gig::dimension_velocity, dimRgn);      int totalSrcVelocityZones;
373      }  };
374      return zones;  typedef std::vector<CopyAssignSchedEntry> CopyAssignSchedule;
 }  
375    
376  /** @brief Copy all DimensionRegions from source Region to target Region.  /** @brief Copy all DimensionRegions from source Region to target Region.
377   *   *
# Line 370  static VelocityZones getVelocityZones(gi Line 388  static VelocityZones getVelocityZones(gi
388   *   *
389   * @param outRgn - where the dimension regions shall be copied to   * @param outRgn - where the dimension regions shall be copied to
390   * @param inRgn - all dimension regions that shall be copied from   * @param inRgn - all dimension regions that shall be copied from
391   * @param dims - dimension definitions of target region   * @param dims - precise dimension definitions of target region
392   * @param iDstLayer - layer number of destination region where the dimension   * @param iDstLayer - layer index of destination region where the dimension
393   *                    regions shall be copied to   *                    regions shall be copied to
394   * @param iSrcLayer - layer number of the source region where the dimension   * @param iSrcLayer - layer index of the source region where the dimension
395   *                    regions shall be copied from   *                    regions shall be copied from
  * @param dstVelocityZones - all precise velocity zones for destination region  
  *                           (since this information is stored on  
  *                           DimensionRegion level and this function is  
  *                           modifying target DimensionRegions, this  
  *                           informations thus needs to be retrieved before  
  *                           calling this function)  
396   * @param dimCase - just for internal purpose (function recursion), don't pass   * @param dimCase - just for internal purpose (function recursion), don't pass
397   *                  anything here, this function will call itself recursively   *                  anything here, this function will call itself recursively
398   *                  will fill this container with concrete dimension values for   *                  will fill this container with concrete dimension values for
399   *                  selecting the precise dimension regions during its task   *                  selecting the precise dimension regions during its task
400     * @param schedule - just for internal purpose (function recursion), don't pass
401                         anything here: list of all DimensionRegion copy operations
402     *                   which is filled during the nested loops / recursions of
403     *                   this function call, they will be peformed after all
404     *                   function recursions have been completed
405   */   */
406  static void copyDimensionRegions(gig::Region* outRgn, gig::Region* inRgn, Dimensions dims, int iDstLayer, int iSrcLayer, const VelocityZones& dstVelocityZones, DimensionCase dimCase = DimensionCase()) {  static void copyDimensionRegions(gig::Region* outRgn, gig::Region* inRgn, Dimensions dims, int iDstLayer, int iSrcLayer, DimensionCase dimCase = DimensionCase(), CopyAssignSchedule* schedule = NULL) {
407      if (dims.empty()) { // finally reached end of function recursion ...      const bool isHighestLevelOfRecursion = !schedule;
408    
409        if (isHighestLevelOfRecursion)
410            schedule = new CopyAssignSchedule;
411    
412        if (dims.empty()) { // reached deepest level of function recursion ...
413            CopyAssignSchedEntry e;
414    
415          // resolve the respective source & destination DimensionRegion ...                  // resolve the respective source & destination DimensionRegion ...        
416          uint srcDimValues[8] = {};          uint srcDimValues[8] = {};
417          uint dstDimValues[8] = {};          uint dstDimValues[8] = {};
# Line 396  static void copyDimensionRegions(gig::Re Line 420  static void copyDimensionRegions(gig::Re
420          srcDimCase[gig::dimension_layer] = iSrcLayer;          srcDimCase[gig::dimension_layer] = iSrcLayer;
421          dstDimCase[gig::dimension_layer] = iDstLayer;          dstDimCase[gig::dimension_layer] = iDstLayer;
422    
423            #if DEBUG_COMBINE_INSTRUMENTS
424            printf("-------------------------------\n");
425            #endif
426    
427          // first select source & target dimension region with an arbitrary          // first select source & target dimension region with an arbitrary
428          // velocity split zone, to get access to the precise individual velocity          // velocity split zone, to get access to the precise individual velocity
429          // split zone sizes (if there is actually a velocity dimension at all,          // split zone sizes (if there is actually a velocity dimension at all,
430          // otherwise we already select the desired source & target dimension          // otherwise we already select the desired source & target dimension
431          // region here)          // region here)
432            #if DEBUG_COMBINE_INSTRUMENTS
433            printf("src "); fflush(stdout);
434            #endif
435          fillDimValues(srcDimValues, srcDimCase, inRgn, false);          fillDimValues(srcDimValues, srcDimCase, inRgn, false);
436            #if DEBUG_COMBINE_INSTRUMENTS
437            printf("dst "); fflush(stdout);
438            #endif
439          fillDimValues(dstDimValues, dstDimCase, outRgn, true);          fillDimValues(dstDimValues, dstDimCase, outRgn, true);
440          gig::DimensionRegion* srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues);          gig::DimensionRegion* srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues);
441          gig::DimensionRegion* dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);          gig::DimensionRegion* dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);
442          #if DEBUG_COMBINE_INSTRUMENTS          #if DEBUG_COMBINE_INSTRUMENTS
443            printf("iDstLayer=%d iSrcLayer=%d\n", iDstLayer, iSrcLayer);
444          printf("srcDimRgn=%lx dstDimRgn=%lx\n", (uint64_t)srcDimRgn, (uint64_t)dstDimRgn);          printf("srcDimRgn=%lx dstDimRgn=%lx\n", (uint64_t)srcDimRgn, (uint64_t)dstDimRgn);
445            printf("srcSample='%s' dstSample='%s'\n",
446                   (!srcDimRgn->pSample ? "NULL" : srcDimRgn->pSample->pInfo->Name.c_str()),
447                   (!dstDimRgn->pSample ? "NULL" : dstDimRgn->pSample->pInfo->Name.c_str())
448            );
449          #endif          #endif
450    
451            assert(srcDimRgn->GetParent() == inRgn);
452            assert(dstDimRgn->GetParent() == outRgn);
453    
454          // now that we have access to the precise velocity split zone upper          // now that we have access to the precise velocity split zone upper
455          // limits, we can select the actual source & destination dimension          // limits, we can select the actual source & destination dimension
456          // regions we need to copy (assuming that source or target region has          // regions we need to copy (assuming that source or target region has
457          // a velocity dimension)          // a velocity dimension)
458          if (outRgn->GetDimensionDefinition(gig::dimension_velocity)) {          if (outRgn->GetDimensionDefinition(gig::dimension_velocity)) {
459              // re-select target dimension region              // re-select target dimension region (with correct velocity zone)
460              assert(dstVelocityZones.find(dstDimRgn) != dstVelocityZones.end());              DimensionZones dstZones = preciseDimensionZonesFor(gig::dimension_velocity, dstDimRgn);
             DimensionZones dstZones = dstVelocityZones.find(dstDimRgn)->second;  
461              assert(dstZones.size() > 1);              assert(dstZones.size() > 1);
462              int iZoneIndex = dstDimCase[gig::dimension_velocity];              int iZoneIndex = dstDimCase[gig::dimension_velocity];
463                e.velocityZone = iZoneIndex;
464              #if DEBUG_COMBINE_INSTRUMENTS              #if DEBUG_COMBINE_INSTRUMENTS
465              printf("dst velocity zone: %d/%d\n", iZoneIndex, dstZones.size());              printf("dst velocity zone: %d/%d\n", iZoneIndex, (int)dstZones.size());
466              #endif              #endif
467              assert(iZoneIndex < dstZones.size());              assert(uint(iZoneIndex) < dstZones.size());
468              dstDimCase[gig::dimension_velocity] = dstZones[iZoneIndex].low; // arbitrary value between low and high              dstDimCase[gig::dimension_velocity] = dstZones[iZoneIndex].low; // arbitrary value between low and high
469              #if DEBUG_COMBINE_INSTRUMENTS              #if DEBUG_COMBINE_INSTRUMENTS
470              printf("dst velocity value = %d\n", dstDimCase[gig::dimension_velocity]);              printf("dst velocity value = %d\n", dstDimCase[gig::dimension_velocity]);
471                printf("dst refilled "); fflush(stdout);
472              #endif              #endif
473              fillDimValues(dstDimValues, dstDimCase, outRgn, true);              fillDimValues(dstDimValues, dstDimCase, outRgn, true);
474              dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);              dstDimRgn = outRgn->GetDimensionRegionByValue(dstDimValues);
475              #if DEBUG_COMBINE_INSTRUMENTS              #if DEBUG_COMBINE_INSTRUMENTS
476              printf("reselected dstDimRgn=%lx\n", (uint64_t)dstDimRgn);              printf("reselected dstDimRgn=%lx\n", (uint64_t)dstDimRgn);
477                printf("dstSample='%s'\n",
478                    (!dstDimRgn->pSample ? "NULL" : dstDimRgn->pSample->pInfo->Name.c_str())
479                );
480              #endif              #endif
481    
482              // re-select source dimension region              // re-select source dimension region with correct velocity zone
483              // (if it has a velocity dimension)              // (if it has a velocity dimension that is)
484              if (inRgn->GetDimensionDefinition(gig::dimension_velocity)) {              if (inRgn->GetDimensionDefinition(gig::dimension_velocity)) {
485                  DimensionZones srcZones = preciseDimensionZonesFor(gig::dimension_velocity, srcDimRgn);                  DimensionZones srcZones = preciseDimensionZonesFor(gig::dimension_velocity, srcDimRgn);
486                    e.totalSrcVelocityZones = srcZones.size();
487                  assert(srcZones.size() > 1);                  assert(srcZones.size() > 1);
488                  if (iZoneIndex >= srcZones.size())                  if (uint(iZoneIndex) >= srcZones.size())
489                      iZoneIndex  = srcZones.size();                      iZoneIndex  = srcZones.size() - 1;
490                  srcDimCase[gig::dimension_velocity] = srcZones[iZoneIndex].low; // same zone as used above for target dimension region (no matter what the precise zone ranges are)                  srcDimCase[gig::dimension_velocity] = srcZones[iZoneIndex].low; // same zone as used above for target dimension region (no matter what the precise zone ranges are)
491                    #if DEBUG_COMBINE_INSTRUMENTS
492                    printf("src refilled "); fflush(stdout);
493                    #endif
494                  fillDimValues(srcDimValues, srcDimCase, inRgn, false);                  fillDimValues(srcDimValues, srcDimCase, inRgn, false);
495                  srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues);                  srcDimRgn = inRgn->GetDimensionRegionByValue(srcDimValues);
496                  #if DEBUG_COMBINE_INSTRUMENTS                  #if DEBUG_COMBINE_INSTRUMENTS
497                  printf("reselected srcDimRgn=%lx\n", (uint64_t)srcDimRgn);                  printf("reselected srcDimRgn=%lx\n", (uint64_t)srcDimRgn);
498                    printf("srcSample='%s'\n",
499                        (!srcDimRgn->pSample ? "NULL" : srcDimRgn->pSample->pInfo->Name.c_str())
500                    );
501                  #endif                  #endif
502              }              }
503          }          }
504    
505          // backup the target DimensionRegion's current dimension zones upper          // Schedule copy opertion of source -> target DimensionRegion for the
506          // limits (because the target DimensionRegion's upper limits are already          // time after all nested loops have been traversed. We have to postpone
507          // defined correctly since calling AddDimension(), and the CopyAssign()          // the actual copy operations this way, because otherwise it would
508          // call next, will overwrite those upper limits unfortunately          // overwrite informations inside the destination DimensionRegion object
509          DimensionRegionUpperLimits dstUpperLimits = getDimensionRegionUpperLimits(dstDimRgn);          // that we need to read in the code block above.
510          DimensionRegionUpperLimits srcUpperLimits = getDimensionRegionUpperLimits(srcDimRgn);          e.src = srcDimRgn;
511            e.dst = dstDimRgn;
512          // copy over the selected DimensionRegion          schedule->push_back(e);
         const gig::Region* const origRgn = dstDimRgn->GetParent(); // just for sanity check below  
         dstDimRgn->CopyAssign(srcDimRgn);  
         assert(origRgn == dstDimRgn->GetParent());  
   
         // restore all original dimension zone upper limits except of the  
         // velocity dimension, because the velocity dimension zone sizes are  
         // allowed to differ for individual DimensionRegions in gig v3 format  
         if (srcUpperLimits.count(gig::dimension_velocity)) {  
             assert(dstUpperLimits.count(gig::dimension_velocity));  
             dstUpperLimits[gig::dimension_velocity] = srcUpperLimits[gig::dimension_velocity];  
         }  
         restoreDimensionRegionUpperLimits(dstDimRgn, dstUpperLimits);  
513    
514          return; // end of recursion          return; // returning from deepest level of function recursion
515      }      }
516    
517      // Copying n dimensions requires n nested loops. That's why this function      // Copying n dimensions requires n nested loops. That's why this function
# Line 479  static void copyDimensionRegions(gig::Re Line 520  static void copyDimensionRegions(gig::Re
520      // argument 'dimCase'.      // argument 'dimCase'.
521    
522      Dimensions::iterator itDimension = dims.begin();      Dimensions::iterator itDimension = dims.begin();
   
523      gig::dimension_t type = itDimension->first;      gig::dimension_t type = itDimension->first;
524      DimensionZones  zones = itDimension->second;      DimensionZones  zones = itDimension->second;
   
525      dims.erase(itDimension);      dims.erase(itDimension);
526    
527      int iZone = 0;      int iZone = 0;
# Line 492  static void copyDimensionRegions(gig::Re Line 531  static void copyDimensionRegions(gig::Re
531          DLS::range_t zoneRange = *itZone;          DLS::range_t zoneRange = *itZone;
532          gig::dimension_def_t* def = outRgn->GetDimensionDefinition(type);          gig::dimension_def_t* def = outRgn->GetDimensionDefinition(type);
533          dimCase[type] = (def->split_type == gig::split_type_bit) ? iZone : zoneRange.low;          dimCase[type] = (def->split_type == gig::split_type_bit) ? iZone : zoneRange.low;
534    
535          // recurse until 'dims' is exhausted (and dimCase filled up with concrete value)          // recurse until 'dims' is exhausted (and dimCase filled up with concrete value)
536          copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer, dstVelocityZones, dimCase);          copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer, dimCase, schedule);
537        }
538    
539        // if current function call is the (very first) entry point ...
540        if (isHighestLevelOfRecursion) {
541            // ... then perform all scheduled DimensionRegion copy operations
542            for (uint i = 0; i < schedule->size(); ++i) {
543                CopyAssignSchedEntry& e = (*schedule)[i];
544    
545                // backup the target DimensionRegion's current dimension zones upper
546                // limits (because the target DimensionRegion's upper limits are
547                // already defined correctly since calling AddDimension(), and the
548                // CopyAssign() call next, will overwrite those upper limits
549                // unfortunately
550                DimensionRegionUpperLimits dstUpperLimits = getDimensionRegionUpperLimits(e.dst);
551                DimensionRegionUpperLimits srcUpperLimits = getDimensionRegionUpperLimits(e.src);
552    
553                // now actually copy over the current DimensionRegion
554                const gig::Region* const origRgn = e.dst->GetParent(); // just for sanity check below
555                e.dst->CopyAssign(e.src);
556                assert(origRgn == e.dst->GetParent()); // if gigedit is crashing here, then you must update libgig (to at least SVN r2547, v3.3.0.svn10)
557    
558                // restore all original dimension zone upper limits except of the
559                // velocity dimension, because the velocity dimension zone sizes are
560                // allowed to differ for individual DimensionRegions in gig v3
561                // format
562                if (srcUpperLimits.count(gig::dimension_velocity)) {
563                    assert(dstUpperLimits.count(gig::dimension_velocity));
564                    dstUpperLimits[gig::dimension_velocity] =
565                        (e.velocityZone >= e.totalSrcVelocityZones)
566                            ? 127 : srcUpperLimits[gig::dimension_velocity];
567                }
568                restoreDimensionRegionUpperLimits(e.dst, dstUpperLimits);
569            }
570            delete schedule;
571      }      }
572  }  }
573    
# Line 597  static void combineInstruments(std::vect Line 671  static void combineInstruments(std::vect
671               itRgn != itGroup->second.end(); ++itRgn) // iterate over 'vertical' / source regions ...               itRgn != itGroup->second.end(); ++itRgn) // iterate over 'vertical' / source regions ...
672          {          {
673              gig::Region* inRgn = itRgn->second;              gig::Region* inRgn = itRgn->second;
             VelocityZones dstVelocityZones = getVelocityZones(outRgn);  
674              for (uint iSrcLayer = 0; iSrcLayer < inRgn->Layers; ++iSrcLayer, ++iDstLayer) {              for (uint iSrcLayer = 0; iSrcLayer < inRgn->Layers; ++iSrcLayer, ++iDstLayer) {
675                  copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer, dstVelocityZones);                  copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer);
676              }              }
677          }          }
678      }      }
# Line 632  CombineInstrumentsDialog::CombineInstrum Line 705  CombineInstrumentsDialog::CombineInstrum
705    
706      m_refTreeModel = Gtk::ListStore::create(m_columns);      m_refTreeModel = Gtk::ListStore::create(m_columns);
707      m_treeView.set_model(m_refTreeModel);      m_treeView.set_model(m_refTreeModel);
708      //m_treeView.set_tooltip_text(_("asdf"));      m_treeView.set_tooltip_text(_(
709            "Use SHIFT + left click or CTRL + left click to select the instruments "
710            "you want to combine."
711        ));
712      m_treeView.append_column("Instrument", m_columns.m_col_name);      m_treeView.append_column("Instrument", m_columns.m_col_name);
713      m_treeView.set_headers_visible(false);      m_treeView.set_headers_visible(false);
714      m_treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);      m_treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
# Line 682  CombineInstrumentsDialog::CombineInstrum Line 758  CombineInstrumentsDialog::CombineInstrum
758      );      );
759    
760      show_all_children();      show_all_children();
761    
762        // show a warning to user if he uses a .gig in v2 format
763        if (gig->pVersion->major < 3) {
764            Glib::ustring txt = _(
765                "You are currently using a .gig file in old v2 format. The current "
766                "combine algorithm will most probably fail trying to combine "
767                "instruments in this old format. So better save the file in new v3 "
768                "format before trying to combine your instruments."
769            );
770            Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_WARNING);
771            msg.run();
772        }
773  }  }
774    
775  void CombineInstrumentsDialog::combineSelectedInstruments() {  void CombineInstrumentsDialog::combineSelectedInstruments() {

Legend:
Removed from v.2549  
changed lines
  Added in v.2550

  ViewVC Help
Powered by ViewVC