[mb-commits] r9884 - in libdiscid/branches/isrc: . src

root at musicbrainz.org root at musicbrainz.org
Wed Jun 25 13:27:54 UTC 2008


Author: luks
Date: 2008-06-25 13:27:54 +0000 (Wed, 25 Jun 2008)
New Revision: 9884

Modified:
   libdiscid/branches/isrc/CMakeLists.txt
   libdiscid/branches/isrc/src/disc_win32_new.c
Log:
Add Windows-specific ISRC/MCN reading code.

Modified: libdiscid/branches/isrc/CMakeLists.txt
===================================================================
--- libdiscid/branches/isrc/CMakeLists.txt	2008-06-25 12:23:06 UTC (rev 9883)
+++ libdiscid/branches/isrc/CMakeLists.txt	2008-06-25 13:27:54 UTC (rev 9884)
@@ -52,6 +52,9 @@
 ADD_EXECUTABLE(discid examples/discid.c)
 TARGET_LINK_LIBRARIES(discid libdiscid)
 
+ADD_EXECUTABLE(discisrc examples/discisrc.c)
+TARGET_LINK_LIBRARIES(discisrc libdiscid)
+
 ADD_EXECUTABLE(test_discid test/test_discid.c)
 TARGET_LINK_LIBRARIES(test_discid libdiscid)
 

Modified: libdiscid/branches/isrc/src/disc_win32_new.c
===================================================================
--- libdiscid/branches/isrc/src/disc_win32_new.c	2008-06-25 12:23:06 UTC (rev 9883)
+++ libdiscid/branches/isrc/src/disc_win32_new.c	2008-06-25 13:27:54 UTC (rev 9884)
@@ -2,7 +2,7 @@
 
    MusicBrainz -- The Internet music metadatabase
 
-   Copyright (C) 2007 Lukas Lalinsky
+   Copyright (C) 2007-2008 Lukas Lalinsky
    
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -34,36 +34,121 @@
 #define XA_INTERVAL		((60 + 90 + 2) * CD_FRAMES)
 
 #define IOCTL_CDROM_READ_TOC         0x24000
+#define IOCTL_CDROM_READ_Q_CHANNEL   0x2402c
 #define IOCTL_CDROM_GET_LAST_SESSION 0x24038
 
 typedef struct {
-  UCHAR  Reserved;
-  UCHAR  Control : 4;
-  UCHAR  Adr : 4;
-  UCHAR  TrackNumber;
-  UCHAR  Reserved1;
-  UCHAR  Address[4];
+	UCHAR  Reserved;
+	UCHAR  Control : 4;
+	UCHAR  Adr : 4;
+	UCHAR  TrackNumber;
+	UCHAR  Reserved1;
+	UCHAR  Address[4];
 } TRACK_DATA;
 
 typedef struct {
-  UCHAR  Length[2];
-  UCHAR  FirstTrack;
-  UCHAR  LastTrack;
-  TRACK_DATA  TrackData[100];
+	UCHAR  Length[2];
+	UCHAR  FirstTrack;
+	UCHAR  LastTrack;
+	TRACK_DATA  TrackData[100];
 } CDROM_TOC;
 
 typedef struct _CDROM_TOC_SESSION_DATA {
-  UCHAR  Length[2];
-  UCHAR  FirstCompleteSession;
-  UCHAR  LastCompleteSession;
-  TRACK_DATA  TrackData[1];
+	UCHAR  Length[2];
+	UCHAR  FirstCompleteSession;
+	UCHAR  LastCompleteSession;
+	TRACK_DATA  TrackData[1];
 } CDROM_TOC_SESSION_DATA;
 
+#define IOCTL_CDROM_SUB_Q_CHANNEL    0x00
+#define IOCTL_CDROM_CURRENT_POSITION 0x01
+#define IOCTL_CDROM_MEDIA_CATALOG    0x02
+#define IOCTL_CDROM_TRACK_ISRC       0x03
+
+typedef struct _CDROM_SUB_Q_DATA_FORMAT {
+	UCHAR Format;
+	UCHAR Track;
+} CDROM_SUB_Q_DATA_FORMAT;
+
+typedef struct _SUB_Q_HEADER {
+	UCHAR  Reserved;
+	UCHAR  AudioStatus;
+	UCHAR  DataLength[2];
+} SUB_Q_HEADER;
+
+typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER {
+	SUB_Q_HEADER  Header;
+	UCHAR  FormatCode;
+	UCHAR  Reserved[3];
+	UCHAR  Reserved1 : 7;
+	UCHAR  Mcval :1;
+	UCHAR  MediaCatalog[15];
+} SUB_Q_MEDIA_CATALOG_NUMBER;
+
+typedef struct _SUB_Q_TRACK_ISRC {
+	SUB_Q_HEADER  Header;
+	UCHAR  FormatCode;
+	UCHAR  Reserved0;
+	UCHAR  Track;
+	UCHAR  Reserved1;
+	UCHAR  Reserved2 : 7;
+	UCHAR  Tcval : 1;
+	UCHAR  TrackIsrc[15];
+} SUB_Q_TRACK_ISRC;
+
+typedef union _SUB_Q_CHANNEL_DATA {
+	/*SUB_Q_CURRENT_POSITION  CurrentPosition;*/
+	SUB_Q_MEDIA_CATALOG_NUMBER  MediaCatalog;
+	SUB_Q_TRACK_ISRC  TrackIsrc;
+} SUB_Q_CHANNEL_DATA;
+
 int AddressToSectors(UCHAR address[4])
 {
 	return address[1] * 4500 + address[2] * 75 + address[3];
 }
 
+static void read_disc_mcn(HANDLE hDevice, mb_disc_private *disc)
+{
+	DWORD dwReturned;
+	BOOL bResult;
+	CDROM_SUB_Q_DATA_FORMAT format;
+	SUB_Q_CHANNEL_DATA data;
+
+	format.Track = 0;
+	format.Format = IOCTL_CDROM_MEDIA_CATALOG;
+	bResult = DeviceIoControl(hDevice, IOCTL_CDROM_READ_Q_CHANNEL,
+                              &format, sizeof(format),
+                              &data, sizeof(data),
+                              &dwReturned, NULL);
+	if (bResult == FALSE) {
+		fprintf(stderr, "Warning: Unable to read the disc's media catalog number.\n");
+	}
+	else {
+		strncpy(disc->mcn, data.MediaCatalog.MediaCatalog, MCN_STR_LENGTH);
+	}
+}
+
+static void read_disc_isrc(HANDLE hDevice, mb_disc_private *disc, int track)
+{
+	DWORD dwReturned;
+	BOOL bResult;
+	CDROM_SUB_Q_DATA_FORMAT format;
+	SUB_Q_CHANNEL_DATA data;
+
+	format.Track = track;
+	format.Format = IOCTL_CDROM_TRACK_ISRC;
+	bResult = DeviceIoControl(hDevice, IOCTL_CDROM_READ_Q_CHANNEL,
+                              &format, sizeof(format),
+                              &data, sizeof(data),
+                              &dwReturned, NULL);
+	if (bResult == FALSE) {
+		fprintf(stderr, "Warning: Unable to read the international standard recording code (ISRC) for track %i\n", track);
+	}
+	else {
+		strncpy(disc->isrc[track], data.TrackIsrc.TrackIsrc, ISRC_STR_LENGTH);
+	}
+}
+
 int mb_disc_read_unportable_nt(mb_disc_private *disc, const char *device)
 {
 	HANDLE hDevice;
@@ -80,8 +165,6 @@
 		len = colon - device + 1;
 	}
 	strncat(filename, device, len > 120 ? 120 : len);
-	printf("%s\n", device);
-	printf("%s\n", filename);
 
 	hDevice = CreateFile(filename, GENERIC_READ,
 	                     FILE_SHARE_READ | FILE_SHARE_WRITE, 
@@ -114,7 +197,7 @@
 		return 0;
 	}
 
-	CloseHandle(hDevice);
+	read_disc_mcn(hDevice, disc);
 
 	disc->first_track_num = toc.FirstTrack;
 	disc->last_track_num = toc.LastTrack;
@@ -133,8 +216,10 @@
 
 	for (i = disc->first_track_num; i <= disc->last_track_num; i++) {
 		disc->track_offsets[i] = AddressToSectors(toc.TrackData[i - 1].Address);
+		read_disc_isrc(hDevice, disc, i);
 	}
 
+	CloseHandle(hDevice);
 	return 1;
 }
 




More information about the MusicBrainz-commits mailing list