如何在C ++中的Windows 7上阅读CD文本 [英] how to read cd text on windows 7 in c++
本文介绍了如何在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 [ ^ ]是由许多可怕的IOCTL调用生成的
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屋!
查看全文