如何在C ++中的Windows 7上阅读CD文本 [英] how to read cd text on windows 7 in c++

查看:156
本文介绍了如何在C ++中的Windows 7上阅读CD文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从CD中提取歌曲信息,以建立我拥有的歌曲数据库.我已经从许多地方收集了代码,可以从我的一些CD中获得歌曲信息,但是在Windows Media中显示专辑封面的那些CD可以与下面显示的代码一起使用.提取歌曲信息是否有其他方法?

I am trying to extract song information from a CD to build a database of songs that I have. I have gleaned code from a variety of places and can get the song infotmation from a few of my CDs but the ones that show an album cover in Windows Media to do work with the code shown below. Is there a different way to extract the song information?

///////////////////////////////////////////////////////////////////////////////
int CAudioCD::GetTrackInfo(HANDLE cdHandl,
						std::vector<struct trackInfoRec *> &trackInfoList)
{
	int status = -1;
	CDROM_READ_TOC_EX cdTocEx;
	WORD size = 0;
	BYTE *cdTextData = NULL;
	DWORD bytesRead;
	int trackNumber = 0;
	std::string discTitle;
	std::string discArtist;
	std::string songWriter;
	std::string composer;
	std::string arranger;
	std::string messages;
	std::string diskId;
	std::string info;
	std::string info2;
	std::string ean;
	std::string closedInfo;
	memset(&cdTocEx, 0, sizeof(cdTocEx));
	cdTocEx.Format = CDROM_READ_TOC_EX_FORMAT_CDTEXT;
	cdTocEx.SessionTrack = 0;
	if (DeviceIoControl(cdHandl, IOCTL_CDROM_READ_TOC_EX, &cdTocEx,
					sizeof(cdTocEx), &size, sizeof(size), &bytesRead, 0) == TRUE)
	{
		// byte swap the size
		size = ((size>>8)|(size<<8)) + sizeof(size);
		// could also set size as
		//     size = 2048; or
		//     size = 2352;
		// to create a really larger buffer to hold anything
		cdTextData = new BYTE[size];
		memset(cdTextData, 0, size);
		CString text;
		if(DeviceIoControl(cdHandl, IOCTL_CDROM_READ_TOC_EX, &cdTocEx,
							sizeof(cdTocEx), cdTextData, size, &bytesRead, 0))
		{
			size = (WORD)(bytesRead - sizeof(CDROM_TOC_CD_TEXT_DATA));
			CDROM_TOC_CD_TEXT_DATA *textData = (CDROM_TOC_CD_TEXT_DATA*)cdTextData;
			CDROM_TOC_CD_TEXT_DATA *dataBlock = textData->Descriptors;
 			CString last;
			while (size >= sizeof(CDROM_TOC_CD_TEXT_DATA_BLOCK))
			{
				const int len = _countof(dataBlock->Text);
				CString text = !dataBlock->Unicode 
					? CString(CStringA((CHAR*)dataBlock->Text, len))
					: CString(CStringW((WCHAR*)dataBlock->WText, len));
	//			int tlen = text.GetLength();  - this was in the original but does not work right
				int tlen = strlen(text.GetString());
				CString tmp = (tlen < 12-1)
					? (!dataBlock->Unicode 
						? CString(CStringA((CHAR*)dataBlock->Text+tlen+1, len-(tlen+1)))
						: CString(CStringW((WCHAR*)dataBlock->WText+tlen+1, len-(tlen+1))))
					: _T("");
				switch(dataBlock->PackType)
				{
					case CDROM_CD_TEXT_PACK_ALBUM_NAME:
						if (last.GetLength() > 0)
						{
							discTitle = last;
						}
						discTitle += text.GetString();
					break;
					case CDROM_CD_TEXT_PACK_PERFORMER:
						discArtist += text;
					break;
					case CDROM_CD_TEXT_PACK_SONGWRITER:
						songWriter += text;
					break;
					case CDROM_CD_TEXT_PACK_COMPOSER:
						composer += text;
					break;
					case CDROM_CD_TEXT_PACK_ARRANGER:
						arranger += text;
					break;
					case CDROM_CD_TEXT_PACK_MESSAGES:
						messages += text;
					break;
					case CDROM_CD_TEXT_PACK_DISC_ID:
						diskId += text;
					break;
					case CDROM_CD_TEXT_PACK_GENRE:
						// still need code to parse genre - it is binary in the text block
					break;
					case CDROM_CD_TEXT_PACK_TOC_INFO:
						info += text;
					break;
					case CDROM_CD_TEXT_PACK_TOC_INFO2:
						info2 += text;
					break;
					case CDROM_CD_TEXT_PACK_UPC_EAN:
						ean += text;
					break;
					case CDROM_CD_TEXT_PACK_SIZE_INFO:
		
					break;
					case CDROM_CD_TEXT_PACK_CLOSED_INFO:
						closedInfo += text;
					break;
					default:
					break;
				}
				last = tmp;
				size -= sizeof(CDROM_TOC_CD_TEXT_DATA_BLOCK);
				dataBlock++;
				if (dataBlock->TrackNumber != trackNumber)
				{
					trackNumber = dataBlock->TrackNumber;
					struct trackInfoRec *trackInfoPtr = new struct trackInfoRec;
					if (trackInfoPtr != NULL)
					{
						trackInfoList.push_back(trackInfoPtr);
						trackInfoPtr->trackNumber = trackNumber;
						trackInfoPtr->discTitle = discTitle;
						trackInfoPtr->discArtist = discArtist;
						trackInfoPtr->songWriter = songWriter;
						trackInfoPtr->composer = composer;
						trackInfoPtr->arranger = arranger;
						trackInfoPtr->messages = messages;
						trackInfoPtr->diskId = diskId;
						trackInfoPtr->info = info;
						trackInfoPtr->info2 = info2;
						trackInfoPtr->ean = ean;
						trackInfoPtr->closedInfo = closedInfo;
					}
					discTitle.erase();
					discArtist.erase();
					songWriter.erase();
					composer.erase();
					arranger.erase();
					messages.erase();
					diskId.erase();
					info.erase();
					info2.erase();
					ean.erase();
					closedInfo.erase();
					status = 0;
				}
			}
		}
	}
	return(status);
}

推荐答案

大多数 CD识别 [ ^ ]应用使用Gracenote或freedb [ ^ ]根据光盘ID [
Most CD Identification[^] apps use Gracenote or freedb[^] to lookup CDs against a Disc ID[^] generated by lots of horrible IOCTL calls


这篇关于如何在C ++中的Windows 7上阅读CD文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆