Пример #1
0
static unsigned long cddb_discid(int tot_trks)
{
    unsigned int i, t = 0, n = 0;

    i = 0;
    while (i < (unsigned int)tot_trks) {
        n = n + cddb_sum((cdtoc[i].min * 60) + cdtoc[i].sec);
        i++;
    }
    t = ((cdtoc[tot_trks].min * 60) + cdtoc[tot_trks].sec) -
        ((cdtoc[0].min * 60) + cdtoc[0].sec);
    return (n % 0xff) << 24 | t << 8 | tot_trks;
}
Пример #2
0
unsigned long cddb_discid(FMOD_CDTOC *toc)
{
    int	i, t, n = 0;

    for (i = 0; i < toc->numtracks; i++)
    {
        n += cddb_sum((toc->min[i] * 60) + toc->sec[i]);
    }

    t = ((toc->min[toc->numtracks] * 60) + toc->sec[toc->numtracks]) - ((toc->min[0] * 60) + toc->sec[0]);

    return ((n % 0xff) << 24 | t << 8 | toc->numtracks);
}
Пример #3
0
/*
 * cddb_discid(cdinfo)
 *
 * calculates the id for a given cdinfo structure
 */
unsigned long cddb_discid(CDInfo *cdinfo)
{
  int i, t=0, n=0;

  /* For backward compatibility this algorithm must not change */
  for (i=0; i<cdinfo->tracks; i++) {
    n+=cddb_sum((cdinfo->track[i].start.minute*60) + cdinfo->track[i].start.second);
    t+=((cdinfo->track[i+1].start.minute*60) + cdinfo->track[i+1].start.second) -
      ((cdinfo->track[i].start.minute*60) + cdinfo->track[i].start.second);
  }
  cdinfo->discid=((n % 0xff) << 24 | t << 8 | cdinfo->tracks);
  return cdinfo->discid;
}
Пример #4
0
// static
Cddb::discid_t Cddb::Discid(unsigned& secs, const Msf v[], unsigned tracks)
{
    int checkSum = 0;
    for (unsigned t = 0; t < tracks; ++t)
        checkSum += cddb_sum(v[t].min * SECS_PER_MIN + v[t].sec);

    secs = v[tracks].min * SECS_PER_MIN + v[tracks].sec -
        (v[0].min * SECS_PER_MIN + v[0].sec);

    const discid_t discID = ((discid_t)(checkSum % 255) << 24) |
        ((discid_t)secs << 8) | tracks;
    return discID;
}
Пример #5
0
unsigned long discid(cd * this_cd) {
  unsigned int i=0, t, n = 0, trks=0, l=0;

  for (i=0; i< this_cd->tracks; i++)
    if(this_cd->track[T2I(i)].type==AUDIO) {
      n += cddb_sum((this_cd->track[T2I(i)].start_lba+CD_MSF_OFFSET)/CD_FRAMES);
      trks++; l=i;
      }

  t = (this_cd->track[T2I(l+1)].start_lba-
       this_cd->track[T2I(0)].start_lba)/CD_FRAMES;

  return (((n % 0xFF) << 24) | (t << 8) | trks);
}
Пример #6
0
guint32
cd_cddb_discid (struct cd * cd)
{
  guint i;
  guint n = 0;
  guint t;

  for (i = 1; i <= cd->num_tracks; i++) {
    n += cddb_sum (cd->tracks[i].minute * 60 + cd->tracks[i].second);
  }

  t = (cd->tracks[LEADOUT].minute * 60 + cd->tracks[LEADOUT].second) -
      (cd->tracks[1].minute * 60 + cd->tracks[1].second);

  return ((n % 0xff) << 24 | t << 8 | (cd->num_tracks));
}
Пример #7
0
static uint32_t
diskid(Toc *t)
{
	int i, n, tmp;
	Msf *ms, *me;

	n = 0;
	for(i=0; i < t->ntrack; i++)
		n += cddb_sum(t->track[i].start.m*60+t->track[i].start.s);

	ms = &t->track[0].start;
	me = &t->track[t->ntrack].start;
	tmp = (me->m*60+me->s) - (ms->m*60+ms->s);

	/*
	 * the spec says n%0xFF rather than n&0xFF.  it's unclear which is correct.
	 * most CDs are in the database under both entries.
	 */
	return ((n & 0xFF) << 24 | (tmp << 8) | t->ntrack);
}
Пример #8
0
Файл: rbaudio.c Проект: btb/d2x
uint32_t RBAGetDiscID()
{
	int i, t = 0, n = 0;

	if (!initialised)
		return 0;

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

	i = 0;

	while (i < s_cd->numtracks) {
		n += cddb_sum(s_cd->track[i].offset / CD_FPS);
		i++;
	}

	t = (s_cd->track[s_cd->numtracks].offset / CD_FPS) -
	    (s_cd->track[0].offset / CD_FPS);

	return ((n % 0xff) << 24 | t << 8 | s_cd->numtracks);
}
Пример #9
0
int32 
CDDBQuery::GetDiscID(const scsi_toc *toc)
{
	// The SCSI TOC data has a 4-byte header and then each track record starts
	TrackRecord *tocData = (TrackRecord*)&(toc->toc_data[4]);

	int32 numTracks = toc->toc_data[3] - toc->toc_data[2] + 1;

	int32 sum1 = 0;
	int32 sum2 = 0;
	for (int index = 0; index < numTracks; index++) {
		sum1 += cddb_sum((tocData[index].min * 60) + tocData[index].sec);

		// the following is probably running over too far
		sum2 +=	(tocData[index + 1].min * 60 + tocData[index + 1].sec) 
				- (tocData[index].min * 60 + tocData[index].sec);
	}
	int32 discID = ((sum1 % 0xff) << 24) + (sum2 << 8) + numTracks;

	return discID;
}
Пример #10
0
int32
CDAudioDevice::GetDiscID()
{
	// Read the disc
	scsi_toc toc;
	status_t result = ioctl(fFileHandle, B_SCSI_GET_TOC, &toc);

	if (result != B_OK)
		return -1;


	int32 id, numTracks;
	BString frameOffsetsString;

	ConvertedToc tocData[100];

	// figure out the disc ID
	for (int index = 0; index < 100; index++) {
		tocData[index].min = toc.toc_data[9 + 8 * index];
		tocData[index].sec = toc.toc_data[10 + 8 * index];
		tocData[index].frame = toc.toc_data[11 + 8 * index];
	}
	numTracks = toc.toc_data[3] - toc.toc_data[2] + 1;

	int32 sum1 = 0;
	int32 sum2 = 0;
	for (int index = 0; index < numTracks; index++) {
		sum1 += cddb_sum((tocData[index].min * 60) + tocData[index].sec);
		
		// the following is probably running over too far
		sum2 +=	(tocData[index + 1].min * 60 + tocData[index + 1].sec) -
			(tocData[index].min * 60 + tocData[index].sec);
	}
	id = ((sum1 % 0xff) << 24) + (sum2 << 8) + numTracks;

	return id;
}
Пример #11
0
int analyze_cdaccess(int fd, SOURCE *s, int level)
{
  int i;
  int first, last, ntracks;
  int cksum, totaltime, seconds;
  u4 diskid;
  u1 ctrl[100];
  u4 lba[100], length;
  char human_readable_size[256];
#ifdef USE_IOCTL_LINUX
  struct cdrom_tochdr tochdr;
  struct cdrom_tocentry tocentry;
#endif

  /* read TOC header */
#ifdef USE_IOCTL_LINUX
  if (ioctl(fd, CDROMREADTOCHDR, &tochdr) < 0) {
    return 0;
  }
  first = tochdr.cdth_trk0;
  last  = tochdr.cdth_trk1;
#endif

  ntracks = last + 1 - first;
  if (ntracks > 99)  /* natural limit */
    return 0;

  /* read per-track data from TOC */
  for (i = 0; i <= ntracks; i++) {
#ifdef USE_IOCTL_LINUX
    if (i == ntracks)
      tocentry.cdte_track = CDROM_LEADOUT;
    else
      tocentry.cdte_track = first + i;
    tocentry.cdte_format = CDROM_LBA;
    if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) < 0) {
      //printf("CDROMREADTOCENTRY: %s: ", strerror(errno));
      return 0;
    }
    ctrl[i] = tocentry.cdte_ctrl;
    lba[i] = tocentry.cdte_addr.lba;
#endif
  }

  /* System-dependent code ends here. From now on, we use the data
     in first, last, ntracks, ctrl[], and lba[]. We also assume
     all systems treat actual data access the same way... */

  /* calculate CDDB disk id */
  cksum = 0;
  for (i = 0; i < ntracks; i++) {
    cksum += cddb_sum(LBA_TO_SECS(lba[i]));
  }
  totaltime = LBA_TO_SECS(lba[ntracks]) - LBA_TO_SECS(lba[0]);
  diskid = (u4)(cksum % 0xff) << 24 | (u4)totaltime << 8 | (u4)ntracks;

  /* print disk info */
  print_line(level, "CD-ROM, %d track%s, CDDB disk ID %08lX",
             ntracks, (ntracks != 1) ? "s" : "", diskid);

  /* Loop over each track */
  for (i = 0; i < ntracks; i++) {
    /* length of track in sectors */
    length = lba[i+1] - lba[i];

    if ((ctrl[i] & 0x4) == 0) {
      /* Audio track, one sector holds 2352 actual data bytes */
      seconds = length / 75;
      format_size(human_readable_size, (u8)length * 2352);
      print_line(level, "Track %d: Audio track, %s, %3d min %02d sec", 
                 first + i, human_readable_size,
                 seconds / 60, seconds % 60);

    } else {
      /* Data track, one sector holds 2048 actual data bytes */
      format_size(human_readable_size, length * 2048);
      print_line(level, "Track %d: Data track, %s",
                 first + i, human_readable_size);

      /* NOTE: we adjust the length to stay clear of padding or
         post-gap stuff */
      analyze_source_special(s, level + 1,
                             (u8)lba[i] * 2048, (u8)(length - 250) * 2048);
    }
  }

  return 1;
}
Пример #12
0
int main(int argc, char *argv[])
{
	int len;
	int drive, i, totaltime;
	long int cksum=0;
	int musicbrainz=0;
	unsigned char first=1, last=1;
	char *devicename=DEVICE_NAME;
	struct cdrom_tochdr hdr;
	struct cdrom_tocentry *TocEntry;
	char *command=argv[0];
#if defined(__OpenBSD__) || defined(__NetBSD__)
	struct ioc_read_toc_entry t;
#elif defined(__APPLE__)
	dk_cd_read_disc_info_t discInfoParams;
#endif

	if (argc >= 2 && ! strcmp(argv[1], "--musicbrainz")) {
		musicbrainz = 1;
		argc--;
		argv++;
	}
	if (argc == 2) {
		devicename = argv[1];
	} else if (argc > 2) {
		fprintf(stderr, "Usage: %s [--musicbrainz] [devicename]\n",
			command);
		exit(1);
	}

	drive = open(devicename, O_RDONLY | O_NONBLOCK);
	if (drive < 0) {
		fprintf(stderr, "%s: %s: ", argv[0], devicename);
		perror("open");
		exit(1);
	}

#if defined(__APPLE__)
	memset(&discInfoParams, 0, sizeof(discInfoParams));
	discInfoParams.buffer = &hdr;
	discInfoParams.bufferLength = sizeof(hdr);
	if (ioctl(drive, DKIOCCDREADDISCINFO, &discInfoParams) < 0
		|| discInfoParams.bufferLength != sizeof(hdr)) {
		fprintf(stderr, "%s: %s: ", argv[0], devicename);
		perror("DKIOCCDREADDISCINFO");
		exit(1);
	}
#else
	if (ioctl(drive, CDROMREADTOCHDR, &hdr) < 0) {
		fprintf(stderr, "%s: %s: ", argv[0], devicename);
		perror("CDROMREADTOCHDR");
		exit(1);
	}
#endif

	first = hdr.cdth_trk0;
	last = hdr.cdth_trk1;

	len = (last + 1) * sizeof(struct cdrom_tocentry);

	TocEntry = malloc(len);
	if (!TocEntry) {
		fprintf(stderr,
			"%s: %s: Can't allocate memory for TOC entries\n",
			argv[0], devicename);
		exit(1);
	}
#if defined(__OpenBSD__) 
	t.starting_track = 0;
#elif defined(__NetBSD__)
	t.starting_track = 1;
#endif
#if defined(__OpenBSD__) || defined(__NetBSD__)
	t.address_format = CDROM_LBA;
	t.data_len = len;
	t.data = TocEntry;
	memset(TocEntry, 0, len);
	
	if (ioctl(drive, CDIOREADTOCENTRYS, (char *) &t) < 0) {
		fprintf(stderr, "%s: %s: ", argv[0], devicename);
		perror("CDIOREADTOCENTRYS");
	}
#elif defined(__APPLE__)
	dk_cd_read_track_info_t trackInfoParams;
	memset( &trackInfoParams, 0, sizeof( trackInfoParams ) );
	trackInfoParams.addressType = kCDTrackInfoAddressTypeTrackNumber;
	trackInfoParams.bufferLength = sizeof( *TocEntry );
        
	for (i = 0; i < last; i++) {
		trackInfoParams.address = i + 1;
		trackInfoParams.buffer = &TocEntry[i];

		if (ioctl(drive, DKIOCCDREADTRACKINFO, &trackInfoParams) < 0) {
			fprintf(stderr, "%s: %s: ", argv[0], devicename);
			perror("DKIOCCDREADTRACKINFO");
		}
	}

	/* MacOS X on G5-based systems does not report valid info for
	 * TocEntry[last-1].lastRecordedAddress + 1, so we compute the start
	 * of leadout from the start+length of the last track instead
	 */
	TocEntry[last].cdte_track_address = TocEntry[last-1].trackSize + TocEntry[last-1].trackStartAddress;
#else /* FreeBSD, Linux, Solaris */
	for (i=0; i < last; i++) {
		/* tracks start with 1, but I must start with 0 on OpenBSD */
		TocEntry[i].cdte_track = i + 1;
		TocEntry[i].cdte_format = CDROM_LBA;
		if (ioctl(drive, CDROMREADTOCENTRY, &TocEntry[i]) < 0) {
			fprintf(stderr, "%s: %s: ", argv[0], devicename);
			perror("CDROMREADTOCENTRY");
		}
	}

	TocEntry[last].cdte_track = CDROM_LEADOUT;
	TocEntry[last].cdte_format = CDROM_LBA;
	if (ioctl(drive, CDROMREADTOCENTRY, &TocEntry[i]) < 0) {
		fprintf(stderr, "%s: %s: ", argv[0], devicename);
		perror("CDROMREADTOCENTRY");
	}
#endif

#if defined(__FreeBSD__)
	TocEntry[i].cdte_track_address = ntohl(TocEntry[i].cdte_track_address);
#endif       

	for (i=0; i < last; i++) {
#if defined(__FreeBSD__)
		TocEntry[i].cdte_track_address = ntohl(TocEntry[i].cdte_track_address);
#endif
		cksum += cddb_sum((TocEntry[i].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES);
	}

	totaltime = ((TocEntry[last].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES) -
		    ((TocEntry[0].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES);

	/* print discid */
	if (! musicbrainz)
		printf("%08lx ", (cksum % 0xff) << 24 | totaltime << 8 | last);

	/* print number of tracks */
	printf("%d", last);

	/* print frame offsets of all tracks */
	for (i = 0; i < last; i++) {
		printf(" %d", TocEntry[i].cdte_track_address + CD_MSF_OFFSET);
	}

	if (musicbrainz) {
		printf(" %d\n", TocEntry[last].cdte_track_address + CD_MSF_OFFSET);
	} else {
	  	/* print length of disc in seconds */
	  	printf(" %d\n", (TocEntry[last].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES);
	}

        free(TocEntry);

        return 0;
}
Пример #13
0
int main(int argc, char *argv[])
{
	int len;
	int i, totaltime;
	long int cksum = 0;
	int musicbrainz = 0;
	unsigned char last = 1;
	char *devicename = DEVICE_NAME;
	struct cdrom_tocentry *TocEntry;
#ifndef __sgi
	int drive;
	struct cdrom_tochdr hdr;
#else
	CDPLAYER *drive;
	CDTRACKINFO info;
	cdrom_tochdr hdr;
#endif
	char *command = argv[0];

#if defined(__OpenBSD__) || defined(__NetBSD__)
	struct ioc_read_toc_entry t;
#elif defined(__APPLE__)
	dk_cd_read_disc_info_t discInfoParams;
#endif

	if (argc == 2 && !strcmp(argv[1], "--help")) {
		usage();
		exit(EXIT_SUCCESS);
	}
	if (argc == 2 && !strcmp(argv[1], "--version")) {
		fprintf(stderr, "cd-discid %s.\n", VERSION);
		exit(EXIT_SUCCESS);
	}
	if (argc >= 2 && !strcmp(argv[1], "--musicbrainz")) {
		musicbrainz = 1;
		argc--;
		argv++;
	}
	if (argc == 2)
		devicename = argv[1];
	else if (argc > 2) {
		usage();
		exit(EXIT_FAILURE);
	}

#if defined(__sgi)
	drive = CDopen(devicename, "r");
	if (drive == 0) {
#else
	drive = open(devicename, O_RDONLY | O_NONBLOCK);
	if (drive < 0) {
#endif
		fprintf(stderr, "%s: %s: ", command, devicename);
		perror("open");
		exit(EXIT_FAILURE);
	}

#if defined(__APPLE__)
	memset(&discInfoParams, 0, sizeof(discInfoParams));
	discInfoParams.buffer = &hdr;
	discInfoParams.bufferLength = sizeof(hdr);
	if (ioctl(drive, DKIOCCDREADDISCINFO, &discInfoParams) < 0
	    || discInfoParams.bufferLength != sizeof(hdr)) {
		fprintf(stderr, "%s: %s: ", command, devicename);
		perror("DKIOCCDREADDISCINFO");
		exit(EXIT_FAILURE);
	}
#elif defined(__sgi)
	if (CDgetstatus(drive, &hdr) == 0) {
		perror("CDROMREADTOCHDR");
		exit(EXIT_FAILURE);
	}
#else
	if (ioctl(drive, CDROMREADTOCHDR, &hdr) < 0) {
		fprintf(stderr, "%s: %s: ", command, devicename);
		perror("CDROMREADTOCHDR");
		exit(EXIT_FAILURE);
	}
#endif

	last = hdr.cdth_trk1;

	len = (last + 1) * sizeof(struct cdrom_tocentry);

	TocEntry = malloc(len);
	if (!TocEntry) {
		fprintf(stderr,
			"%s: %s: Can't allocate memory for TOC entries\n",
			command, devicename);
		exit(EXIT_FAILURE);
	}

#if defined(__OpenBSD__)
	t.starting_track = 0;
#elif defined(__NetBSD__)
	t.starting_track = 1;
#endif

#if defined(__OpenBSD__) || defined(__NetBSD__)
	t.address_format = CDROM_LBA;
	t.data_len = len;
	t.data = TocEntry;
	memset(TocEntry, 0, len);

	if (ioctl(drive, CDIOREADTOCENTRYS, (char*)&t) < 0) {
		fprintf(stderr, "%s: %s: ", command, devicename);
		perror("CDIOREADTOCENTRYS");
	}
#elif defined(__APPLE__)
	dk_cd_read_track_info_t trackInfoParams;
	memset(&trackInfoParams, 0, sizeof(trackInfoParams));
	trackInfoParams.addressType = kCDTrackInfoAddressTypeTrackNumber;
	trackInfoParams.bufferLength = sizeof(*TocEntry);

	for (i = 0; i < last; i++) {
		trackInfoParams.address = i + 1;
		trackInfoParams.buffer = &TocEntry[i];

		if (ioctl(drive, DKIOCCDREADTRACKINFO, &trackInfoParams) < 0) {
			fprintf(stderr, "%s: %s: ", command, devicename);
			perror("DKIOCCDREADTRACKINFO");
		}
	}

	/* MacOS X on G5-based systems does not report valid info for
	 * TocEntry[last-1].lastRecordedAddress + 1, so we compute the start
	 * of leadout from the start+length of the last track instead
	 */
	TocEntry[last].cdte_track_address = htonl(ntohl(TocEntry[last-1].trackSize) + ntohl(TocEntry[last-1].trackStartAddress));
#elif defined(__sgi)
	for (i = 0; i < last; i++) {
		if (CDgettrackinfo(drive, i + 1, &info) == 0) {
			fprintf(stderr, "CDgettrackinfo failed on track %i: %s\n", i + 1, devicename);
		}
		TocEntry[i].cdte_track_address = info.start_min*60*CD_FRAMES + info.start_sec*CD_FRAMES + info.start_frame;
	}
	TocEntry[last].cdte_track_address = TocEntry[last - 1].cdte_track_address + info.total_min*60*CD_FRAMES + info.total_sec*CD_FRAMES + info.total_frame;
#else   /* FreeBSD, Linux, Solaris */
	for (i = 0; i < last; i++) {
		/* tracks start with 1, but I must start with 0 on OpenBSD */
		TocEntry[i].cdte_track = i + 1;
		TocEntry[i].cdte_format = CDROM_LBA;
		if (ioctl(drive, CDROMREADTOCENTRY, &TocEntry[i]) < 0) {
			fprintf(stderr, "%s: %s: ", command, devicename);
			perror("CDROMREADTOCENTRY");
		}
	}

	TocEntry[last].cdte_track = CDROM_LEADOUT;
	TocEntry[last].cdte_format = CDROM_LBA;
	if (ioctl(drive, CDROMREADTOCENTRY, &TocEntry[i]) < 0) {
		fprintf(stderr, "%s: %s: ", command, devicename);
		perror("CDROMREADTOCENTRY");
	}
#endif

	/* release file handle */
	close(drive);

#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
	TocEntry[i].cdte_track_address = ntohl(TocEntry[i].cdte_track_address);
#endif

	for (i = 0; i < last; i++) {
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
		TocEntry[i].cdte_track_address = ntohl(TocEntry[i].cdte_track_address);
#endif
		cksum += cddb_sum((TocEntry[i].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES);
	}

	totaltime = ((TocEntry[last].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES) -
		((TocEntry[0].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES);

	/* print discid */
	if (!musicbrainz)
		printf("%08lx ", (cksum % 0xff) << 24 | totaltime << 8 | last);

	/* print number of tracks */
	printf("%d", last);

	/* print frame offsets of all tracks */
	for (i = 0; i < last; i++)
		printf(" %d", TocEntry[i].cdte_track_address + CD_MSF_OFFSET);

	if (musicbrainz)
		printf(" %d\n", TocEntry[last].cdte_track_address + CD_MSF_OFFSET);
	else
		/* print length of disc in seconds */
		printf(" %d\n", (TocEntry[last].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES);

	free(TocEntry);

	return 0;
}
Пример #14
0
static int
quh_cddb_in_open (st_quh_nfo_t * file)
{
  int x = 0;
  char buf[MAXBUFSIZE];
  int t = 0, n = 0;
  char buf2[MAXBUFSIZE];
  char *p = NULL;
  st_http_header_t http_header;
  char http_header_s[NET_MAXHTTPHEADERSIZE];

  if (!inited)
    { 
      if (!quh_get_object_s (quh.filter_chain, QUH_OPTION))
        quh_set_object_s (quh.filter_chain, QUH_OPTION, "http://freedb.freedb.org/~cddb/cddb.cgi");

#ifdef  USE_TCP
      net = net_init (NET_TCP|NET_CLIENT, 5);
#endif
      inited = 1; 
    }

  *buf = 0;
  if (!file->indices)
    {
      strcpy (buf, "Failed: Input has no indices");

      quh_set_object_s (quh.filter_chain, QUH_OUTPUT, buf);
  
      return 0;
    }

  for (x = 0; x < file->indices; x++)
    {
      // add to cddb_sum
      n += cddb_sum (file->index_pos[x] / file->channels / file->size / file->rate);

      if (x == 0)
        t = (file->raw_size / file->channels / file->size / file->rate) - 
            (file->index_pos[x] / file->channels / file->size / file->rate) -
            ((file->index_pos[x] / file->channels / file->size / file->rate) % 60); 
    }

  cddb_id = (n % 0xff) << 24 | t << 8 | file->indices;

#ifdef  USE_TCP
  net_open (net, cddb_host, 80);

  sprintf (buf, "%s%s?cmd=cddb+query+%08lx+%d+",
    cddb_host,
    cddb_uri,
    cddb_id,
    file->indices);
  
  for (x = 0; x < file->indices; x++)
    sprintf (strchr (buf, 0), "%ld+", (file->index_pos[x] / 2352) + 150);

  sprintf (strchr (buf, 0), "%ld&hello=anonymous+localhost+%s+%s&proto=6",
    ((file->raw_size / 2352) + 150) / 75,
    "Quh",
    QUH_VERSION_S);

  net_build_http_request (http_header_s, buf, "Quh", 0, NET_METHOD_GET, 0);

  net_write (net, http_header_s, strlen (http_header_s));

  net_parse_http_response (&http_header, net);

  // before: classical 9b10f50b Wayne Marshall / Symphonie
  // after: classical+9b10f50b
  while (net_gets (net, buf, MAXBUFSIZE))
    {
      // 200 classical 9e10cb0b Wayne Marshall / Organ Transcriptions
      if (!strncmp (buf, "200 ", 4))
        {
          strtrim_s (buf, "200 ", NULL);
          p = strchr (buf, ' ');

          if (p)
            *p = '+';

          p = strchr (buf, ' ');

          if (p)
            *p = 0;

          strncpy (buf2, buf, MAXBUFSIZE)[MAXBUFSIZE - 1] = 0;

          break;
        }

      // 211 Found inexact matches, list follows (until terminating .')
      // classical 9b10f50b Wayne Marshall / Symphonie
      // .
      if (!strncmp (buf, "211 ", 4))
        if (net_gets (net, buf, MAXBUFSIZE))
          {
            p = strchr (buf, ' ');

            if (p)
              *p = '+';

            p = strchr (buf, ' ');

            if (p)
              *p = 0;

            strncpy (buf2, buf, MAXBUFSIZE)[MAXBUFSIZE - 1] = 0;

            break;
          }
    }

  // we don't use the http keep alive flag
  net_close (net);
  net_open (net, cddb_host, 80);

  sprintf (buf, "%s%s?cmd=cddb+read+%s&hello=anonymous+localhost+%s+%s&proto=6",
    cddb_host,
    cddb_uri,
    buf2,
    "Quh",
    QUH_VERSION_S);

  p = net_build_http_request (buf, "Quh", 0, NET_METHOD_GET, 0);
  
  net_write (net, p, strlen (p));
  
  net_parse_http_response (net);

  x = 0;
  while (net_gets (net, buf, MAXBUFSIZE))
    if (!strncmp (buf, "TTITLE", 6))
      {
        sprintf (buf2, "TTITLE%d", x);
        p = (char *) get_property_from_string (buf, buf2, '=', '#');
        if (p)
          strncpy (file->index_name[x], p, QUH_INDEX_NAME_LEN)[QUH_INDEX_NAME_LEN - 1] = 0;
        else
          *(file->index_name[x]) = 0;

#ifdef  DEBUG
        printf ("%s\n\n", file->index_name[x]);
#endif

        x++;

        if (x == file->indices)
          break;
      }

  net_close (net);  
#endif  // USE_TCP

  *buf = 0;
  sprintf (strchr (buf, 0), "DiscId: 0x%08lx\n", cddb_id);

  if (file->indices)
    for (x = 1 ; x < file->indices + 1; x++)
      {
        unsigned long len = (x < file->indices ? file->index_pos[x] : file->raw_size) - file->index_pos[x - 1];

        sprintf (strchr (buf, 0), "%0*d:", misc_digits (QUH_MAXINDEX), x);

        sprintf (strchr (buf, 0), " %s", file->index_name[x - 1]);

        sprintf (strchr (buf, 0), "%s",
          quh_bytes_to_units (file, len, QUH_UNITS_CLOCK));
        
        if (x < file->indices)
          strcat (buf, "\n");
      }

  quh_set_object_s (quh.filter_chain, QUH_OUTPUT, buf);

  return 0;
}