/[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 2550 by schoenebeck, Wed May 14 01:31:30 2014 UTC revision 2552 by schoenebeck, Wed May 14 16:09:58 2014 UTC
# Line 15  Line 15 
15  #include <set>  #include <set>
16  #include <iostream>  #include <iostream>
17  #include <assert.h>  #include <assert.h>
18    #include <stdarg.h>
19    #include <string.h>
20    
21  #include <glibmm/ustring.h>  #include <glibmm/ustring.h>
22  #include <gtkmm/stock.h>  #include <gtkmm/stock.h>
# Line 32  typedef std::map<gig::dimension_t,int> D Line 34  typedef std::map<gig::dimension_t,int> D
34    
35  typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits;  typedef std::map<gig::dimension_t, int> DimensionRegionUpperLimits;
36    
37    typedef std::set<Glib::ustring> Warnings;
38    
39    ///////////////////////////////////////////////////////////////////////////
40    // private static data
41    
42    static Warnings g_warnings;
43    
44  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
45  // private functions  // private functions
46    
# Line 47  static void printRanges(const RegionGrou Line 56  static void printRanges(const RegionGrou
56  #endif  #endif
57    
58  /**  /**
59     * Store a warning message that shall be stored and displayed to the user as a
60     * list of warnings after the overall operation has finished. Duplicate warning
61     * messages are automatically eliminated.
62     */
63    inline void addWarning(const char* fmt, ...) {
64        va_list arg;
65        va_start(arg, fmt);
66        const int SZ = 255 + strlen(fmt);
67        char* buf = new char[SZ];
68        vsnprintf(buf, SZ, fmt, arg);
69        Glib::ustring s = buf;
70        delete [] buf;
71        va_end(arg);
72        std::cerr << _("WARNING:") << " " << s << std::endl << std::flush;
73        g_warnings.insert(s);
74    }
75    
76    /**
77   * If the two ranges overlap, then this function returns the smallest point   * If the two ranges overlap, then this function returns the smallest point
78   * within that overlapping zone. If the two ranges do not overlap, then this   * within that overlapping zone. If the two ranges do not overlap, then this
79   * function will return -1 instead.   * function will return -1 instead.
# Line 131  static RegionGroup getAllRegionsWhichOve Line 158  static RegionGroup getAllRegionsWhichOve
158          std::vector<gig::Region*> v = getAllRegionsWhichOverlapRange(instr, range);          std::vector<gig::Region*> v = getAllRegionsWhichOverlapRange(instr, range);
159          if (v.empty()) continue;          if (v.empty()) continue;
160          if (v.size() > 1) {          if (v.size() > 1) {
161              std::cerr << "WARNING: More than one region found!" << std::endl;              addWarning("More than one region found!");
162          }          }
163          group[instr] = v[0];          group[instr] = v[0];
164      }      }
# Line 175  static RegionGroups groupByRegionInterse Line 202  static RegionGroups groupByRegionInterse
202          if (!group.empty())          if (!group.empty())
203              groups[range] = group;              groups[range] = group;
204          else          else
205              std::cerr << "WARNING: empty region group!" << std::endl;              addWarning("Empty region group!");
206      }      }
207    
208      return groups;      return groups;
# Line 484  static void copyDimensionRegions(gig::Re Line 511  static void copyDimensionRegions(gig::Re
511              if (inRgn->GetDimensionDefinition(gig::dimension_velocity)) {              if (inRgn->GetDimensionDefinition(gig::dimension_velocity)) {
512                  DimensionZones srcZones = preciseDimensionZonesFor(gig::dimension_velocity, srcDimRgn);                  DimensionZones srcZones = preciseDimensionZonesFor(gig::dimension_velocity, srcDimRgn);
513                  e.totalSrcVelocityZones = srcZones.size();                  e.totalSrcVelocityZones = srcZones.size();
514                  assert(srcZones.size() > 1);                  assert(srcZones.size() > 0);
515                    if (srcZones.size() <= 1) {
516                        addWarning("Input region has a velocity dimension with only ONE zone!");
517                    }
518                  if (uint(iZoneIndex) >= srcZones.size())                  if (uint(iZoneIndex) >= srcZones.size())
519                      iZoneIndex  = srcZones.size() - 1;                      iZoneIndex  = srcZones.size() - 1;
520                  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)
# Line 560  static void copyDimensionRegions(gig::Re Line 590  static void copyDimensionRegions(gig::Re
590              // allowed to differ for individual DimensionRegions in gig v3              // allowed to differ for individual DimensionRegions in gig v3
591              // format              // format
592              if (srcUpperLimits.count(gig::dimension_velocity)) {              if (srcUpperLimits.count(gig::dimension_velocity)) {
593                  assert(dstUpperLimits.count(gig::dimension_velocity));                  if (!dstUpperLimits.count(gig::dimension_velocity)) {
594                  dstUpperLimits[gig::dimension_velocity] =                      addWarning("Source instrument seems to have a velocity dimension whereas new target instrument doesn't!");
595                      (e.velocityZone >= e.totalSrcVelocityZones)                  } else {
596                          ? 127 : srcUpperLimits[gig::dimension_velocity];                      dstUpperLimits[gig::dimension_velocity] =
597                            (e.velocityZone >= e.totalSrcVelocityZones)
598                                ? 127 : srcUpperLimits[gig::dimension_velocity];
599                    }
600              }              }
601              restoreDimensionRegionUpperLimits(e.dst, dstUpperLimits);              restoreDimensionRegionUpperLimits(e.dst, dstUpperLimits);
602          }          }
# Line 618  static void combineInstruments(std::vect Line 651  static void combineInstruments(std::vect
651      {      {
652          gig::Region* outRgn = outInstr->AddRegion();          gig::Region* outRgn = outInstr->AddRegion();
653          outRgn->SetKeyRange(itGroup->first.low, itGroup->first.high);          outRgn->SetKeyRange(itGroup->first.low, itGroup->first.high);
654            #if DEBUG_COMBINE_INSTRUMENTS
655            printf("---> Start target region %d..%d\n", itGroup->first.low, itGroup->first.high);
656            #endif
657    
658          // detect the total amount of layers required to build up this combi          // detect the total amount of layers required to build up this combi
659          // for current key range          // for current key range
# Line 628  static void combineInstruments(std::vect Line 664  static void combineInstruments(std::vect
664              gig::Region* inRgn = itRgn->second;              gig::Region* inRgn = itRgn->second;
665              iTotalLayers += inRgn->Layers;              iTotalLayers += inRgn->Layers;
666          }          }
667            #if DEBUG_COMBINE_INSTRUMENTS
668            printf("Required total layers: %d\n", iTotalLayers);
669            #endif
670            
671          // create all required dimensions for this output region          // create all required dimensions for this output region
672          // (except the layer dimension, which we create as next step)          // (except the layer dimension, which we create as next step)
673          Dimensions dims = getDimensionsForRegionGroup(itGroup->second);          Dimensions dims = getDimensionsForRegionGroup(itGroup->second);
         for (Dimensions::iterator itDim = dims.begin();  
              itDim != dims.end(); ++itDim)  
674          {          {
675              if (itDim->first == gig::dimension_layer) continue;              std::vector<gig::dimension_t> skipTheseDimensions; // used to prevent a misbehavior (i.e. crash) of the combine algorithm in case one of the source instruments has a dimension with only one zone, which is not standard conform
676    
677              gig::dimension_def_t def;              for (Dimensions::iterator itDim = dims.begin();
678              def.dimension = itDim->first; // dimension type                  itDim != dims.end(); ++itDim)
679              def.zones = itDim->second.size();              {
680              def.bits = zoneCountToBits(def.zones);                  // layer dimension is created separately in the next code block
681              #if DEBUG_COMBINE_INSTRUMENTS                  // (outside of this loop)
682              std::cout << "Adding new regular dimension type=" << std::hex << (int)def.dimension << std::dec << ", zones=" << (int)def.zones << ", bits=" << (int)def.bits << " ... " << std::flush;                  if (itDim->first == gig::dimension_layer) continue;
683              #endif  
684              outRgn->AddDimension(&def);                  gig::dimension_def_t def;
685              #if DEBUG_COMBINE_INSTRUMENTS                  def.dimension = itDim->first; // dimension type
686              std::cout << "OK" << std::endl << std::flush;                  def.zones = itDim->second.size();
687              #endif                  def.bits = zoneCountToBits(def.zones);
688                    if (def.zones < 2) {
689                        addWarning(
690                            "Attempt to create dimension with type=0x%x with only "
691                            "ONE zone (because at least one of the source "
692                            "instruments seems to have such a velocity dimension "
693                            "with only ONE zone, which is odd)! Skipping this "
694                            "dimension for now.",
695                            (int)itDim->first
696                        );
697                        skipTheseDimensions.push_back(itDim->first);
698                        continue;
699                    }
700                    #if DEBUG_COMBINE_INSTRUMENTS
701                    std::cout << "Adding new regular dimension type=" << std::hex << (int)def.dimension << std::dec << ", zones=" << (int)def.zones << ", bits=" << (int)def.bits << " ... " << std::flush;
702                    #endif
703                    outRgn->AddDimension(&def);
704                    #if DEBUG_COMBINE_INSTRUMENTS
705                    std::cout << "OK" << std::endl << std::flush;
706                    #endif
707                }
708                // prevent the following dimensions to be processed further below
709                // (since the respective dimension was not created above)
710                for (int i = 0; i < skipTheseDimensions.size(); ++i)
711                    dims.erase(skipTheseDimensions[i]);
712          }          }
713    
714          // create the layer dimension (if necessary for current key range)          // create the layer dimension (if necessary for current key range)
# Line 671  static void combineInstruments(std::vect Line 732  static void combineInstruments(std::vect
732               itRgn != itGroup->second.end(); ++itRgn) // iterate over 'vertical' / source regions ...               itRgn != itGroup->second.end(); ++itRgn) // iterate over 'vertical' / source regions ...
733          {          {
734              gig::Region* inRgn = itRgn->second;              gig::Region* inRgn = itRgn->second;
735                #if DEBUG_COMBINE_INSTRUMENTS
736                printf("[source region of '%s']\n", inRgn->GetParent()->pInfo->Name.c_str());
737                #endif
738              for (uint iSrcLayer = 0; iSrcLayer < inRgn->Layers; ++iSrcLayer, ++iDstLayer) {              for (uint iSrcLayer = 0; iSrcLayer < inRgn->Layers; ++iSrcLayer, ++iDstLayer) {
739                  copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer);                  copyDimensionRegions(outRgn, inRgn, dims, iDstLayer, iSrcLayer);
740              }              }
# Line 786  void CombineInstrumentsDialog::combineSe Line 850  void CombineInstrumentsDialog::combineSe
850          instruments.push_back(instrument);          instruments.push_back(instrument);
851      }      }
852    
853        g_warnings.clear();
854    
855      try {      try {
856          combineInstruments(instruments, m_gig, m_newCombinedInstrument);          combineInstruments(instruments, m_gig, m_newCombinedInstrument);
857      } catch (RIFF::Exception e) {;      } catch (RIFF::Exception e) {;
# Line 794  void CombineInstrumentsDialog::combineSe Line 860  void CombineInstrumentsDialog::combineSe
860          return;          return;
861      }      }
862    
863        if (!g_warnings.empty()) {
864            Glib::ustring txt = _(
865                "Combined instrument was created successfully, but there were warnings:"
866            );
867            txt += "\n\n";
868            for (Warnings::const_iterator itWarn = g_warnings.begin();
869                 itWarn != g_warnings.end(); ++itWarn)
870            {
871                txt += "-> " + *itWarn + "\n";
872            }
873            txt += "\n";
874            txt += _(
875                "You might also want to check the console for further warnings and "
876                "error messages."
877            );
878            Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_WARNING);
879            msg.run();
880        }
881    
882      // no error occurred      // no error occurred
883      m_fileWasChanged = true;      m_fileWasChanged = true;
884      hide();      hide();

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

  ViewVC Help
Powered by ViewVC