home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / cdtst105.zip / testspeed.cpp < prev    next >
C/C++ Source or Header  |  1999-01-30  |  6KB  |  214 lines

  1. /* CD-ROM speed tester (C) 1998-1999 Samuel Audet <guardia@cam.org> */
  2.  
  3. #define INCL_PM
  4. #define INCL_DOS
  5. #include <os2.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <time.h>
  10. #include <conio.h>
  11. #include <float.h>
  12.  
  13. #include "miscsam.h"
  14. #include "readcd.h"
  15.  
  16. #define CHUNK 27
  17.  
  18. void displayHelp(char *program)
  19. {
  20.     printf("CD-ROM Speed Tester 1.0  (C) 1998 Samuel Audet <guardia@cam.org>\n"
  21.            "\n"
  22.            "Syntax:\n"
  23.            "   %s <cd drive letter> [/c <bogus cache size in kB>] [/t <track,track,...>] [/s <fake cd writing speed>]\n"
  24.            "\n"
  25.            "The default bogus cache size is 4096 kB.  "
  26.            "By default, all tracks are tested.\n"
  27.            "The default fake CD writing speed is 4x.\n",program);
  28. }
  29.  
  30. int main(int argc, char *argv[])
  31. {
  32.    CD_drive drive;
  33.    ULONG firstsector, lastsector, sector;
  34.    CDREADLONGDATA data[CHUNK];
  35.    double *timeTable;
  36.    double lowestSpeed;
  37.    int sizeTable;
  38.    int farpos, curpos, i, e;
  39.    char *driveLetter = NULL;
  40.    short cacheSize = 4096, cacheStatus;
  41.    double cdSpeed = 4.0;
  42.    double lastTime, curTime, timer;
  43.    char tracksToTest[256];
  44.    int hitBottom; /* how many times did the cache empty */
  45.  
  46.    /* all tracks */
  47.    for(i = 0; i < 256; i++)
  48.       tracksToTest[i] = i+1;
  49.  
  50.    if(argc == 1)
  51.    {
  52.       displayHelp(argv[0]);
  53.       return 0;
  54.    }
  55.  
  56.  
  57.    for(i = 1; i < argc; i++)
  58.    {
  59.       if(argv[i][0] == '/' || argv[i][0] == '-')
  60.       {
  61.          switch(argv[i][1])
  62.          {
  63.             case 'c': case 'C':
  64.                cacheSize = atoi(argv[++i]); break;
  65.             case 't': case 'T':
  66.             {
  67.                char *comma = argv[++i];
  68.                e = 0;
  69.                do 
  70.                {
  71.                   tracksToTest[e++] = atoi(comma);
  72.                } while((comma = strchr(comma,',')+1) != (char*)1);
  73.                tracksToTest[e] = 0;
  74.                break;
  75.             }
  76.             case 's': case 'S':
  77.                cdSpeed = atoi(argv[++i]); break;
  78.             case '?':
  79.             default:
  80.                displayHelp(argv[0]); return 0;
  81.          }
  82.       }
  83.       else
  84.          driveLetter = argv[i];
  85.    }
  86.  
  87.    if(!driveLetter)
  88.    {
  89.       fprintf(stderr,"Error: no drive letter specified.");
  90.       return 1;
  91.    }
  92.  
  93.    printf("Faking a %d kB cache writing at %#.3gx.\n",cacheSize,cdSpeed);
  94.  
  95.    sizeTable = cacheSize*1024/2352/CHUNK;
  96.    timeTable = (double*)alloca(sizeTable*sizeof(timeTable[0]));
  97.  
  98.    drive.open(driveLetter);
  99.    drive.readCDInfo();
  100.    drive.fillTrackInfo();
  101.  
  102.    for(i = 0; i < 256 && tracksToTest[i]; i++)
  103.    {
  104.       bool found = false;
  105.  
  106.       /* finding the track */
  107.       for(e = 0; e < drive.getCount() && !found; e++)
  108.          if(drive.getTrackInfo(e)->number == tracksToTest[i])
  109.             found = true;
  110.       if(!found)
  111.          continue;
  112.       e--;
  113.  
  114.       timeTable[0] = (double) clock()/CLOCKS_PER_SEC;
  115.       firstsector = sector = CD_drive::getLBA(drive.getTrackInfo(e)->start);
  116.       lastsector = CD_drive::getLBA(drive.getTrackInfo(e)->end);
  117.       curpos = farpos = 0;
  118.       lowestSpeed = _INF;
  119.       cacheStatus = 0;
  120.       lastTime = (double) clock()/CLOCKS_PER_SEC;
  121.       hitBottom = 0;
  122.  
  123.       /* spin up the drive */
  124.       drive.readSectors(data,1,sector);
  125.       DosSleep(2000);
  126.  
  127.       printf("Testing track %d...\n",drive.getTrackInfo(e)->number);
  128.  
  129.       while(sector < lastsector-1)
  130.       {
  131.          int timeLength; /* length between two times */
  132.          double speed, xspeed;
  133.          int readLength = min(CHUNK,lastsector-sector-1); /* amount of sectors to read */
  134.          BOOL updateScreen = FALSE;
  135.  
  136.          curTime = (double) clock()/CLOCKS_PER_SEC;
  137.          timer += (curTime - lastTime);
  138.          if(timer > 0.5 || sector+readLength >= lastsector-1)
  139.             updateScreen = TRUE;
  140.  
  141.          if(updateScreen)
  142.          {
  143.             if(_kbhit() && _getch() == 27)
  144.             {
  145.                i = drive.getCount();
  146.                break;
  147.             }
  148.  
  149.             fflush(stdin);
  150.  
  151.             printf("Reading %6.1d -> %d ",sector, lastsector-1);
  152.          }
  153.          drive.readSectors(data,readLength,sector);
  154.          sector += readLength;
  155.  
  156.          curpos++;
  157.          if(curpos >= sizeTable)
  158.             curpos = 0;
  159.  
  160.          if(curpos == farpos)
  161.          {
  162.             farpos++;
  163.             if(farpos >= sizeTable)
  164.                farpos = 0;
  165.          }
  166.  
  167.  
  168.          if(curpos > farpos)
  169.             timeLength = (curpos-farpos)*CHUNK*2352;
  170.          else
  171.             timeLength = (sizeTable-farpos+curpos)*CHUNK*2352;
  172.  
  173.          timeTable[curpos] = (double) clock()/CLOCKS_PER_SEC;
  174.  
  175.          speed = timeLength/(timeTable[curpos]-timeTable[farpos])/1024;
  176.          xspeed = speed /150;
  177.  
  178.          if(updateScreen)
  179.             printf(" Avg Speed: %#8.6g kB/s == %#.3gx ", speed, xspeed);
  180.  
  181.  
  182.          cacheStatus += readLength * 2352/1024;
  183.          if(sector-firstsector > sizeTable*CHUNK)
  184.             cacheStatus -= (curTime-lastTime) * cdSpeed * 150;
  185.          /* truncate the cache data if it's too big */
  186.          if(cacheStatus > cacheSize)
  187.             cacheStatus = cacheSize;
  188.          else if(cacheStatus <= 0)
  189.          {
  190.             cacheStatus = 0;
  191.             hitBottom++;
  192.          }
  193.          if(updateScreen)
  194.             printf(" Cache: %5.1d kB  \r",cacheStatus);
  195.  
  196.  
  197.          if(speed < lowestSpeed && sector-firstsector > sizeTable*CHUNK)
  198.             lowestSpeed = speed;
  199.  
  200.          if(updateScreen)
  201.          {
  202.             fflush(stdout);
  203.             timer = 0.0;
  204.          }
  205.          lastTime = curTime;
  206.       }
  207.       printf("\nLowest Speed: %#8.6g kB/s == %#.3gx  Hit Bottom: %d times\n",lowestSpeed,lowestSpeed/150, hitBottom);
  208.    }
  209.  
  210.    drive.close();
  211.  
  212.    return 0;
  213. }
  214.