录音/制作/创作 吉他 扩声技术 视频技术 作品展示 生活 信息 更多... | 音频应用专卖店

求助:有什么好的抓轨的开源软件?

( 14 )
 
[收藏]

9
#1 05-11-29 15:59

求助:有什么好的抓轨的开源软件?

现在想找个开源的软件,功能如下:
1.实现cd的抓轨
2.生成mp2、mp3、wav格式的文件

请诸位不吝赐教,先行谢了!

751
#2 05-11-29 22:16
www.sourceforge.net看看。

1412
#3 05-11-29 23:01
EAC095pb3  这个软件抓音轨,音质基本无损。

2520
#4 05-11-30 03:02
不知道milanjason说的“开源软件”指的是"free software"还是“OSS”? 如果是"free software"的话有那是很多的,如果是“OSS”的话倒可以试看看下面这个:

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)

数据大小

格式类型("WAVE")

"fmt"

Sizeof(WAVEFORMATEX)

WAVEFORMATEX

"data"

声音数据大小

声音数据


WAVEFORMATEX结构原型:


  typedef struct
  {
       WORD wFormatTag; //编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等
       WORD nChannels; //声道数,单声道为1,双声道为2
       DWORD nSamplesPerSec; //采样频率
       DWORD nAvgBytesPerSec; //每秒的数据量
       WORD nBlockAlign; //块对齐
       WORD wBitsPerSample; //WAVE文件的采样大小
       WORD cbSize;
   } WAVEFORMATEX; *PWAVEFORMATEX;

9、定义WAVE文件结构
    DWORD m_WaveHeaderSize = 38;
    DWORD m_WaveFormatSize = 18;
    DWORD m_AudioDataSize =0;
    DWORD m_WrittenBytes = 0;
    WAVEFORMATEX m_WaveFormatEx;
    m_WaveFormatEx.wFormatTag=WAVE_FORMAT_PCM ;
    m_WaveFormatEx.nSamplesPerSec=48000;
    m_WaveFormatEx.wBitsPerSample=16;
    m_WaveFormatEx.nChannels=2;
    m_WaveFormatEx.cbSize=0;
    m_WaveFormatEx.nBlockAlign=m_WaveFormatEx.nChannels*(m_WaveFormatEx.wBitsPerSample/8);
    m_WaveFormatEx.nAvgBytesPerSec=m_WaveFormatEx.nSamplesPerSec*m_WaveFormatEx.nBlockAlign;

10、创建新文件

    CFile m_file;
    CFileException fileException;
    CString m_csFileName= m_SavePath;
    m_file.Open(m_csFileName,CFile::modeCreate|CFile::modeReadWrite, &fileException);
    int StartSect=GetStartSector(m_List.GetCurSel()+1);
    int EndSect=GetEndSector(m_List.GetCurSel()+1);
    DWORD Bytes2Read=(EndSect - StartSect)*CB_AUDIO;
    m_AudioDataSize=Bytes2Read;
    BYTE Data[CB_AUDIO*NSECTORS];

11、写入WAV文件头
WAV文件头一定要按顺序写入

  m_file.SeekToBegin();
  m_file.Write("RIFF",4);
  unsigned int Sec=(m_AudioDataSize + m_WaveHeaderSize);
  m_file.Write(&Sec,sizeof(Sec));
  m_file.Write("WAVE",4);
  m_file.Write("fmt ",4);
  m_file.Write(&m_WaveFormatSize,sizeof(m_WaveFormatSize));
  m_file.Write(&m_WaveFormatEx.wFormatTag,sizeof(m_WaveFormatEx.wFormatTag));
  m_file.Write(&m_WaveFormatEx.nChannels,sizeof(m_WaveFormatEx.nChannels));
  m_file.Write(&m_WaveFormatEx.nSamplesPerSec,sizeof(m_WaveFormatEx.nSamplesPerSec));
  m_file.Write(&m_WaveFormatEx.nAvgBytesPerSec,sizeof(m_WaveFormatEx.nAvgBytesPerSec));
  m_file.Write(&m_WaveFormatEx.nBlockAlign,sizeof(m_WaveFormatEx.nBlockAlign));
  m_file.Write(&m_WaveFormatEx.wBitsPerSample,sizeof(m_WaveFormatEx.wBitsPerSample));
  m_file.Write(&m_WaveFormatEx.cbSize,sizeof(m_WaveFormatEx.cbSize));
  m_file.Write("data",4);
  m_file.Write(&m_AudioDataSize,sizeof(m_AudioDataSize));

12、写入音频数据
把音频数据放到WAV文件头后写入

   DWORD m_seek=46; //文件头长度为46个字,必须从46后写入
   for (int sector = StartSect; (sector < EndSect); sector+=NSECTORS)
   {
         int Sectors2Read = ( (sector + NSECTORS) < EndSect )?NSECTORS:(EndSect-sector);
         if (ReadSector(sector, Data, Sectors2Read))
         {
               m_file.Write(Data,CB_AUDIO*Sectors2Read);
               m_file.Seek(m_seek+=CB_AUDIO*Sectors2Read,CFile::begin);
         }
   }
   m_file.Close();

详细请看源代码。以上在 VC7+Window2000+NTDDK 测试通过。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

163
#5 05-11-30 08:20
我下载了一次

9
#6 05-11-30 14:39
原帖由 高山云雾 于 2005-11-29 23:01 发表
EAC095pb3  这个软件抓音轨,音质基本无损。


谢谢回复,不过EAC只是个共享的软件啊,不是开源软件,是否?

9
#7 05-11-30 17:26
原帖由 毕西芈 于 2005-11-30 03:02 发表
不知道milanjason说的“开源软件”指的是"free software"还是“OSS”? 如果是"free software"的话有那是很多的,如果是“OSS”的话倒可以试看看下面这个:

C++实现CD抓轨转WAV[ ...


谢谢,还有个问题请教:
1.从cd抓轨生成mp2、mp3
2.先从cd抓轨生成wav然后用wav转换为mp2、mp3
以上两种方法那种生成的mp2、mp3的音质好呢?

2520
#8 05-11-30 17:53
第2种方式好一些,就是费时间

9
#9 05-12-2 09:41
原帖由 毕西芈 于 2005-11-30 17:53 发表
第2种方式好一些,就是费时间



能否具体解释一下?cd抓轨到wav没有音质的损失吗?

2520
#10 05-12-2 14:42
音频文件除了用“复制”, “粘贴”或数字录音以外的各种方法的转换都有音质损失..
既然要的是MP3, 那就不要介意是CD转的还是WAV转的...也许用真力音箱能听出个中的区别, 但又有谁会用真力去扣MP3的音质呢...
MP3就是MP3, 即便打扮得再华丽也摆脱不了它的贫苦出身...
它就像压缩饼干, 在公车上, 地铁中, 办公室里...被我们咀嚼着, 已经顾不得口感和健康那么多了, 先填了肚子再说...

9
#11 05-12-5 17:36
原帖由 毕西芈 于 2005-12-2 14:42 发表
音频文件除了用“复制”, “粘贴”或数字录音以外的各种方法的转换都有音质损失..
既然要的是MP3, 那就不要介意是CD转的还是WAV转的...也许用真力音箱能听出个中的区别, 但又有谁会用真力去扣MP3的音质呢...
MP ...


现在在做一个音频系统,其中的一个模块是转储子系统。整个系统采用B/S结构,统一的登录界面。
转储子系统的功能:
1.从CD上抓轨生成mp2、mp3,同时取得CD的各个节目的信息,如:歌手、专辑、歌名等
2.对生成的mp2、mp3要考虑爆音的问题
3.想利用开源的抓轨软件,前端用JS或JAVA来调用
4.抓轨软件需要能调解速度
对于以上需求,老大给些建议,谢谢。

1
#12 10-1-15 14:46

1
#13 11-9-18 17:08
找这个好久了。呵呵。

1
#14 13-7-31 12:10
正找这个呢,想改进一下抓轨方法

4697
#15 13-8-1 09:41
年年都有挖坟的,Foobar2000就OK了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

搜索