Guest User

wavcrc32

a guest
Jun 18th, 2010
770
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.94 KB | None | 0 0
  1. /*
  2. ----------------------------------------------------------
  3. wavcrc32.cpp
  4. Version 0.22
  5. ----------------------------------------------------------
  6. A program for counting audiodata CRC checksums
  7. that used in EAC (Exact Audio Copy by Andre Wiethoff)
  8. ----------------------------------------------------------
  9. This program is freeware and open-source, you may
  10. freely redistribute or modify it, or use code in your
  11. applications.
  12. ----------------------------------------------------------
  13. I hope this code can be compiled with any C/C++ compiler
  14. like microsoft visual c++, gcc, open-watcom c/c++, ...
  15. If you experience any problems with compiling this program
  16. you may feel free to ask me, what's the hell it is, maybe
  17. I can help you.
  18.  
  19. At this time I've checked that
  20. * gcc/g++ 3.4.4 @ cygwin
  21. * msvc 8.0
  22. * open watcom c/c++ 1.6
  23. work fine with this code!
  24. ----------------------------------------------------------
  25. (c) ]DichlofoS[ Systems, 2007
  26. ----------------------------------------------------------
  27. */
  28.  
  29. #if _MSC_VER >= 1400
  30.     // this option is for Safe STDLIB fopen_s, etc functions
  31.     #define MSC_SAFECODE 1
  32. #else
  33.     #undef MSC_SAFECODE
  34. #endif
  35.  
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38.  
  39. #if _MSC_VER >= 1400
  40.     #include <windows.h>
  41. #endif
  42.  
  43. #define SAMPLE_BUFFER_SIZE 1024
  44.  
  45. // Function prototypes
  46. void InitCRC32Table();
  47. unsigned int Reflect(unsigned int ref, char ch);
  48. bool CheckDWORD(FILE* f, unsigned int nOffset, unsigned int nProperValue, const char* szMessage);
  49. unsigned int CheckRIFFHeader(FILE* f);
  50.  
  51. unsigned int CRC32Table[256];
  52.  
  53. // Call this function only once to initialize the CRC table
  54. void InitCRC32Table()
  55. {
  56.     unsigned int ulPolynomial = 0x04c11db7;
  57.  
  58.     // 256 values representing ASCII character codes.
  59.     for(int i = 0; i <= 0xFF; i++)
  60.     {
  61.         CRC32Table[i] = Reflect(i, 8) << 24;
  62.         for (int j = 0; j < 8; j++)
  63.             CRC32Table[i] = (CRC32Table[i] << 1) ^ (CRC32Table[i] & (1 << 31) ? ulPolynomial : 0);
  64.         CRC32Table[i] = Reflect(CRC32Table[i], 32);
  65.     }
  66. }
  67.  
  68. /*
  69.     Reflection is a requirement for the official CRC-32 standard.
  70.     You can create CRCs without it, but they won't conform to the standard.
  71.     Used only by InitCRC32Table()
  72. */
  73. unsigned int Reflect(unsigned int ref, char ch)
  74. {
  75.     unsigned int value(0);
  76.  
  77.     // Swap bit 0 for bit 7
  78.     // bit 1 for bit 6, etc.
  79.     for (int i = 1; i < (ch + 1); i++)
  80.     {
  81.         if (ref & 1)
  82.             value |= 1 << (ch - i);
  83.         ref >>= 1;
  84.     }
  85.     return value;
  86. }
  87.  
  88. /*
  89.     Checks DWORD in WAV file on validness
  90. */
  91. bool CheckDWORD(FILE* f, unsigned int nOffset, unsigned int nProperValue, const char* szMessage)
  92. {
  93.     unsigned int dwCheck = 0;
  94.     fseek(f, nOffset, SEEK_SET);
  95.     fread(&dwCheck, 1, 4, f);
  96.     if (dwCheck != nProperValue)
  97.     {
  98.         printf("%s\n", szMessage);
  99.         return false;
  100.     }
  101.     return true;
  102. }
  103. /*
  104.     Checks RIFF header in WAV file on validness
  105. */
  106. unsigned int CheckRIFFHeader(FILE* f)
  107. {
  108.     if (!CheckDWORD(f, 0x00, 0x46464952, "*** non-RIFF format!")) return 0;
  109.     if (!CheckDWORD(f, 0x08, 0x45564157, "*** non-WAVE format!")) return 0;
  110.     if (!CheckDWORD(f, 0x0C, 0x20746d66, "*** cannot find format chunk!")) return 0;
  111.     if (!CheckDWORD(f, 0x10, 0x00000010, "*** invalid format chunk size!")) return 0;
  112.     if (!CheckDWORD(f, 0x14, 0x00020001, "*** invalid audio format!")) return 0;
  113.     if (!CheckDWORD(f, 0x24, 0x61746164, "*** cannot find data chunk!")) return 0;
  114.  
  115.     unsigned int dwDataSize = 0;
  116.     fseek(f, 0x28, SEEK_SET);
  117.     fread(&dwDataSize, 1, 4, f);
  118.     return dwDataSize;
  119. }
  120.  
  121.  
  122. int main(int argc, char** argv)
  123. {
  124.     InitCRC32Table();
  125.  
  126. #if _MSC_VER >= 1400
  127.     DWORD StartTime = GetTickCount();
  128. #endif
  129.  
  130.     printf("EAC wavcrc32 v0.22 (c) ]DichlofoS[ Systems, 2007\nthanx to: BakLAN, siro and other beta-testers/contributors!\n");
  131.     if (argc != 2)
  132.     {
  133.         printf("*** invalid cmdline arguments!\nsyntax: wavcrc32 filename.wav\n");
  134.         return -1;
  135.     }
  136.     const char* sFileName = argv[1];
  137.  
  138. #ifdef MSC_SAFECODE
  139.     FILE* f = 0;
  140.     fopen_s(&f, sFileName, "rb");
  141. #else
  142.     FILE* f = fopen(sFileName, "rb");
  143. #endif
  144.  
  145.     if (!f)
  146.     {
  147.         printf("*** cannot open file!\n");
  148.         return -1;
  149.     }
  150.     printf("file opened ok\n");
  151.  
  152.     // check header
  153.     unsigned int nDataSize = CheckRIFFHeader(f);
  154.     if (!nDataSize)
  155.     {
  156.         fclose(f);
  157.         return -1;
  158.     }
  159.     printf("RIFF header checked ok\n");
  160.  
  161.     unsigned char chBuffer[4*SAMPLE_BUFFER_SIZE];
  162.  
  163.     unsigned int nSampleCount = nDataSize >> 2;
  164.  
  165.     unsigned int crc(0xffffffff);
  166.     unsigned int crcns(0xffffffff);
  167.     unsigned int crcnsl(0xffffffff);
  168.     unsigned int crcnslr(0xffffffff);
  169.     unsigned int crcnb(0xffffffff);
  170.  
  171.     printf("please wait while couning checksums...\n");
  172.     printf("processing %d samples...\n", nSampleCount);
  173.  
  174.     unsigned int i = 0;
  175.     while (i < nSampleCount)
  176.     {
  177.         unsigned int nCurrentBlockSize = nSampleCount - i;
  178.         if (nCurrentBlockSize > SAMPLE_BUFFER_SIZE) nCurrentBlockSize = SAMPLE_BUFFER_SIZE;
  179.         if (fread(chBuffer, 1, 4*nCurrentBlockSize, f) != 4*nCurrentBlockSize)
  180.         {
  181.             printf("*** cannot read from input file!\n");
  182.             fclose(f);
  183.             printf("file closed ok\n");
  184.             return -1;
  185.         }
  186.         i += nCurrentBlockSize;
  187.         for (unsigned int k = 0; k < nCurrentBlockSize; k++)
  188.         {
  189.             unsigned char nSample[4];
  190.             *(unsigned int*)nSample = *((unsigned int*)chBuffer+k);
  191.             // calculate checksum skipping nulsamples
  192.             if (*(unsigned int*)nSample)
  193.                 for (int j = 0; j < 4; j++)
  194.                     crcns = (crcns >> 8) ^ CRC32Table[(crcns & 0xFF) ^ nSample[j]];
  195.             // calculate checksum skipping nulsamples on left/right channel
  196.             if (nSample[0] || nSample[1])
  197.                 for (int j = 0; j < 2; j++)
  198.                     crcnslr = (crcnslr >> 8) ^ CRC32Table[(crcnslr & 0xFF) ^ nSample[j]];
  199.             if (nSample[2] || nSample[3])
  200.                 for (int j = 2; j < 4; j++)
  201.                     crcnslr = (crcnslr >> 8) ^ CRC32Table[(crcnslr & 0xFF) ^ nSample[j]];
  202.             // calculate non-zero-bytes checksum on left channel
  203.             if (nSample[0] || nSample[1])
  204.                 for (int j = 0; j < 2; j++)
  205.                     crcnsl = (crcnsl >> 8) ^ CRC32Table[(crcnsl & 0xFF) ^ nSample[j]];
  206.             // calculate non-zero-bytes checksum
  207.             for (int j = 0; j < 4; j++)
  208.                 if (nSample[j])
  209.                     crcnb = (crcnb >> 8) ^ CRC32Table[(crcnb & 0xFF) ^ nSample[j]];
  210.  
  211.             // calculate standard checksum
  212.             for (int j = 0; j < 4; j++)
  213.                 crc = (crc >> 8) ^ CRC32Table[(crc & 0xFF) ^ nSample[j]];
  214.         }
  215.     }
  216.     fclose(f);
  217.     printf("file closed ok\n");
  218.  
  219.     crc = crc^0xffffffff;
  220.     crcns = crcns^0xffffffff;
  221.     crcnsl = crcnsl^0xffffffff;
  222.     crcnslr = crcnslr^0xffffffff;
  223.     crcnb = crcnslr^0xffffffff;
  224.  
  225.     printf("--- used in EAC:\n");
  226.     printf("generic: grabbing, \"no use...\" off [all bytes]            : %08X.\n", crc);
  227.     printf("generic: grabbing, \"no use...\" on [word nulsamples l/r]   : %08X.\n", crcnslr);
  228.     printf("waveditor [word nulsamples l]                             : %08X.\n", crcnsl);
  229.     printf("--- no used in EAC, only for reference:\n");
  230.     printf("byte ignore zeros                                         : %08X.\n", crcnb);
  231.     printf("dword nulsamples                                          : %08X.\n", crcns);
  232.  
  233. #if _MSC_VER >= 1400
  234.     printf("---\ntime elapsed: %d ms\n", GetTickCount()-StartTime);
  235. #endif
  236.     return 0;
  237. }
Advertisement
Add Comment
Please, Sign In to add comment