/[svn]/libgig/trunk/src/tools/gigdump.cpp
ViewVC logotype

Diff of /libgig/trunk/src/tools/gigdump.cpp

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

libgig/trunk/src/gigdump.cpp revision 2493 by schoenebeck, Wed Jan 1 17:06:51 2014 UTC libgig/trunk/src/tools/gigdump.cpp revision 3446 by schoenebeck, Sun Dec 23 21:47:26 2018 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   libgig - C++ cross-platform Gigasampler format file access library    *   *   libgig - C++ cross-platform Gigasampler format file access library    *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003-2009 by Christian Schoenebeck                      *   *   Copyright (C) 2003-2018 by Christian Schoenebeck                      *
6   *                              <cuse@users.sourceforge.net>               *   *                              <cuse@users.sourceforge.net>               *
7   *                                                                         *   *                                                                         *
8   *   This program is part of libgig.                                       *   *   This program is part of libgig.                                       *
# Line 31  Line 31 
31  #include <cstdlib>  #include <cstdlib>
32  #include <string>  #include <string>
33    
34  #include "gig.h"  #include "../gig.h"
35    
36  using namespace std;  using namespace std;
37    
38  string Revision();  string Revision();
39  void PrintVersion();  void PrintVersion();
40  void PrintFileInformations(gig::File* gig);  void PrintFileInformation(gig::File* gig);
41  void PrintGroups(gig::File* gig);  void PrintGroups(gig::File* gig);
42  void PrintSamples(gig::File* gig);  void PrintSamples(gig::File* gig);
43    void PrintScripts(gig::File* gig);
44  void PrintInstruments(gig::File* gig);  void PrintInstruments(gig::File* gig);
45    void PrintInstrumentNamesOnly(gig::File* gig);
46  void PrintRegions(gig::Instrument* instr);  void PrintRegions(gig::Instrument* instr);
47  void PrintUsage();  void PrintUsage();
48  void PrintDimensionRegions(gig::Region* rgn);  void PrintDimensionRegions(gig::Region* rgn);
49    bool VerifyFile(gig::File* gig);
50    void RebuildChecksumTable(gig::File* gig);
51    
52    class PubSample : public gig::Sample {
53    public:
54        using DLS::Sample::pCkData;
55    };
56    
57    class PubFile : public gig::File {
58    public:
59        using gig::File::VerifySampleChecksumTable;
60        using gig::File::RebuildSampleChecksumTable;
61    };
62    
63    
64  int main(int argc, char *argv[])  int main(int argc, char *argv[])
65  {  {
66        bool bVerify = false;
67        bool bRebuildChecksums = false;
68        bool bInstrumentNamesOnly = false;
69    
70      if (argc <= 1) {      if (argc <= 1) {
71          PrintUsage();          PrintUsage();
72          return EXIT_FAILURE;          return EXIT_FAILURE;
73      }      }
74      if (argv[1][0] == '-') {  
75          switch (argv[1][1]) {      int iArg;
76              case 'v':      for (iArg = 1; iArg < argc; ++iArg) {
77                  PrintVersion();          const string opt = argv[iArg];
78                  return EXIT_SUCCESS;          if (opt == "--") { // common for all command line tools: separator between initial option arguments and i.e. subsequent file arguments
79                iArg++;
80                break;
81          }          }
82            if (opt.substr(0, 1) != "-") break;
83    
84            if (opt == "-v") {
85                PrintVersion();
86                return EXIT_SUCCESS;
87            } else if (opt == "--verify") {
88                bVerify = true;
89            } else if (opt == "--rebuild-checksums") {
90                bRebuildChecksums = true;
91            } else if (opt == "--instrument-names") {
92                bInstrumentNamesOnly = true;
93            } else {
94                cerr << "Unknown option '" << opt << "'" << endl;
95                cerr << endl;
96                PrintUsage();
97                return EXIT_FAILURE;
98            }
99        }
100        if (iArg >= argc) {
101            cout << "No file name provided!" << endl;
102            return EXIT_FAILURE;
103      }      }
104      FILE* hFile = fopen(argv[1], "r");      const char* filename = argv[iArg];
105    
106        FILE* hFile = fopen(filename, "r");
107      if (!hFile) {      if (!hFile) {
108          cout << "Invalid file argument!" << endl;          cout << "Invalid file argument!" << endl;
109          return EXIT_FAILURE;          return EXIT_FAILURE;
110      }      }
111      fclose(hFile);      fclose(hFile);
112      try {      try {
113          RIFF::File* riff = new RIFF::File(argv[1]);          RIFF::File* riff = new RIFF::File(filename);
114          gig::File*  gig  = new gig::File(riff);          gig::File*  gig  = new gig::File(riff);
115          PrintFileInformations(gig);  
116          cout << endl;          if (bRebuildChecksums) {
117          PrintGroups(gig);              RebuildChecksumTable(gig);
118          cout << endl;          } else if (bVerify) {
119          PrintSamples(gig);              bool OK = VerifyFile(gig);
120          cout << endl;              if (OK) cout << "All checks passed successfully! :-)\n";
121          PrintInstruments(gig);              return (OK) ? EXIT_SUCCESS : EXIT_FAILURE;
122            } else {
123                if (bInstrumentNamesOnly) {
124                    PrintInstrumentNamesOnly(gig);
125                } else {
126                    PrintFileInformation(gig);
127                    cout << endl;
128                    PrintGroups(gig);
129                    cout << endl;
130                    PrintSamples(gig);
131                    cout << endl;
132                    PrintScripts(gig);
133                    cout << endl;
134                    PrintInstruments(gig);
135                }
136            }
137          delete gig;          delete gig;
138          delete riff;          delete riff;
139      }      }
# Line 89  int main(int argc, char *argv[]) Line 149  int main(int argc, char *argv[])
149      return EXIT_SUCCESS;      return EXIT_SUCCESS;
150  }  }
151    
152  void PrintFileInformations(gig::File* gig) {  void PrintFileInformation(gig::File* gig) {
153      cout << "Global File Informations:" << endl;      cout << "Global File Information:" << endl;
154      cout << "    Total instruments: " << gig->Instruments << endl;      cout << "    Total instruments: " << gig->Instruments << endl;
155      if (gig->pVersion) {      if (gig->pVersion) {
156         cout << "    Version: " << gig->pVersion->major   << "."         cout << "    Version: " << gig->pVersion->major   << "."
# Line 150  void PrintGroups(gig::File* gig) { Line 210  void PrintGroups(gig::File* gig) {
210  void PrintSamples(gig::File* gig) {  void PrintSamples(gig::File* gig) {
211      int samples = 0;      int samples = 0;
212      cout << "ALL Available Samples (as there might be more than referenced by Instruments):" << endl;      cout << "ALL Available Samples (as there might be more than referenced by Instruments):" << endl;
213      gig::Sample* pSample = gig->GetFirstSample();      PubSample* pSample = (PubSample*) gig->GetFirstSample();
214      while (pSample) {      while (pSample) {
215          samples++;          samples++;
216          // determine sample's name          // determine sample's name
# Line 176  void PrintSamples(gig::File* gig) { Line 236  void PrintSamples(gig::File* gig) {
236              cout << ", LoopFraction=" << pSample->LoopFraction << ", Start=" << pSample->LoopStart << ", End=" << pSample->LoopEnd;              cout << ", LoopFraction=" << pSample->LoopFraction << ", Start=" << pSample->LoopStart << ", End=" << pSample->LoopEnd;
237              cout << ", LoopPlayCount=" << pSample->LoopPlayCount;              cout << ", LoopPlayCount=" << pSample->LoopPlayCount;
238          }          }
239          cout << ", Length=" << pSample->SamplesTotal << " Compressed=" << ((pSample->Compressed) ? "true" : "false") << endl;          cout << flush;
240          pSample = gig->GetNextSample();          printf(", crc=%x", pSample->GetWaveDataCRC32Checksum());
241            fflush(stdout);
242            cout << ", Length=" << pSample->SamplesTotal << " Compressed=" << ((pSample->Compressed) ? "true" : "false")
243                 << " foffset=" << pSample->pCkData->GetFilePos()
244                 << " fsz=" << pSample->pCkData->GetSize()
245                 << endl;
246    #if 0
247            {
248                const uint bufSize = 64;
249                unsigned char buf[bufSize] = {};
250                pSample->SetPos(0);
251                RIFF::file_offset_t n = pSample->pCkData->Read(&buf[0], bufSize, 1);
252                //RIFF::file_offset_t n = pSample->Read(&buf[0], bufSize / pSample->FrameSize);
253                cout << "        FrameSize=" << pSample->FrameSize << ",Data[" << n << "]" << flush;
254                for (int x = 0; x < bufSize; ++x)
255                    printf("%02x ", buf[x]);
256                printf("\n");
257                fflush(stdout);
258            }
259    #endif
260            pSample = (PubSample*) gig->GetNextSample();
261        }
262    }
263    
264    void PrintScripts(gig::File* gig) {
265        cout << "ALL Available Real-Time Instrument Scripts (as there might be more than referenced by Instruments):" << endl;
266        for (int g = 0; gig->GetScriptGroup(g); ++g) {
267            gig::ScriptGroup* pGroup = gig->GetScriptGroup(g);
268            cout << "    Group " << g+1 << ") '" << pGroup->Name << "'\n";
269            for (int s = 0; pGroup->GetScript(s); ++s) {
270                gig::Script* pScript = pGroup->GetScript(s);
271                cout << "        Script " << s+1 << ") '" << pScript->Name << "':\n";
272                cout << "[START OF SCRIPT]\n";
273                cout << pScript->GetScriptAsText();
274                cout << "[END OF SCRIPT]\n";
275            }
276      }      }
277  }  }
278    
# Line 193  void PrintInstruments(gig::File* gig) { Line 288  void PrintInstruments(gig::File* gig) {
288          cout << "    Instrument " << instruments << ") " << name << ", ";          cout << "    Instrument " << instruments << ") " << name << ", ";
289    
290          cout << " MIDIBank=" << pInstrument->MIDIBank << ", MIDIProgram=" << pInstrument->MIDIProgram << endl;          cout << " MIDIBank=" << pInstrument->MIDIBank << ", MIDIProgram=" << pInstrument->MIDIProgram << endl;
291    
292            cout << "        ScriptSlots=" << pInstrument->ScriptSlotCount() << endl;
293            for (int s = 0; s < pInstrument->ScriptSlotCount(); ++s) {
294                gig::Script* pScript = pInstrument->GetScriptOfSlot(s);
295                string name = pScript->Name;
296                cout << "        ScriptSlot[" << s << "]='" << name << "'\n";
297            }
298    
299          PrintRegions(pInstrument);          PrintRegions(pInstrument);
300    
301          pInstrument = gig->GetNextInstrument();          pInstrument = gig->GetNextInstrument();
302      }      }
303  }  }
304    
305    void PrintInstrumentNamesOnly(gig::File* gig) {
306        int instruments = 0;
307        gig::Instrument* pInstrument = gig->GetFirstInstrument();
308        for (; pInstrument; pInstrument = gig->GetNextInstrument()) {
309            instruments++;
310            string name = pInstrument->pInfo->Name;
311            if (name == "") name = "<NO NAME>";
312            else            name = '\"' + name + '\"';
313            cout << "Instrument " << instruments << ") " << name << endl;
314        }
315    }
316    
317  void PrintRegions(gig::Instrument* instr) {  void PrintRegions(gig::Instrument* instr) {
318      int iRegion = 1;      int iRegion = 1;
319      gig::Region* pRegion = instr->GetFirstRegion();      gig::Region* pRegion = instr->GetFirstRegion();
# Line 351  void PrintRegions(gig::Instrument* instr Line 466  void PrintRegions(gig::Instrument* instr
466      }      }
467  }  }
468    
469    template<typename T_int>
470    static void printIntArray(T_int* array, int size) {
471        printf("{");
472        for (int i = 0; i < size; ++i)
473            printf("[%d]=%d,", i, array[i]);
474        printf("}");
475        fflush(stdout);
476    }
477    
478  void PrintDimensionRegions(gig::Region* rgn) {  void PrintDimensionRegions(gig::Region* rgn) {
479      int dimensionRegions = 0;      int dimensionRegions = 0;
480      gig::DimensionRegion* pDimensionRegion;      gig::DimensionRegion* pDimensionRegion;
# Line 394  void PrintDimensionRegions(gig::Region* Line 518  void PrintDimensionRegions(gig::Region*
518                  cout << "UNKNOWN - please report this !";                  cout << "UNKNOWN - please report this !";
519          }          }
520          cout << ", VelocityResponseDepth=" << (int) pDimensionRegion->VelocityResponseDepth << ", VelocityResponseCurveScaling=" << (int) pDimensionRegion->VelocityResponseCurveScaling << endl;          cout << ", VelocityResponseDepth=" << (int) pDimensionRegion->VelocityResponseDepth << ", VelocityResponseCurveScaling=" << (int) pDimensionRegion->VelocityResponseCurveScaling << endl;
521          cout << "                Pan=" << (int) pDimensionRegion->Pan << endl;          cout << "                VelocityUpperLimit=" << (int) pDimensionRegion->VelocityUpperLimit << " DimensionUpperLimits[]=" << flush;
522            printIntArray(pDimensionRegion->DimensionUpperLimits, 8);
523            cout << endl;
524    #if 0 // requires access to protected member VelocityTable, so commented out for now
525            if (pDimensionRegion->VelocityTable) {
526                cout << "                VelocityTable[]=" << flush;
527                printIntArray(pDimensionRegion->VelocityTable, 127);
528                cout << endl;
529            }
530    #endif
531            cout << "                Pan=" << (int) pDimensionRegion->Pan;
532            cout << ", SustainReleaseTrigger=";
533            switch (pDimensionRegion->SustainReleaseTrigger) {
534                case gig::sust_rel_trg_none:
535                    cout << "NONE";
536                    break;
537                case gig::sust_rel_trg_maxvelocity:
538                    cout << "MAXVELOCITY";
539                    break;
540                case gig::sust_rel_trg_keyvelocity:
541                    cout << "KEYVELOCITY";
542                    break;
543            }
544            cout << ", NoNoteOffReleaseTrigger=" << int(pDimensionRegion->NoNoteOffReleaseTrigger);
545            cout << endl;
546            {
547                gig::eg_opt_t& egopt = pDimensionRegion->EG1Options;
548                cout << "                EG1AttackCancel=" << egopt.AttackCancel << ", EG1AttackHoldCancel=" << egopt.AttackHoldCancel << ", EG1Decay1Cancel=" << egopt.Decay1Cancel << ", EG1Decay2Cancel=" << egopt.Decay2Cancel << ", EG1ReleaseCancel=" << egopt.ReleaseCancel << endl;
549            }
550            {
551                gig::eg_opt_t& egopt = pDimensionRegion->EG2Options;
552                cout << "                EG2AttackCancel=" << egopt.AttackCancel << ", EG2AttackHoldCancel=" << egopt.AttackHoldCancel << ", EG2Decay1Cancel=" << egopt.Decay1Cancel << ", EG2Decay2Cancel=" << egopt.Decay2Cancel << ", EG2ReleaseCancel=" << egopt.ReleaseCancel << endl;
553            }
554    
555          dimensionRegions++;          dimensionRegions++;
556      }      }
557  }  }
558    
559    struct _FailedSample {
560        gig::Sample* sample;
561        uint32_t calculatedCRC;
562    };
563    
564    bool VerifyFile(gig::File* _gig) {
565        PubFile* gig = (PubFile*) _gig;
566    
567        cout << "Verifying sample checksum table ... " << flush;
568        if (!gig->VerifySampleChecksumTable()) {
569            cout << "DAMAGED\n";
570            cout << "You may use --rebuild-checksums to repair the sample checksum table.\n";
571            return false;
572        }
573        cout << "OK\n" << flush;
574    
575        cout << "Verifying samples ... " << flush;
576        std::map<int,_FailedSample> failedSamples;
577        int iTotal = 0;
578        for (gig::Sample* pSample = gig->GetFirstSample(); pSample; pSample = gig->GetNextSample(), ++iTotal) {
579            uint32_t crc; // will be set to the actually now calculated checksum
580            if (!pSample->VerifyWaveData(&crc)) {
581                _FailedSample failed;
582                failed.sample = pSample;
583                failed.calculatedCRC = crc;
584                failedSamples[iTotal] = failed;
585            }
586        }
587        if (failedSamples.empty()) {
588            cout << "ALL OK\n";
589            return true;
590        } else {
591            cout << failedSamples.size() << " of " << iTotal << " Samples DAMAGED:\n";
592            for (std::map<int,_FailedSample>::iterator it = failedSamples.begin(); it != failedSamples.end(); ++it) {
593                const int i = it->first;
594                gig::Sample* pSample = it->second.sample;
595    
596                string name = pSample->pInfo->Name;
597                if (name == "") name = "<NO NAME>";
598                else            name = '\"' + name + '\"';
599    
600                cout << "Damaged Sample " << (i+1) << ") " << name << flush;
601                printf(" expectedCRC=%x calculatedCRC=%x\n", pSample->GetWaveDataCRC32Checksum(), it->second.calculatedCRC);
602            }
603            return false;
604        }
605    }
606    
607    void RebuildChecksumTable(gig::File* _gig) {
608        PubFile* gig = (PubFile*) _gig;
609    
610        cout << "Recalculating checksums of all samples ... " << flush;
611        bool bSaveRequired = gig->RebuildSampleChecksumTable();
612        cout << "OK\n";
613        if (bSaveRequired) {
614            cout << "WARNING: File structure change required, rebuilding entire file now ..." << endl;
615            gig->Save();
616            cout << "DONE\n";
617            cout << "NOTE: Since the entire file was rebuilt, you may need to manually check all samples in this particular case now!\n";
618        }
619    }
620    
621  string Revision() {  string Revision() {
622      string s = "$Revision$";      string s = "$Revision$";
623      return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword      return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
# Line 413  void PrintVersion() { Line 631  void PrintVersion() {
631  void PrintUsage() {  void PrintUsage() {
632      cout << "gigdump - parses Gigasampler files and prints out the content." << endl;      cout << "gigdump - parses Gigasampler files and prints out the content." << endl;
633      cout << endl;      cout << endl;
634      cout << "Usage: gigdump [-v] FILE" << endl;      cout << "Usage: gigdump [-v | --verify | --rebuild-checksums] FILE" << endl;
635        cout << endl;
636        cout << "   --rebuild-checksums  Rebuild checksum table for all samples." << endl;
637        cout << endl;
638        cout << "   -v                   Print version and exit." << endl;
639        cout << endl;
640        cout << "   --verify             Checks raw wave data integrity of all samples." << endl;
641      cout << endl;      cout << endl;
642      cout << "   -v  Print version and exit." << endl;      cout << "   --instrument-names   Print only instrument names." << endl;
643      cout << endl;      cout << endl;
644  }  }

Legend:
Removed from v.2493  
changed lines
  Added in v.3446

  ViewVC Help
Powered by ViewVC