我正在使用 CloneCD 5.3.3.0 在配备三星 SH-S223L 驱动器的 Windows 10 x64 计算机上备份旧视频游戏。
其中之一是 PC 版《地狱火》(暗黑破坏神 1 扩展包):
- 光盘上有
COMPACT disc DATA STORAGE
徽标 - 序列号:
S0011770
- 工厂 SID 代码:
IFPI 1218
- CD 主控 SID 代码:
IFPI L032
- ISO 9660 PVD创建日期:
1997-11-18 16:30:00.00
我用redump.orgCloneCD 配置文件推荐:
[CloneCD ReadPrefs]
ReadSubData=1
RegenerateData=0
ReadSubAudio=1
AbortOnReadError=0
FastErrorSkip=0
ReadSpeedData=8
ReadSpeedAudio=8
IntelligentBadSectorScan=1
SectorSkip=1
NoErrorReport=0
FirstSessionOnly=0
AudioQuality=3
据我所知,游戏没有保护,但当我转储光盘两次时,我得到了不同的子通道文件(.sub
)。.ccd
和.img
文件是相同的,只有.sub
不同,我使用 SHA1 校验和和十六进制编辑器来验证这一点。
我上传了两个.sub
文件转储这里。
我必须提到,我拥有这张光盘的两份副本,并且两张光盘的行为完全相同。
我还转储了其他几块 CD-ROM 介质,有时候我会遇到这种情况,但有时子通道在转储过程中是一致的。
这种行为该如何解释?
编辑:
我再次使用 Lite-On iH124-14 驱动器转储了同一张 CD-ROM,看到了相同的行为(不同的.sub
文件)。
我还使用 KProbe 2 检查了介质中的错误,得到了以下结果:
编辑:
似乎光盘状况和/或驱动器缺乏精度,加上子通道没有错误控制机制(Q 通道除外)的事实,解释了为什么我.sub
在多次转储同一介质时会得到不同的文件。
我必须提一下,我还买了一个 Plextor PX-712A 驱动器,并设法.sub
通过使用以下方法在转储中获得一致的文件光盘映像创建器。该软件利用0xD8
指令而不是0xBE
指令来读取光盘,从而产生更准确的图像。只有少数驱动器(主要是 Plextor)支持此指令。
此外,我实际上拥有两份我要转储的 CD-ROM 的物理副本(相同的序列号、相同的 IFPI 代码和相同的激光雕刻信息)。如果我使用 Disc Image Creator 多次转储同一张光盘,我会得到一致的.sub
文件,但如果我先转储第一张光盘,然后再转储第二张光盘,我会得到不一致的文件。
我猜这与介质状况有关,因为其中一张光盘有一些划痕和更多的 C1/C2 错误。
答案1
各种 CD 格式有点复杂,官方规范(音频 CD 的“红皮书”,数据 CD 的“黄皮书”)不是免费提供的。但您可以在 Ecma-130 等可用标准中找到一些详细信息。
最初的音频 CD(也称为 CD-DA)以黑胶唱片为模型,这意味着它也使用连续音频数据的螺旋轨道(DVD 后来使用圆形轨道)。 8 个子通道(P 到 W)以非常复杂的方式交织在这些音频数据中,其中 Q 子通道包含时间信息(以分钟/秒/秒的分数为单位)和当前曲目编号。 对于最初的目的来说,这已经足够了:对于连续播放,只需稍微调整镜头以跟随曲目即可。 要进行寻道,镜头会在解码 Q 子通道的同时移动,直到找到正确的曲目。 这种定位有点粗糙,但完全足以听音乐。
时至今日,许多计算机 CD 驱动器仍无法完全准确地定位镜头并同步解码电路,以便从准确的位置开始读取音频样本。这就是为什么许多 CD 翻录程序都具有“偏执”模式,它们会进行重叠读取并比较结果以调整这种“抖动”。作为音频流的一部分,子通道也会受到抖动的影响,这就是为什么当您在无法准确定位的 CD 驱动器上翻录时会得到不同的子通道文件。
当开发数据 CD (CD-ROM) 规范以扩展 CD-DA 规范时,人们认识到准确寻址和读取数据的重要性,因此将 2352 字节的音频帧细分为 12 个同步字节和 4 个标头字节(用于扇区地址),将剩余的 2336 字节用于数据和额外的错误校正级别。使用此方案,可以准确寻址扇区,而不必仅依赖 Q 通道信息。因此抖动效应不适用,转储 CD-ROM 时始终获得相同的数据,并且转储时无需额外的技巧。
编辑更多详细信息:
根据Ecma-130,数据分阶段进行加扰:24 个字节组成一个F1-帧,这些帧中的 106 个字节分布到 106F2-框架,这些帧会获得 8 个额外的错误纠正字节。这些帧又会获得一个额外的字节(“控制字节”),使它们变成F3-框架。额外的字节包含子通道信息(每个位位置一个子通道)。一组 98 个 F3 帧称为部分,98 个相关控制字节包含两个同步字节和 96 字节实际子通道数据。Q 子通道在这 96 位中还包含 16 位 CRC 纠错。
其背后的想法是将数据以这样一种方式分布在磁盘表面,使得划痕、污垢等不会影响大量连续的位,因此只要划痕不是太大,错误校正就可以恢复丢失的数据。
因此,CD 驱动器硬件需要在重新定位镜头后读取完整的部分,以找出它在数据流中的位置。各个阶段的解扰由硬件完成,硬件需要将自身与控制字节流中的 2 个同步字节同步。所有 CD 驱动器型号都需要与其他型号不同的同步时间(如果有的话,您可以通过从两个不同的驱动器读取来测试),具体取决于硬件的实现方式。此外,许多型号并不总是需要完全相同的同步时间,因此它们可以稍早或稍晚开始,并且输出解扰数据并不总是在同一字节。
因此,当翻录程序发出READ CD
(0xBE) 命令时,它会提供传输长度和起始地址(或者更确切地说,Q 通道时间)。驱动器定位镜头、解码帧、提取 Q 通道、比较时间,当找到正确的时间时,它开始传输。此传输并不总是从同一字节开始,如上所述,因此多个READ CD
命令的结果可能会相互偏移。这就是您在翻录器中看到不同子通道文件的原因。
根据硬件和镜头调整时的情况,传输开始的时间是早几个样本还是晚几个样本,这或多或少是随机的。因此,您在结果中看到的唯一模式是偏移是传输长度的倍数。
某些驱动器型号实际上具有精确的硬件,它们将始终同时开始传输。标准在模式页 0x2a(“CD/DVD 功能和机械状态页”)中定义了一个位,用于指示是否是这种情况,但实际经验表明,一些声称精确的驱动器实际上并非如此。(在 Linux 下,您可以使用软件包sg_modes
中的sg3-utiles
工具来读取模式页,我不知道在 Windows 下使用什么工具)。
答案2
根据这篇维基百科文章
一帧包含 33 个字节,其中 24 个字节为音频或用户数据,8 个字节为纠错(CIRC 生成),1 个字节为子码。
这表明子通道没有错误校正。
我还发现其他地方的另一个问题。这是关于音频 CD 的,但我认为它解决了正确的问题:
我只能说,从同一张 CD-DA/CD-TEXT 读取时,我从未获得过两个相同的子通道读数(*.SUB 文件)。在 RAW 模式下读取时这种情况正常吗?因为 CD-DA/CD-TEXT 格式并非在所有子通道中都带有 EDC/ECC,所以数据未得到纠正。
答案在那里:
只有音频数据需要经过 Reed-Solomon 编码 (C1 & C2)。子码通道数据 (通道 P...W) 不经过交错或错误保护。
尽管迪尔克特可能就在对你的问题的另一个回答您可能不需要.sub
文件,答案并没有明确回答您的问题:
这种行为该如何解释?
我的回答是:您获得不同的.sub
文件是因为子通道没有纠错功能。读取错误在读取音频或用户数据时会被纠正(或至少会被检测到),但读取错误在子通道位发生时可以原封不动地通过。由于划痕或灰尘而导致的特定错误可能在一次读取过程中出现,而在另一次读取过程中不会出现,等等——因此.sub
文件会有所不同。
答案扩展以解决评论:
我有两份此磁盘的副本,一份状况良好(没有明显的划痕),但其行为仍然相同。我还有其他状况最差的旧游戏 CD-ROM,但
.sub
多个转储中的文件一致。
我怀疑(但不幸的是没有确凿的证据)不同的 CD 可能以不同的质量制造。在子通道无关紧要的情况下,质量较低的磁盘仍可能通过旨在仅检测数据不一致的质量测试。或者它可能只是概率问题:一个磁盘有其弱点(给出不一致读数的位),错误更正可以修复它;另一个恰好在子通道区域有它。
一个这样的子通道位足以为您提供不同的校验和,而即使用户数据区域中的数千个“未定”位也可以在需要时被悄悄纠正,只要它们分布得足够多,因此纠错算法一次处理的不会太多。
针对 KProbe 2 的结果,答案进行了扩展。
据我所知,C1 错误是允许的(一定数量),因为它们会被悄悄纠正(更多内容)。这种校正之所以有效,是因为有纠错位。正如我之前所说,子通道通常没有这样的冗余(迪尔克特提到了 Q 子通道 CRC 纠错,但这对我的结论没有太大影响)。此外,如果错误发生在那里,除非您事先知道正确的子通道数据是什么,否则没有办法知道它。
因此,您总共知道 1855 个错误。重复测试(认真地做!),您可能会遇到例如 1790 个错误;或 1892 个错误。但每次读取时,更正后的输出都是相同的。
如果每 32 个数据位有一个子通道位,那么我认为您可能有大约 1855/32 个子通道位在读取时未检测到错误。大约 58 位。嗯,差不多,因为多亏了 Q 子通道 CRC,至少可以检测到其中一些错误。由于 Q 是八个子通道之一,我估计您在其他子通道中还剩下大约 50 个错误位。下次读取时,您可能会得到几个没有错误的位,并且在其他地方得到一些新的子通道错误。所以你会得到不同的.sub
文件。但你仍然无法确定这些位中的哪些是第一次或第二次正确读取的。