/[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 1953 by schoenebeck, Thu Jul 30 08:16:02 2009 UTC libgig/trunk/src/tools/gigdump.cpp revision 3048 by schoenebeck, Fri Nov 25 18:34:45 2016 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-2016 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    
# Line 40  void PrintVersion(); Line 40  void PrintVersion();
40  void PrintFileInformations(gig::File* gig);  void PrintFileInformations(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 PrintRegions(gig::Instrument* instr);  void PrintRegions(gig::Instrument* instr);
46  void PrintUsage();  void PrintUsage();
47  void PrintDimensionRegions(gig::Region* rgn);  void PrintDimensionRegions(gig::Region* rgn);
48    bool VerifyFile(gig::File* gig);
49    void RebuildChecksumTable(gig::File* gig);
50    
51    class PubSample : public gig::Sample {
52    public:
53        using DLS::Sample::pCkData;
54    };
55    
56    class PubFile : public gig::File {
57    public:
58        using gig::File::VerifySampleChecksumTable;
59        using gig::File::RebuildSampleChecksumTable;
60    };
61    
62    
63  int main(int argc, char *argv[])  int main(int argc, char *argv[])
64  {  {
65        bool bVerify = false;
66        bool bRebuildChecksums = false;
67    
68      if (argc <= 1) {      if (argc <= 1) {
69          PrintUsage();          PrintUsage();
70          return EXIT_FAILURE;          return EXIT_FAILURE;
71      }      }
72      if (argv[1][0] == '-') {  
73          switch (argv[1][1]) {      int iArg;
74              case 'v':      for (iArg = 1; iArg < argc; ++iArg) {
75                  PrintVersion();          const string opt = argv[iArg];
76                  return EXIT_SUCCESS;          if (opt == "--") { // common for all command line tools: separator between initial option arguments and i.e. subsequent file arguments
77                iArg++;
78                break;
79            }
80            if (opt.substr(0, 1) != "-") break;
81    
82            if (opt == "-v") {
83                PrintVersion();
84                return EXIT_SUCCESS;
85            } else if (opt == "--verify") {
86                bVerify = true;
87            } else if (opt == "--rebuild-checksums") {
88                bRebuildChecksums = true;
89            } else {
90                cerr << "Unknown option '" << opt << "'" << endl;
91                cerr << endl;
92                PrintUsage();
93                return EXIT_FAILURE;
94          }          }
95      }      }
96      FILE* hFile = fopen(argv[1], "r");      if (iArg >= argc) {
97            cout << "No file name provided!" << endl;
98            return EXIT_FAILURE;
99        }
100        const char* filename = argv[iArg];
101    
102        FILE* hFile = fopen(filename, "r");
103      if (!hFile) {      if (!hFile) {
104          cout << "Invalid file argument!" << endl;          cout << "Invalid file argument!" << endl;
105          return EXIT_FAILURE;          return EXIT_FAILURE;
106      }      }
107      fclose(hFile);      fclose(hFile);
108      try {      try {
109          RIFF::File* riff = new RIFF::File(argv[1]);          RIFF::File* riff = new RIFF::File(filename);
110          gig::File*  gig  = new gig::File(riff);          gig::File*  gig  = new gig::File(riff);
111          PrintFileInformations(gig);  
112          cout << endl;          if (bRebuildChecksums) {
113          PrintGroups(gig);              RebuildChecksumTable(gig);
114          cout << endl;          } else if (bVerify) {
115          PrintSamples(gig);              bool OK = VerifyFile(gig);
116          cout << endl;              if (OK) cout << "All checks passed successfully! :-)\n";
117          PrintInstruments(gig);              return (OK) ? EXIT_SUCCESS : EXIT_FAILURE;
118            } else {
119                PrintFileInformations(gig);
120                cout << endl;
121                PrintGroups(gig);
122                cout << endl;
123                PrintSamples(gig);
124                cout << endl;
125                PrintScripts(gig);
126                cout << endl;
127                PrintInstruments(gig);
128            }
129          delete gig;          delete gig;
130          delete riff;          delete riff;
131      }      }
# Line 90  int main(int argc, char *argv[]) Line 142  int main(int argc, char *argv[])
142  }  }
143    
144  void PrintFileInformations(gig::File* gig) {  void PrintFileInformations(gig::File* gig) {
145      cout << "Global File Informations:" << endl;      cout << "Global File Information:" << endl;
146      cout << "    Total instruments: " << gig->Instruments << endl;      cout << "    Total instruments: " << gig->Instruments << endl;
147      if (gig->pVersion) {      if (gig->pVersion) {
148         cout << "    Version: " << gig->pVersion->major   << "."         cout << "    Version: " << gig->pVersion->major   << "."
# Line 150  void PrintGroups(gig::File* gig) { Line 202  void PrintGroups(gig::File* gig) {
202  void PrintSamples(gig::File* gig) {  void PrintSamples(gig::File* gig) {
203      int samples = 0;      int samples = 0;
204      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;
205      gig::Sample* pSample = gig->GetFirstSample();      PubSample* pSample = (PubSample*) gig->GetFirstSample();
206      while (pSample) {      while (pSample) {
207          samples++;          samples++;
208          // determine sample's name          // determine sample's name
# Line 176  void PrintSamples(gig::File* gig) { Line 228  void PrintSamples(gig::File* gig) {
228              cout << ", LoopFraction=" << pSample->LoopFraction << ", Start=" << pSample->LoopStart << ", End=" << pSample->LoopEnd;              cout << ", LoopFraction=" << pSample->LoopFraction << ", Start=" << pSample->LoopStart << ", End=" << pSample->LoopEnd;
229              cout << ", LoopPlayCount=" << pSample->LoopPlayCount;              cout << ", LoopPlayCount=" << pSample->LoopPlayCount;
230          }          }
231          cout << ", Length=" << pSample->SamplesTotal << " Compressed=" << ((pSample->Compressed) ? "true" : "false") << endl;          cout << flush;
232          pSample = gig->GetNextSample();          printf(", crc=%x", pSample->GetWaveDataCRC32Checksum());
233            fflush(stdout);
234            cout << ", Length=" << pSample->SamplesTotal << " Compressed=" << ((pSample->Compressed) ? "true" : "false")
235                 << " foffset=" << pSample->pCkData->GetFilePos()
236                 << " fsz=" << pSample->pCkData->GetSize()
237                 << endl;
238    #if 0
239            {
240                const uint bufSize = 64;
241                unsigned char buf[bufSize] = {};
242                pSample->SetPos(0);
243                RIFF::file_offset_t n = pSample->pCkData->Read(&buf[0], bufSize, 1);
244                //RIFF::file_offset_t n = pSample->Read(&buf[0], bufSize / pSample->FrameSize);
245                cout << "        FrameSize=" << pSample->FrameSize << ",Data[" << n << "]" << flush;
246                for (int x = 0; x < bufSize; ++x)
247                    printf("%02x ", buf[x]);
248                printf("\n");
249                fflush(stdout);
250            }
251    #endif
252            pSample = (PubSample*) gig->GetNextSample();
253        }
254    }
255    
256    void PrintScripts(gig::File* gig) {
257        cout << "ALL Available Real-Time Instrument Scripts (as there might be more than referenced by Instruments):" << endl;
258        for (int g = 0; gig->GetScriptGroup(g); ++g) {
259            gig::ScriptGroup* pGroup = gig->GetScriptGroup(g);
260            cout << "    Group " << g+1 << ") '" << pGroup->Name << "'\n";
261            for (int s = 0; pGroup->GetScript(s); ++s) {
262                gig::Script* pScript = pGroup->GetScript(s);
263                cout << "        Script " << s+1 << ") '" << pScript->Name << "':\n";
264                cout << "[START OF SCRIPT]\n";
265                cout << pScript->GetScriptAsText();
266                cout << "[END OF SCRIPT]\n";
267            }
268      }      }
269  }  }
270    
# Line 193  void PrintInstruments(gig::File* gig) { Line 280  void PrintInstruments(gig::File* gig) {
280          cout << "    Instrument " << instruments << ") " << name << ", ";          cout << "    Instrument " << instruments << ") " << name << ", ";
281    
282          cout << " MIDIBank=" << pInstrument->MIDIBank << ", MIDIProgram=" << pInstrument->MIDIProgram << endl;          cout << " MIDIBank=" << pInstrument->MIDIBank << ", MIDIProgram=" << pInstrument->MIDIProgram << endl;
283    
284            cout << "        ScriptSlots=" << pInstrument->ScriptSlotCount() << endl;
285            for (int s = 0; s < pInstrument->ScriptSlotCount(); ++s) {
286                gig::Script* pScript = pInstrument->GetScriptOfSlot(s);
287                string name = pScript->Name;
288                cout << "        ScriptSlot[" << s << "]='" << name << "'\n";
289            }
290    
291          PrintRegions(pInstrument);          PrintRegions(pInstrument);
292    
293          pInstrument = gig->GetNextInstrument();          pInstrument = gig->GetNextInstrument();
# Line 351  void PrintRegions(gig::Instrument* instr Line 446  void PrintRegions(gig::Instrument* instr
446      }      }
447  }  }
448    
449    template<typename T_int>
450    static void printIntArray(T_int* array, int size) {
451        printf("{");
452        for (int i = 0; i < size; ++i)
453            printf("[%d]=%d,", i, array[i]);
454        printf("}");
455        fflush(stdout);
456    }
457    
458  void PrintDimensionRegions(gig::Region* rgn) {  void PrintDimensionRegions(gig::Region* rgn) {
459      int dimensionRegions = 0;      int dimensionRegions = 0;
460      gig::DimensionRegion* pDimensionRegion;      gig::DimensionRegion* pDimensionRegion;
# Line 394  void PrintDimensionRegions(gig::Region* Line 498  void PrintDimensionRegions(gig::Region*
498                  cout << "UNKNOWN - please report this !";                  cout << "UNKNOWN - please report this !";
499          }          }
500          cout << ", VelocityResponseDepth=" << (int) pDimensionRegion->VelocityResponseDepth << ", VelocityResponseCurveScaling=" << (int) pDimensionRegion->VelocityResponseCurveScaling << endl;          cout << ", VelocityResponseDepth=" << (int) pDimensionRegion->VelocityResponseDepth << ", VelocityResponseCurveScaling=" << (int) pDimensionRegion->VelocityResponseCurveScaling << endl;
501            cout << "                VelocityUpperLimit=" << (int) pDimensionRegion->VelocityUpperLimit << " DimensionUpperLimits[]=" << flush;
502            printIntArray(pDimensionRegion->DimensionUpperLimits, 8);
503            cout << endl;
504    #if 0 // requires access to protected member VelocityTable, so commented out for now
505            if (pDimensionRegion->VelocityTable) {
506                cout << "                VelocityTable[]=" << flush;
507                printIntArray(pDimensionRegion->VelocityTable, 127);
508                cout << endl;
509            }
510    #endif
511          cout << "                Pan=" << (int) pDimensionRegion->Pan << endl;          cout << "                Pan=" << (int) pDimensionRegion->Pan << endl;
512    
513          dimensionRegions++;          dimensionRegions++;
514      }      }
515  }  }
516    
517    struct _FailedSample {
518        gig::Sample* sample;
519        uint32_t calculatedCRC;
520    };
521    
522    bool VerifyFile(gig::File* _gig) {
523        PubFile* gig = (PubFile*) _gig;
524    
525        cout << "Verifying sample checksum table ... " << flush;
526        if (!gig->VerifySampleChecksumTable()) {
527            cout << "DAMAGED\n";
528            cout << "You may use --rebuild-checksums to repair the sample checksum table.\n";
529            return false;
530        }
531        cout << "OK\n" << flush;
532    
533        cout << "Verifying samples ... " << flush;
534        std::map<int,_FailedSample> failedSamples;
535        int iTotal = 0;
536        for (gig::Sample* pSample = gig->GetFirstSample(); pSample; pSample = gig->GetNextSample(), ++iTotal) {
537            uint32_t crc; // will be set to the actually now calculated checksum
538            if (!pSample->VerifyWaveData(&crc)) {
539                _FailedSample failed;
540                failed.sample = pSample;
541                failed.calculatedCRC = crc;
542                failedSamples[iTotal] = failed;
543            }
544        }
545        if (failedSamples.empty()) {
546            cout << "ALL OK\n";
547            return true;
548        } else {
549            cout << failedSamples.size() << " of " << iTotal << " Samples DAMAGED:\n";
550            for (std::map<int,_FailedSample>::iterator it = failedSamples.begin(); it != failedSamples.end(); ++it) {
551                const int i = it->first;
552                gig::Sample* pSample = it->second.sample;
553    
554                string name = pSample->pInfo->Name;
555                if (name == "") name = "<NO NAME>";
556                else            name = '\"' + name + '\"';
557    
558                cout << "Damaged Sample " << (i+1) << ") " << name << flush;
559                printf(" expectedCRC=%x calculatedCRC=%x\n", pSample->GetWaveDataCRC32Checksum(), it->second.calculatedCRC);
560            }
561            return false;
562        }
563    }
564    
565    void RebuildChecksumTable(gig::File* _gig) {
566        PubFile* gig = (PubFile*) _gig;
567    
568        cout << "Recalculating checksums of all samples ... " << flush;
569        bool bSaveRequired = gig->RebuildSampleChecksumTable();
570        cout << "OK\n";
571        if (bSaveRequired) {
572            cout << "WARNING: File structure change required, rebuilding entire file now ..." << endl;
573            gig->Save();
574            cout << "DONE\n";
575            cout << "NOTE: Since the entire file was rebuilt, you may need to manually check all samples in this particular case now!\n";
576        }
577    }
578    
579  string Revision() {  string Revision() {
580      string s = "$Revision: 1.24 $";      string s = "$Revision$";
581      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
582  }  }
583    
# Line 413  void PrintVersion() { Line 589  void PrintVersion() {
589  void PrintUsage() {  void PrintUsage() {
590      cout << "gigdump - parses Gigasampler files and prints out the content." << endl;      cout << "gigdump - parses Gigasampler files and prints out the content." << endl;
591      cout << endl;      cout << endl;
592      cout << "Usage: gigdump [-v] FILE" << endl;      cout << "Usage: gigdump [-v | --verify | --rebuild-checksums] FILE" << endl;
593        cout << endl;
594        cout << "   --rebuild-checksums  Rebuild checksum table for all samples." << endl;
595        cout << endl;
596        cout << "   -v                   Print version and exit." << endl;
597      cout << endl;      cout << endl;
598      cout << "   -v  Print version and exit." << endl;      cout << "   --verify             Checks raw wave data integrity of all samples." << endl;
599      cout << endl;      cout << endl;
600  }  }

Legend:
Removed from v.1953  
changed lines
  Added in v.3048

  ViewVC Help
Powered by ViewVC