Solved

VB5 CDDB-Generating CDDB ID

Posted on 1998-09-30
13
580 Views
Last Modified: 2012-06-21
I am trying to get VB5 to generate the ID for a CD for the CDDB-(http://www.cddb.com) They have Delphi and C code to do this, and my efforts to genearate the code have been futile,I really need this code if anyone can provide it!
0
Comment
Question by:flosoft
  • 5
  • 4
  • 3
  • +1
13 Comments
 
LVL 8

Expert Comment

by:MikeP090797
ID: 1437529
post the relevant code here, if it's not too long, I'll try
0
 

Author Comment

by:flosoft
ID: 1437530
//  Code in C, I also have it in pascal(more info can be found at //http://www.cddb.com/downloads)
http://www.experts-exchange.com/Q.10085179
/********************************************************************************************\
 **
 ** ComputeDiscId
 **
 ** This function computes audio CD DISC-ID according to the CDDB specification
 ** under Microsoft Windows environment.
 **
 **------------------------------------------------------------------------------------------
 **
 ** The function reads the CD TOC (Table Of Content) from the specified cd-rom drive
 **   using MCI interface and returns the computed DISC-ID.
 **
 ** Link program with winmm.lib library for MCI interface access.
 **
 ********************************************************************************************
 **
 ** CDDB Specification
 **  
 **
 ** See also:
 **   CDDB web site (http://www.cddb.com/)
 **   CDDB-related software and archive (http://www.cddb.com/downloads/)
 **
 


#include <windows.h>

/********************************************************************************************\
 * ComputeDiscId function                                                                   *
\********************************************************************************************/
//
// Calculates a CD DISC-ID
// Uses MCI interface to query CD information (CD TOC)
//
// input:
//  pszDrive
//    drive which contains the audio CD (e.g.: "d:")
//    if pszDrive is NULL, the first CD drive is used
//
// return:
//  The CD DISC-ID as a DWORD value
//  returns 0 (zero) if drive does not contain a CD
//
// examples
//   dwDiscId=ComputeDiscId(NULL);
//   dwDiscId=ComputeDiscId("d:");
//
DWORD ComputeDiscId(char *pszDrive)
{
      // general variables
      int i;
      DWORD dwDiscId;

      // MCI variables
      MCIDEVICEID wDeviceID;
      MCI_OPEN_PARMS mciOpenParms;
      MCI_SET_PARMS mciSetParms;
      MCI_STATUS_PARMS mciStatusParms;

      // temporary variables
      DWORD dwPosM, dwPosS, dwPosF, dwPos;
      DWORD dwLenM, dwLenS, dwLenF;

      // CD TOC information variables
      struct { int min; int sec; int frame; } cdtoc[100];
      int tot_trks;

      // cddb discid computation variables
      int      j, t, n, cddb_sum;

      /////////////////
      // Read CD TOC //

    // open MCI device
    mciOpenParms.lpstrDeviceType = "cdaudio";
      mciOpenParms.lpstrElementName = pszDrive;
    if (mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | (pszDrive ? MCI_OPEN_ELEMENT : 0), (DWORD)&mciOpenParms))
    {
        return 0;
    }

    // save MCI device ID
    wDeviceID = mciOpenParms.wDeviceID;

      // set time format to minute/second/frame (MSF) format
    mciSetParms.dwTimeFormat = MCI_FORMAT_MSF;
    if (mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)&mciSetParms))
      {
        mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0);
        return 0;
      }

    // get total tracks count
    mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
    if (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD)&mciStatusParms))
      {
        mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0);
        return 0;
    }

    // save total tracks count
    tot_trks = mciStatusParms.dwReturn;

      // for each track, get position (starting location)
    for(i=1; i<=tot_trks; i++) {
        mciStatusParms.dwItem = MCI_STATUS_POSITION;
        mciStatusParms.dwTrack = i;
        if (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK, (DWORD)&mciStatusParms))
            {
            mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0);
            return 0;
        }

            // save track position in MSF format
            cdtoc[i-1].frame = MCI_MSF_FRAME(mciStatusParms.dwReturn);
            cdtoc[i-1].sec = MCI_MSF_SECOND(mciStatusParms.dwReturn);
            cdtoc[i-1].min = MCI_MSF_MINUTE(mciStatusParms.dwReturn);
    }

      /////////////////////////////////////
      // Compute lead-out track position //

      // get last track length
      mciStatusParms.dwItem = MCI_STATUS_LENGTH;
      mciStatusParms.dwTrack = tot_trks;
      if (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK, (DWORD)&mciStatusParms))
      {
            mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0);
            return 0;
      }

      // get last track position
      dwPosM = cdtoc[tot_trks-1].min;
      dwPosS = cdtoc[tot_trks-1].sec;
      dwPosF = cdtoc[tot_trks-1].frame;

      // get last track length
      dwLenM = MCI_MSF_MINUTE(mciStatusParms.dwReturn);
      dwLenS = MCI_MSF_SECOND(mciStatusParms.dwReturn);
      dwLenF = MCI_MSF_FRAME(mciStatusParms.dwReturn) + 1;      // +1 to fix Windows MCI bug, according to cddb howto

      // compute lead-out track position (in frame format)
      dwPos=(dwPosM*60*75)+(dwPosS*75)+dwPosF+(dwLenM*60*75)+(dwLenS*75)+dwLenF;

      // save lead-out track position (in MSF format)
      cdtoc[tot_trks].frame = dwPos % 75;  dwPos = dwPos / 75;
      cdtoc[tot_trks].sec = dwPos % 60;    dwPos = dwPos / 60;
      cdtoc[tot_trks].min = dwPos;

      // close MCI device
    mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0);

      /////////////////////
      // Compute DISC-ID //

      /* For backward compatibility this algorithm must not change */

      // cddb_discid
      i = 0; n = 0;
      while (i < tot_trks) {

            // cddb_sum
            cddb_sum=0;
            j=(cdtoc[i].min * 60) + cdtoc[i].sec;
            while (j > 0) {
                  cddb_sum = cddb_sum + (j % 10);
                  j = j / 10;
            }

            n = n + cddb_sum;
            i++;
      }

      // compute total CD length in seconds
      t = ((cdtoc[tot_trks].min * 60) + cdtoc[tot_trks].sec) - ((cdtoc[0].min * 60) + cdtoc[0].sec);

      // compute disc-id
      dwDiscId = ((n % 0xff) << 24 | t << 8 | tot_trks);

      return dwDiscId;
}


/********************************************************************************************\
 * Main program                                                                             *
\********************************************************************************************/

#include <stdio.h>

//
// Sample program
// Call ComputeDiscId() function and display result
//
int main(void)
{
      int nKey1, nKey2;
      DWORD dwDiscId;

      printf("DISC-ID Calculation program\n");
      printf("Press ENTER to compute disc-id\n");
      printf("Type anything folowed by ENTER to quit\n\n");

      do
      {
            dwDiscId=ComputeDiscId(NULL);

            if (dwDiscId) printf("DISC-ID : %08x\n", dwDiscId);
            else printf("Please insert a CD in your first CD player...\n");

            nKey1=nKey2=getchar();
            while (nKey2!=10) nKey2=getchar();
      }
      while (nKey1==10);

      return 0;
}

If you need the code in Delphi(pascal) just let me know, and thanks!
0
 
LVL 2

Expert Comment

by:mkmccreary
ID: 1437531
I hate to be a point monger, but I'm in a little competition with my boss.  If you boost it to 200 I'll do it.

Sorry,
Martin
0
 

Author Comment

by:flosoft
ID: 1437532
Adjusted points to 220
0
 

Author Comment

by:flosoft
ID: 1437533
I upped the points to 220!
There is info at http://www.cddb.com/downloads, it has the technical specs and some other info to make it easier, If you can do this it will be great, well I even upped the points to more than you wanted so, I am waiting an answer. If you have further questions I can be reached at vbnewbie@yahoo.com
Thanks

0
 
LVL 2

Accepted Solution

by:
mkmccreary earned 220 total points
ID: 1437534
Public Const MCI_ALL_DEVICE_ID = -1   '  Matches all MCI devices
Public Const MCI_ANIM_GETDEVCAPS_CAN_REVERSE = &H4001&
Public Const MCI_ANIM_GETDEVCAPS_CAN_STRETCH = &H4007&
Public Const MCI_ANIM_GETDEVCAPS_FAST_RATE = &H4002&
Public Const MCI_ANIM_GETDEVCAPS_MAX_WINDOWS = &H4008&
Public Const MCI_ANIM_GETDEVCAPS_NORMAL_RATE = &H4004&
Public Const MCI_ANIM_GETDEVCAPS_PALETTES = &H4006&
Public Const MCI_ANIM_GETDEVCAPS_SLOW_RATE = &H4003&
Public Const MCI_ANIM_INFO_TEXT = &H10000
Public Const MCI_ANIM_OPEN_NOSTATIC = &H40000
Public Const MCI_ANIM_OPEN_PARENT = &H20000
Public Const MCI_ANIM_OPEN_WS = &H10000
Public Const MCI_ANIM_PLAY_FAST = &H40000
Public Const MCI_ANIM_PLAY_REVERSE = &H20000
Public Const MCI_ANIM_PLAY_SCAN = &H100000
Public Const MCI_ANIM_PLAY_SLOW = &H80000
Public Const MCI_ANIM_PLAY_SPEED = &H10000
Public Const MCI_ANIM_PUT_DESTINATION = &H40000      '  also  MCI_WHERE
Public Const MCI_ANIM_PUT_SOURCE = &H20000      '  also  MCI_WHERE
Public Const MCI_ANIM_REALIZE_BKGD = &H20000
Public Const MCI_ANIM_REALIZE_NORM = &H10000
Public Const MCI_ANIM_RECT = &H10000
Public Const MCI_ANIM_STATUS_FORWARD = &H4002&
Public Const MCI_ANIM_STATUS_HPAL = &H4004&
Public Const MCI_ANIM_STATUS_HWND = &H4003&
Public Const MCI_ANIM_STATUS_SPEED = &H4001&
Public Const MCI_ANIM_STATUS_STRETCH = &H4005&
Public Const MCI_ANIM_STEP_FRAMES = &H20000
Public Const MCI_ANIM_STEP_REVERSE = &H10000
Public Const MCI_ANIM_UPDATE_HDC = &H20000
Public Const MCI_ANIM_WHERE_DESTINATION = &H40000
Public Const MCI_ANIM_WHERE_SOURCE = &H20000
Public Const MCI_ANIM_WINDOW_DEFAULT = &H0&
Public Const MCI_ANIM_WINDOW_DISABLE_STRETCH = &H200000
Public Const MCI_ANIM_WINDOW_ENABLE_STRETCH = &H100000
Public Const MCI_ANIM_WINDOW_HWND = &H10000
Public Const MCI_ANIM_WINDOW_STATE = &H40000
Public Const MCI_ANIM_WINDOW_TEXT = &H80000
Public Const MCI_BREAK = &H811
Public Const MCI_BREAK_HWND = &H200&
Public Const MCI_BREAK_KEY = &H100&
Public Const MCI_BREAK_OFF = &H400&
Public Const MCI_CD_OFFSET = 1088
Public Const MCI_CLOSE = &H804
Public Const MCI_COPY = &H852
Public Const MCI_CUE = &H830
Public Const MCI_CUT = &H851
Public Const MCI_DELETE = &H856
Public Const MCI_DEVTYPE_ANIMATION = 519
Public Const MCI_DEVTYPE_CD_AUDIO = 516
Public Const MCI_DEVTYPE_DAT = 517
Public Const MCI_DEVTYPE_DIGITAL_VIDEO = 520
Public Const MCI_DEVTYPE_VCR = 513
Public Const MCI_DEVTYPE_FIRST = MCI_DEVTYPE_VCR
Public Const MCI_DEVTYPE_FIRST_USER = &H1000
Public Const MCI_DEVTYPE_SEQUENCER = 523
Public Const MCI_DEVTYPE_LAST = MCI_DEVTYPE_SEQUENCER
Public Const MCI_DEVTYPE_OTHER = 521
Public Const MCI_DEVTYPE_OVERLAY = 515
Public Const MCI_DEVTYPE_SCANNER = 518
Public Const MCI_DEVTYPE_VIDEODISC = 514
Public Const MCI_DEVTYPE_WAVEFORM_AUDIO = 522
Public Const MCI_ESCAPE = &H805
Public Const MCI_FIRST = &H800
Public Const MCI_FORMAT_BYTES = 8
Public Const MCI_FORMAT_FRAMES = 3
Public Const MCI_FORMAT_HMS = 1
Public Const MCI_FORMAT_MILLISECONDS = 0
Public Const MCI_FORMAT_MSF = 2
Public Const MCI_FORMAT_SAMPLES = 9
Public Const MCI_FORMAT_SMPTE_24 = 4
Public Const MCI_FORMAT_SMPTE_25 = 5
Public Const MCI_FORMAT_SMPTE_30 = 6
Public Const MCI_FORMAT_SMPTE_30DROP = 7
Public Const MCI_FORMAT_TMSF = 10
Public Const MCI_FREEZE = &H844
Public Const MCI_FROM = &H4&
Public Const MCI_GETDEVCAPS = &H80B
Public Const MCI_GETDEVCAPS_CAN_EJECT = &H7&
Public Const MCI_GETDEVCAPS_CAN_PLAY = &H8&
Public Const MCI_GETDEVCAPS_CAN_RECORD = &H1&
Public Const MCI_GETDEVCAPS_CAN_SAVE = &H9&
Public Const MCI_GETDEVCAPS_COMPOUND_DEVICE = &H6&
Public Const MCI_GETDEVCAPS_DEVICE_TYPE = &H4&
Public Const MCI_GETDEVCAPS_HAS_AUDIO = &H2&
Public Const MCI_GETDEVCAPS_HAS_VIDEO = &H3&
Public Const MCI_GETDEVCAPS_ITEM = &H100&
Public Const MCI_GETDEVCAPS_USES_FILES = &H5&
Public Const MCI_INFO = &H80A
Public Const MCI_INFO_FILE = &H200&
Public Const MCI_INFO_PRODUCT = &H100&
Public Const MCI_LAST = &HFFF
Public Const MCI_LOAD = &H850
Public Const MCI_LOAD_FILE = &H100&
Public Const MCI_STRING_OFFSET = 512  '  if this number is changed you MUST
Public Const MCI_MODE_NOT_READY = (MCI_STRING_OFFSET + 12)
Public Const MCI_MODE_OPEN = (MCI_STRING_OFFSET + 18)
Public Const MCI_MODE_PAUSE = (MCI_STRING_OFFSET + 17)
Public Const MCI_MODE_PLAY = (MCI_STRING_OFFSET + 14)
Public Const MCI_MODE_RECORD = (MCI_STRING_OFFSET + 15)
Public Const MCI_MODE_SEEK = (MCI_STRING_OFFSET + 16)
Public Const MCI_MODE_STOP = (MCI_STRING_OFFSET + 13)
Public Const MCI_NOTIFY = &H1&
Public Const MCI_NOTIFY_ABORTED = &H4
Public Const MCI_NOTIFY_FAILURE = &H8
Public Const MCI_NOTIFY_SUCCESSFUL = &H1
Public Const MCI_NOTIFY_SUPERSEDED = &H2
Public Const MCI_OPEN = &H803
Public Const MCI_OPEN_ALIAS = &H400&
Public Const MCI_OPEN_ELEMENT = &H200&
Public Const MCI_OPEN_ELEMENT_ID = &H800&
Public Const MCI_OPEN_SHAREABLE = &H100&
Public Const MCI_OPEN_TYPE = &H2000&
Public Const MCI_OPEN_TYPE_ID = &H1000&
Public Const MCI_OVLY_GETDEVCAPS_CAN_FREEZE = &H4002&
Public Const MCI_OVLY_GETDEVCAPS_CAN_STRETCH = &H4001&
Public Const MCI_OVLY_GETDEVCAPS_MAX_WINDOWS = &H4003&
Public Const MCI_OVLY_INFO_TEXT = &H10000
Public Const MCI_OVLY_OPEN_PARENT = &H20000
Public Const MCI_OVLY_OPEN_WS = &H10000
Public Const MCI_OVLY_PUT_DESTINATION = &H40000
Public Const MCI_OVLY_PUT_FRAME = &H80000
Public Const MCI_OVLY_PUT_SOURCE = &H20000
Public Const MCI_OVLY_PUT_VIDEO = &H100000
Public Const MCI_OVLY_RECT = &H10000
Public Const MCI_OVLY_STATUS_HWND = &H4001&
Public Const MCI_OVLY_STATUS_STRETCH = &H4002&
Public Const MCI_OVLY_WHERE_DESTINATION = &H40000
Public Const MCI_OVLY_WHERE_FRAME = &H80000
Public Const MCI_OVLY_WHERE_SOURCE = &H20000
Public Const MCI_OVLY_WHERE_VIDEO = &H100000
Public Const MCI_OVLY_WINDOW_DEFAULT = &H0&
Public Const MCI_OVLY_WINDOW_DISABLE_STRETCH = &H200000
Public Const MCI_OVLY_WINDOW_ENABLE_STRETCH = &H100000
Public Const MCI_OVLY_WINDOW_HWND = &H10000
Public Const MCI_OVLY_WINDOW_STATE = &H40000
Public Const MCI_OVLY_WINDOW_TEXT = &H80000
Public Const MCI_PASTE = &H853
Public Const MCI_PAUSE = &H809
Public Const MCI_PLAY = &H806
Public Const MCI_PUT = &H842
Public Const MCI_REALIZE = &H840
Public Const MCI_RECORD = &H80F
Public Const MCI_RECORD_INSERT = &H100&
Public Const MCI_RECORD_OVERWRITE = &H200&
Public Const MCI_RESUME = &H855
Public Const MCI_SAVE = &H813
Public Const MCI_SAVE_FILE = &H100&
Public Const MCI_SEEK = &H807
Public Const MCI_SEEK_TO_END = &H200&
Public Const MCI_SEEK_TO_START = &H100&
Public Const MCI_SEQ_OFFSET = 1216
Public Const MCI_SEQ_DIV_PPQN = (0 + MCI_SEQ_OFFSET)
Public Const MCI_SEQ_DIV_SMPTE_24 = (1 + MCI_SEQ_OFFSET)
Public Const MCI_SEQ_DIV_SMPTE_25 = (2 + MCI_SEQ_OFFSET)
Public Const MCI_SEQ_DIV_SMPTE_30 = (4 + MCI_SEQ_OFFSET)
Public Const MCI_SEQ_DIV_SMPTE_30DROP = (3 + MCI_SEQ_OFFSET)
Public Const MCI_SEQ_FILE = &H4002
Public Const MCI_SEQ_FORMAT_SONGPTR = &H4001
Public Const MCI_SEQ_MAPPER = 65535
Public Const MCI_SEQ_MIDI = &H4003
Public Const MCI_SEQ_NONE = 65533
Public Const MCI_SEQ_SET_MASTER = &H80000
Public Const MCI_SEQ_SET_OFFSET = &H1000000
Public Const MCI_SEQ_SET_PORT = &H20000
Public Const MCI_SEQ_SET_SLAVE = &H40000
Public Const MCI_SEQ_SET_TEMPO = &H10000
Public Const MCI_SEQ_SMPTE = &H4004
Public Const MCI_SEQ_STATUS_DIVTYPE = &H400A&
Public Const MCI_SEQ_STATUS_MASTER = &H4008&
Public Const MCI_SEQ_STATUS_OFFSET = &H4009&
Public Const MCI_SEQ_STATUS_PORT = &H4003&
Public Const MCI_SEQ_STATUS_SLAVE = &H4007&
Public Const MCI_SEQ_STATUS_TEMPO = &H4002&
Public Const MCI_SET = &H80D
Public Const MCI_SET_AUDIO = &H800&
Public Const MCI_SET_AUDIO_ALL = &H4001&
Public Const MCI_SET_AUDIO_LEFT = &H4002&
Public Const MCI_SET_AUDIO_RIGHT = &H4003&
Public Const MCI_SET_DOOR_CLOSED = &H200&
Public Const MCI_SET_DOOR_OPEN = &H100&
Public Const MCI_SET_OFF = &H4000&
Public Const MCI_SET_ON = &H2000&
Public Const MCI_SET_TIME_FORMAT = &H400&
Public Const MCI_SET_VIDEO = &H1000&
Public Const MCI_SOUND = &H812
Public Const MCI_SOUND_NAME = &H100&
Public Const MCI_SPIN = &H80C
Public Const MCI_STATUS = &H814
Public Const MCI_STATUS_CURRENT_TRACK = &H8&
Public Const MCI_STATUS_ITEM = &H100&
Public Const MCI_STATUS_LENGTH = &H1&
Public Const MCI_STATUS_MEDIA_PRESENT = &H5&
Public Const MCI_STATUS_MODE = &H4&
Public Const MCI_STATUS_NUMBER_OF_TRACKS = &H3&
Public Const MCI_STATUS_POSITION = &H2&
Public Const MCI_STATUS_READY = &H7&
Public Const MCI_STATUS_START = &H200&
Public Const MCI_STATUS_TIME_FORMAT = &H6&
Public Const MCI_STEP = &H80E
Public Const MCI_STOP = &H808
Public Const MCI_SYSINFO = &H810
Public Const MCI_SYSINFO_INSTALLNAME = &H800&
Public Const MCI_SYSINFO_NAME = &H400&
Public Const MCI_SYSINFO_OPEN = &H200&
Public Const MCI_SYSINFO_QUANTITY = &H100&
Public Const MCI_TO = &H8&
Public Const MCI_TRACK = &H10&
Public Const MCI_UNFREEZE = &H845
Public Const MCI_UPDATE = &H854
Public Const MCI_USER_MESSAGES = (&H400 + MCI_FIRST)
Public Const MCI_VD_ESCAPE_STRING = &H100&
Public Const MCI_VD_FORMAT_TRACK = &H4001
Public Const MCI_VD_GETDEVCAPS_CAN_REVERSE = &H4002&
Public Const MCI_VD_GETDEVCAPS_CAV = &H20000
Public Const MCI_VD_GETDEVCAPS_CLV = &H10000
Public Const MCI_VD_GETDEVCAPS_FAST_RATE = &H4003&
Public Const MCI_VD_GETDEVCAPS_NORMAL_RATE = &H4005&
Public Const MCI_VD_GETDEVCAPS_SLOW_RATE = &H4004&
Public Const MCI_VD_OFFSET = 1024
Public Const MCI_VD_MEDIA_CAV = (MCI_VD_OFFSET + 3)
Public Const MCI_VD_MEDIA_CLV = (MCI_VD_OFFSET + 2)
Public Const MCI_VD_MEDIA_OTHER = (MCI_VD_OFFSET + 4)
Public Const MCI_VD_MODE_PARK = (MCI_VD_OFFSET + 1)
Public Const MCI_VD_PLAY_FAST = &H20000
Public Const MCI_VD_PLAY_REVERSE = &H10000
Public Const MCI_VD_PLAY_SCAN = &H80000
Public Const MCI_VD_PLAY_SLOW = &H100000
Public Const MCI_VD_PLAY_SPEED = &H40000
Public Const MCI_VD_SEEK_REVERSE = &H10000
Public Const MCI_VD_SPIN_DOWN = &H20000
Public Const MCI_VD_SPIN_UP = &H10000
Public Const MCI_VD_STATUS_DISC_SIZE = &H4006&
Public Const MCI_VD_STATUS_FORWARD = &H4003&
Public Const MCI_VD_STATUS_MEDIA_TYPE = &H4004&
Public Const MCI_VD_STATUS_SIDE = &H4005&
Public Const MCI_VD_STATUS_SPEED = &H4002&
Public Const MCI_VD_STEP_FRAMES = &H10000
Public Const MCI_VD_STEP_REVERSE = &H20000
Public Const MCI_WAIT = &H2&
Public Const MCI_WAVE_GETDEVCAPS_INPUTS = &H4001&
Public Const MCI_WAVE_GETDEVCAPS_OUTPUTS = &H4002&
Public Const MCI_WAVE_INPUT = &H400000
Public Const MCI_WAVE_OFFSET = 1152
Public Const MCI_WAVE_MAPPER = (MCI_WAVE_OFFSET + 1)
Public Const MCI_WAVE_OPEN_BUFFER = &H10000
Public Const MCI_WAVE_OUTPUT = &H800000
Public Const MCI_WAVE_PCM = (MCI_WAVE_OFFSET + 0)
Public Const MCI_WAVE_SET_ANYINPUT = &H4000000
Public Const MCI_WAVE_SET_ANYOUTPUT = &H8000000
Public Const MCI_WAVE_SET_AVGBYTESPERSEC = &H80000
Public Const MCI_WAVE_SET_BITSPERSAMPLE = &H200000
Public Const MCI_WAVE_SET_BLOCKALIGN = &H100000
Public Const MCI_WAVE_SET_CHANNELS = &H20000
Public Const MCI_WAVE_SET_FORMATTAG = &H10000
Public Const MCI_WAVE_SET_SAMPLESPERSEC = &H40000
Public Const MCI_WAVE_STATUS_AVGBYTESPERSEC = &H4004&
Public Const MCI_WAVE_STATUS_BITSPERSAMPLE = &H4006&
Public Const MCI_WAVE_STATUS_BLOCKALIGN = &H4005&
Public Const MCI_WAVE_STATUS_CHANNELS = &H4002&
Public Const MCI_WAVE_STATUS_FORMATTAG = &H4001&
Public Const MCI_WAVE_STATUS_LEVEL = &H4007&
Public Const MCI_WAVE_STATUS_SAMPLESPERSEC = &H4003&
Public Const MCI_WHERE = &H843
Public Const MCI_WINDOW = &H841
Public Const MCIERR_BASE = 256
Public Const MCIERR_BAD_CONSTANT = (MCIERR_BASE + 34)
Public Const MCIERR_BAD_INTEGER = (MCIERR_BASE + 14)
Public Const MCIERR_BAD_TIME_FORMAT = (MCIERR_BASE + 37)
Public Const MCIERR_CANNOT_LOAD_DRIVER = (MCIERR_BASE + 10)
Public Const MCIERR_CANNOT_USE_ALL = (MCIERR_BASE + 23)
Public Const MCIERR_CREATEWINDOW = (MCIERR_BASE + 91)
Public Const MCIERR_CUSTOM_DRIVER_BASE = (MCIERR_BASE + 256)
Public Const MCIERR_DEVICE_LENGTH = (MCIERR_BASE + 54)
Public Const MCIERR_DEVICE_LOCKED = (MCIERR_BASE + 32)
Public Const MCIERR_DEVICE_NOT_INSTALLED = (MCIERR_BASE + 50)
Public Const MCIERR_DEVICE_NOT_READY = (MCIERR_BASE + 20)
Public Const MCIERR_DEVICE_OPEN = (MCIERR_BASE + 9)
Public Const MCIERR_DEVICE_ORD_LENGTH = (MCIERR_BASE + 55)
Public Const MCIERR_DEVICE_TYPE_REQUIRED = (MCIERR_BASE + 31)
Public Const MCIERR_DRIVER = (MCIERR_BASE + 22)
Public Const MCIERR_DRIVER_INTERNAL = (MCIERR_BASE + 16)
Public Const MCIERR_DUPLICATE_ALIAS = (MCIERR_BASE + 33)
Public Const MCIERR_DUPLICATE_FLAGS = (MCIERR_BASE + 39)
Public Const MCIERR_EXTENSION_NOT_FOUND = (MCIERR_BASE + 25)
Public Const MCIERR_EXTRA_CHARACTERS = (MCIERR_BASE + 49)
Public Const MCIERR_FILE_NOT_FOUND = (MCIERR_BASE + 19)
Public Const MCIERR_FILE_NOT_SAVED = (MCIERR_BASE + 30)
Public Const MCIERR_FILE_READ = (MCIERR_BASE + 92)
Public Const MCIERR_FILE_WRITE = (MCIERR_BASE + 93)
Public Const MCIERR_FILENAME_REQUIRED = (MCIERR_BASE + 48)
Public Const MCIERR_FLAGS_NOT_COMPATIBLE = (MCIERR_BASE + 28)
Public Const MCIERR_GET_CD = (MCIERR_BASE + 51)
Public Const MCIERR_HARDWARE = (MCIERR_BASE + 6)
Public Const MCIERR_ILLEGAL_FOR_AUTO_OPEN = (MCIERR_BASE + 47)
Public Const MCIERR_INTERNAL = (MCIERR_BASE + 21)
Public Const MCIERR_INVALID_DEVICE_ID = (MCIERR_BASE + 1)
Public Const MCIERR_INVALID_DEVICE_NAME = (MCIERR_BASE + 7)
Public Const MCIERR_INVALID_FILE = (MCIERR_BASE + 40)
Public Const MCIERR_MISSING_COMMAND_STRING = (MCIERR_BASE + 11)
Public Const MCIERR_MISSING_DEVICE_NAME = (MCIERR_BASE + 36)
Public Const MCIERR_MISSING_PARAMETER = (MCIERR_BASE + 17)
Public Const MCIERR_MISSING_STRING_ARGUMENT = (MCIERR_BASE + 13)
Public Const MCIERR_MULTIPLE = (MCIERR_BASE + 24)
Public Const MCIERR_MUST_USE_SHAREABLE = (MCIERR_BASE + 35)
Public Const MCIERR_NEW_REQUIRES_ALIAS = (MCIERR_BASE + 43)
Public Const MCIERR_NO_CLOSING_QUOTE = (MCIERR_BASE + 38)
Public Const MCIERR_NO_ELEMENT_ALLOWED = (MCIERR_BASE + 45)
Public Const MCIERR_NO_INTEGER = (MCIERR_BASE + 56)
Public Const MCIERR_NO_WINDOW = (MCIERR_BASE + 90)
Public Const MCIERR_NONAPPLICABLE_FUNCTION = (MCIERR_BASE + 46)
Public Const MCIERR_NOTIFY_ON_AUTO_OPEN = (MCIERR_BASE + 44)
Public Const MCIERR_NULL_PARAMETER_BLOCK = (MCIERR_BASE + 41)
Public Const MCIERR_OUT_OF_MEMORY = (MCIERR_BASE + 8)
Public Const MCIERR_OUTOFRANGE = (MCIERR_BASE + 26)
Public Const MCIERR_PARAM_OVERFLOW = (MCIERR_BASE + 12)
Public Const MCIERR_PARSER_INTERNAL = (MCIERR_BASE + 15)
Public Const MCIERR_SEQ_DIV_INCOMPATIBLE = (MCIERR_BASE + 80)
Public Const MCIERR_SEQ_NOMIDIPRESENT = (MCIERR_BASE + 87)
Public Const MCIERR_SEQ_PORT_INUSE = (MCIERR_BASE + 81)
Public Const MCIERR_SEQ_PORT_MAPNODEVICE = (MCIERR_BASE + 83)
Public Const MCIERR_SEQ_PORT_MISCERROR = (MCIERR_BASE + 84)
Public Const MCIERR_SEQ_PORT_NONEXISTENT = (MCIERR_BASE + 82)
Public Const MCIERR_SEQ_PORTUNSPECIFIED = (MCIERR_BASE + 86)
Public Const MCIERR_SEQ_TIMER = (MCIERR_BASE + 85)
Public Const MCIERR_SET_CD = (MCIERR_BASE + 52)
Public Const MCIERR_SET_DRIVE = (MCIERR_BASE + 53)
Public Const MCIERR_UNNAMED_RESOURCE = (MCIERR_BASE + 42)
Public Const MCIERR_UNRECOGNIZED_COMMAND = (MCIERR_BASE + 5)
Public Const MCIERR_UNRECOGNIZED_KEYWORD = (MCIERR_BASE + 3)
Public Const MCIERR_UNSUPPORTED_FUNCTION = (MCIERR_BASE + 18)
Public Const MCIERR_WAVE_INPUTSINUSE = (MCIERR_BASE + 66)
Public Const MCIERR_WAVE_INPUTSUNSUITABLE = (MCIERR_BASE + 72)
Public Const MCIERR_WAVE_INPUTUNSPECIFIED = (MCIERR_BASE + 69)
Public Const MCIERR_WAVE_OUTPUTSINUSE = (MCIERR_BASE + 64)
Public Const MCIERR_WAVE_OUTPUTSUNSUITABLE = (MCIERR_BASE + 70)
Public Const MCIERR_WAVE_OUTPUTUNSPECIFIED = (MCIERR_BASE + 68)
Public Const MCIERR_WAVE_SETINPUTINUSE = (MCIERR_BASE + 67)
Public Const MCIERR_WAVE_SETINPUTUNSUITABLE = (MCIERR_BASE + 73)
Public Const MCIERR_WAVE_SETOUTPUTINUSE = (MCIERR_BASE + 65)
Public Const MCIERR_WAVE_SETOUTPUTUNSUITABLE = (MCIERR_BASE + 71)


Public Type MCI_OPEN_PARMS
        dwCallback As Long
        wDeviceID As Long
        lpstrDeviceType As String
        lpstrElementName As String
        lpstrAlias As String
End Type

Public Type MCI_SET_PARMS
        dwCallback As Long
        dwTimeFormat As Long
        dwAudio As Long
End Type

Public Type MCI_STATUS_PARMS
        dwCallback As Long
        dwReturn As Long
        dwItem As Long
        dwTrack As Integer
End Type

' CD TOC information variables
Public Type CDTable
    min As Integer
    sec As Integer
    frame As Integer
End Type

Public Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Long, ByVal uMessage As Long, ByVal dwParam1 As Long, dwParam2 As Any) As Long



Public Function ComputeDiscId(pszDrive As String) As Long

Dim i As Integer
Dim dwDiscId As Long
Dim lReturn As Long

' MCI variables
Dim wDeviceID As Long
Dim mciOpenParms As MCI_OPEN_PARMS
Dim mciSetParms As MCI_SET_PARMS
Dim mciStatusParms As MCI_STATUS_PARMS

Dim cdtoc(100) As CDTable

''  temporary variables
Dim dwPosM As Long
Dim dwPosS As Long
Dim dwPosF As Long
Dim dwPos As Long
Dim dwLenM As Long
Dim dwLenS As Long
Dim dwLenF As Long
Dim tot_trks As Integer

' cddb discid computation variables
Dim j As Long
Dim t As Long
Dim n As Long
Dim cddb_sum As Long

'/ Read CD TOC //

'    // open MCI device
    mciOpenParms.lpstrDeviceType = "cdaudio"
    mciOpenParms.lpstrElementName = pszDrive
    If (mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE Or IIf(pszDrive <> "", MCI_OPEN_ELEMENT, 0), mciOpenParms)) Then
        ComputeDiscId = 0
        Exit Function
    End If

    '// save MCI device ID
    wDeviceID = mciOpenParms.wDeviceID

'// set time format to minute/second/frame (MSF) format
    mciSetParms.dwTimeFormat = MCI_FORMAT_MSF
    If (mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, mciSetParms)) Then
        lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)
        ComputeDiscId = 0
        Exit Function
    End If
   
    '// get total tracks count
    mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS
    If (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, mciStatusParms)) Then
        lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)
        ComputeDiscId = 0
        Exit Function
    End If
    '// save total tracks count
    tot_trks = mciStatusParms.dwReturn

'// for each track, get position (starting location)
    For i = 1 To tot_trks
        mciStatusParms.dwItem = MCI_STATUS_POSITION
        mciStatusParms.dwTrack = i
        If (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM Or MCI_TRACK, mciStatusParms)) Then
            lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)
            ComputeDiscId = 0
            Exit Function
        End If

        '// save track position in MSF format
        cdtoc(i - 1).frame = Fix(mciStatusParms.dwReturn / &H10000) And &HFF
        cdtoc(i - 1).sec = Fix(mciStatusParms.dwReturn / &H100) And &HFF
        cdtoc(i - 1).min = mciStatusParms.dwReturn And &HFF
    Next i

'/////////////////////////////////////
'// Compute lead-out track position //

'// get last track length
mciStatusParms.dwItem = MCI_STATUS_LENGTH
mciStatusParms.dwTrack = tot_trks
If (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM Or MCI_TRACK, mciStatusParms)) Then
    lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)
    ComputeDiscId = 0
    Exit Function
End If

'// get last track position
dwPosM = cdtoc(tot_trks - 1).min
dwPosS = cdtoc(tot_trks - 1).sec
dwPosF = cdtoc(tot_trks - 1).frame

'// get last track length
dwLenM = mciStatusParms.dwReturn And &HFF
dwLenS = Fix(mciStatusParms.dwReturn / &H100) And &HFF
dwLenF = (Fix(mciStatusParms.dwReturn / &H10000) And &HFF) + 1 '// +1 to fix Windows MCI bug, according to cddb howto

'// compute lead-out track position (in frame format)
dwPos = (dwPosM * 60 * 75) + (dwPosS * 75) + dwPosF + (dwLenM * 60 * 75) + (dwLenS * 75) + dwLenF

'// save lead-out track position (in MSF format)
cdtoc(tot_trks).frame = dwPos Mod 75
dwPos = Fix(dwPos / 75)
cdtoc(tot_trks).sec = dwPos Mod 60
dwPos = Fix(dwPos / 60)
cdtoc(tot_trks).min = dwPos

'// close MCI device
    lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)

'/////////////////////
'// Compute DISC-ID //

'/* For backward compatibility this algorithm must not change */

'// cddb_discid
i = 0
n = 0
While (i < tot_trks)
    '// cddb_sum
    cddb_sum = 0
    j = (cdtoc(i).min * 60) + cdtoc(i).sec
    While (j > 0)
        cddb_sum = cddb_sum + (j Mod 10)
        j = Fix(j / 10)
    Wend
   
    n = n + cddb_sum
    i = i + 1
Wend

'// compute total CD length in seconds
t = ((cdtoc(tot_trks).min * 60) + cdtoc(tot_trks).sec) - ((cdtoc(0).min * 60) + cdtoc(0).sec)

'// compute disc-id
dwDiscId = (((n Mod &HFF) * &H1000000) Or (t * &H100) Or tot_trks)

ComputeDiscId = dwDiscId

End Function


I also have a project zipped up that I could e-mail to you if you would like.  I tested this out and it appears to work.  Let me know if you want the e-mail by dropping a comment.

Later,
Martin




0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 2

Expert Comment

by:mkmccreary
ID: 1437535
I found a bug, I'm working on fixing it now.  On certain CDs you get an overflow.  C let the overflow become a "negative" number.  VB just doesn't like this.  Let you know when its done.

0
 
LVL 2

Expert Comment

by:mkmccreary
ID: 1437536
The problem is VB doesn't allow for an "Unsigned" type of long.  I think I have it fixed.  I used variants for some of the variables to stop overflow errors, and added functionality to make a two's complement of the number if it is supposed to be negative.  The only part that changed was the function.  Here it is:

Public Function ComputeDiscId(pszDrive As String) As Long

Dim i As Integer
Dim dwDiscId As Variant
Dim lReturn As Long
Dim dblAdjuster As Double

' MCI variables
Dim wDeviceID As Long
Dim mciOpenParms As MCI_OPEN_PARMS
Dim mciSetParms As MCI_SET_PARMS
Dim mciStatusParms As MCI_STATUS_PARMS

Dim cdtoc(100) As CDTable

''  temporary variables
Dim dwPosM As Long
Dim dwPosS As Long
Dim dwPosF As Long
Dim dwPos As Long
Dim dwLenM As Long
Dim dwLenS As Long
Dim dwLenF As Long
Dim tot_trks As Integer

' cddb discid computation variables
Dim j As Variant
Dim t As Variant
Dim n As Variant
Dim cddb_sum As Variant

'/ Read CD TOC //

'    // open MCI device
    mciOpenParms.lpstrDeviceType = "cdaudio"
    mciOpenParms.lpstrElementName = pszDrive
    If (mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE Or IIf(pszDrive <> "", MCI_OPEN_ELEMENT, 0), mciOpenParms)) Then
        ComputeDiscId = 0
        Exit Function
    End If

    '// save MCI device ID
    wDeviceID = mciOpenParms.wDeviceID

'// set time format to minute/second/frame (MSF) format
    mciSetParms.dwTimeFormat = MCI_FORMAT_MSF
    If (mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, mciSetParms)) Then
        lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)
        ComputeDiscId = 0
        Exit Function
    End If
   
    '// get total tracks count
    mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS
    If (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, mciStatusParms)) Then
        lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)
        ComputeDiscId = 0
        Exit Function
    End If
    '// save total tracks count
    tot_trks = mciStatusParms.dwReturn

'// for each track, get position (starting location)
    For i = 1 To tot_trks
        mciStatusParms.dwItem = MCI_STATUS_POSITION
        mciStatusParms.dwTrack = i
        If (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM Or MCI_TRACK, mciStatusParms)) Then
            lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)
            ComputeDiscId = 0
            Exit Function
        End If

        '// save track position in MSF format
        cdtoc(i - 1).frame = Fix(mciStatusParms.dwReturn / &H10000) And &HFF
        cdtoc(i - 1).sec = Fix(mciStatusParms.dwReturn / &H100) And &HFF
        cdtoc(i - 1).min = mciStatusParms.dwReturn And &HFF
    Next i

'/////////////////////////////////////
'// Compute lead-out track position //

'// get last track length
mciStatusParms.dwItem = MCI_STATUS_LENGTH
mciStatusParms.dwTrack = tot_trks
If (mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM Or MCI_TRACK, mciStatusParms)) Then
    lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)
    ComputeDiscId = 0
    Exit Function
End If

'// get last track position
dwPosM = cdtoc(tot_trks - 1).min
dwPosS = cdtoc(tot_trks - 1).sec
dwPosF = cdtoc(tot_trks - 1).frame

'// get last track length
dwLenM = mciStatusParms.dwReturn And &HFF
dwLenS = Fix(mciStatusParms.dwReturn / &H100) And &HFF
dwLenF = (Fix(mciStatusParms.dwReturn / &H10000) And &HFF) + 1 '// +1 to fix Windows MCI bug, according to cddb howto

'// compute lead-out track position (in frame format)
dwPos = (dwPosM * 60 * 75) + (dwPosS * 75) + dwPosF + (dwLenM * 60 * 75) + (dwLenS * 75) + dwLenF

'// save lead-out track position (in MSF format)
cdtoc(tot_trks).frame = dwPos Mod 75
dwPos = Fix(dwPos / 75)
cdtoc(tot_trks).sec = dwPos Mod 60
dwPos = Fix(dwPos / 60)
cdtoc(tot_trks).min = dwPos

'// close MCI device
    lReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0)

'/////////////////////
'// Compute DISC-ID //

'/* For backward compatibility this algorithm must not change */

'// cddb_discid
i = 0
n = 0
While (i < tot_trks)
    '// cddb_sum
    cddb_sum = 0
    j = (cdtoc(i).min * 60) + cdtoc(i).sec
    While (j > 0)
        cddb_sum = cddb_sum + (j Mod 10)
        j = Fix(j / 10)
    Wend
   
    n = n + cddb_sum
    i = i + 1
Wend

'// compute total CD length in seconds
t = ((cdtoc(tot_trks).min * 60) + cdtoc(tot_trks).sec) - ((cdtoc(0).min * 60) + cdtoc(0).sec)

'// compute disc-id
'dwDiscId = CLng(((n Mod &HFF) * &H1000000) Or (t * &H100) Or tot_trks)

dwDiscId = (((n Mod &HFF) * &H1000000) + (t * &H100) + tot_trks)


If dwDiscId > &H7FFFFFFF Then
    'dwDiscId = (((n Mod &H7F) * &H1000000) + (t * &H100) + tot_trks)
    dblAdjuster = &H7FFFFFFF
    dblAdjuster = (dblAdjuster * 2) + 2
    dwDiscId = dwDiscId - dblAdjuster
End If

ComputeDiscId = dwDiscId

End Function

I will also e-mail it to you.

Good Luck,
Martin

0
 

Author Comment

by:flosoft
ID: 1437537
Hey,you hit it on the nose, there are alot of us fairly new to VB that needed this code, and WHAM! you did it! Great job, I only regret that I don't have 1,000 points to give you mkmccreay's! Well Thanks again!
0
 

Expert Comment

by:mp91805
ID: 1437538
Hello mkmccreany
Can I get your project (CDDB)
Thank you so much
0
 
LVL 2

Expert Comment

by:mkmccreary
ID: 1437539
Just give me your e-mail address and it is yours.

Later,
Martin

0
 

Expert Comment

by:mp91805
ID: 1437540
Hello mkmccreany
Can I get your project (CDDB)
Thank you so much
0
 

Expert Comment

by:mp91805
ID: 1437541
my email address is
thee@iname.com
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now