Advertisement
Guest User

wavcrc32

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