Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9548530
  • 博文数量: 1227
  • 博客积分: 10026
  • 博客等级: 上将
  • 技术积分: 20273
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-16 12:40
文章分类

全部博文(1227)

文章存档

2010年(1)

2008年(1226)

我的朋友

分类: C/C++

2008-04-23 21:45:47

C 实现CD抓轨转WAV


作者:




  现在介绍一下C 实现CD抓轨转WAV,CD抓轨的方法有好几种,现在介绍其中一种。我们可以通过API函数CreateFile获得设备句柄,再用API函数DeviceIoControl来实现对设备的访问获取信息。再此还会用到WAVE文件结构WAVEFORMATEX,再把读到的信息写到文件里生成WAVE格式的文件。

我们要用到的头文件有: ntddcdrm.h(NTDDK开发包) winioctl.h Mmreg.h

1、搜索光驱
我们可以用GetDriveType来判断设备类型,5为CDROM类型。返回类型可以参看MSDN,里面有详细介绍。

2、打开设备
用CreateFile获得设备句柄,例子如下:

    HANDLE m_hDevice;

    CString FileName=”F:”;

    m_hDevice =CreateFile("\\\\.\\" FileName,                // 文件名路径

    GENERIC_READ,                                            // 读写方式

    FILE_SHARE_READ | FILE_SHARE_WRITE,                      // 共享方式

    NULL,                                                    // 默认的安全描述符

    OPEN_EXISTING,                                           // 创建方式

    0,                                                       // 不需设置文件属性

    NULL);                                                   // 不需参照模板文件

3、读取CD参数
得到了设备句柄,我们就可以用DeviceIoControl来获息相关信息.
DeviceIoControl函数原型:
    BOOL DeviceIoControl(

    HANDLE hDevice,                                 // 设备句柄

    DWORD dwIoControlCode,                          // 控制码

    LPVOID lpInBuffer,                              // 输入数据缓冲区指针

    DWORD nInBufferSize,                           // 输入数据缓冲区长度

    LPVOID lpOutBuffer,                             // 输出数据缓冲区指针

    DWORD nOutBufferSize,                          // 输出数据缓冲区长度

    LPDWORD lpBytesReturned,                        // 输出数据实际长度单元长度

    LPOVERLAPPED lpOverlapped                      // 重叠操作结构指针

    );


4、获取曲目
使用IOCTL_CDROM_READ_TOC控制码输出CDROM_TOC结构

  BOOL bResult;

  DWORD dwOutBytes;

  CDROM_TOC CdromTOC;               //曲目信息结构,详细请看MSDN

  bResult=DeviceIoControl(m_hDevice,

  			IOCTL_CDROM_READ_TOC,NULL,0,

  			&CdromTOC,

  			sizeof(CdromTOC),

  			&dwOutBytes,  

  			(LPOVERLAPPED)NULL);

5、获取曲目始点
DWORD CCdToWavDlg::GetStartSector(int track)

{

         return (CdromTOC.TrackData[track-1].Address[1]*60*75       

         		CdromTOC.TrackData[track-1].Address[2]*75  

         		CdromTOC.TrackData[track-1].Address[3])-150;

}

6、获取曲目终点
DWORD CCdToWavDlg::GetEndSector(int track)

{

      return (CdromTOC.TrackData[track].Address[1]*60*75 	  

      			CdromTOC.TrackData[track].Address[2]*75   

      			CdromTOC.TrackData[track].Address[3])-151;

}

7、读取曲目信息
使用IOCTL_CDROM_RAW_READ输入RAW_READ_INFO结构信息,输出来获取区域内容
BOOL CCdToWavDlg::ReadSector(int sector,BYTE Buffer[], int NumSectors) 

{

	DWORD dwOutBytes;

	RAW_READ_INFO rri; //结构详细请看MSDN

	rri.TrackMode =(TRACK_MODE_TYPE)2;

	rri.SectorCount = (DWORD)NumSectors;

	rri.DiskOffset =(DWORD64)(sector*CB_CDROMSECTOR);

	if (DeviceIoControl(m_hDevice,IOCTL_CDROM_RAW_READ,

		&rri, 

		sizeof(rri),

		Buffer, 

		(DWORD)NumSectors*CB_AUDIO,&dwOutBytes,

		(LPOVERLAPPED)NULL)) return true; 

	return false;

}

8、 文件生成
  WAVE文件是非常简单的一种RIFF文件,它的格式类型为"WAVE"。RIFF块包含两个子块,这两个子块的ID分别是"fmt"和"data",其中"fmt"子块由结构WAVEFORMATEX所组成,其子块的大小就是sizeofof(WAVEFORMATEX),数据组成就是WAVEFORMATEX结构中的数据。WAVE文件的结构如下图所示:

标志符(RIFF)

阅读(348) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~