我收集音乐:购买CD,使用“
精确音频复制”将其数字化,然后扫描封面和插入物。 有时,如果10年前在国外发行限量版CD,这并不容易。 最困难的事情是CD是否存在制造缺陷-并且某些磁道无法读取。
Altneuland的钢琴编曲专辑
帰き ki 城于2005年发行。 三年后(可能是在YouTube上),我找到了它,下载了最佳副本-并将其放在以后的购买清单中。 国际邮件技术的最新进展使得去年可以购买二手磁盘。 不幸的是,我的所有CD驱动器都无法读取磁道号3。在购买旧光盘时,尤其是在通过USPS国际运输中心时,这种情况经常发生。 我把它放在一旁,开始寻找我上个月发现的另一本。 他星期五到达-我立即设法撕裂他。 但是与推送具有
完全相同的错误 。 看来这不是磨损或损坏的问题-光盘可能是从工厂出来的有缺陷的。
另外:经过调查,我不再认为这是工厂的缺陷。 当我将不良曲目的开头或结尾写入空CD-R并将其复制时,开膛手会产生相同的错误! 自己尝试使用
minimal.flac文件。
剩下两个选项:要么有一天尝试寻找将成功复制(不太可能)的另一个副本,要么以某种方式从损坏的磁盘恢复原始声音数据。 您已经知道我选择了哪个选项。
开膛手是如何工作的
EAC无法从光盘[帰べき城]读取第3轨CD可以存储数字数据,但是在光盘,激光器和光学二极管之间有一个完全模拟的接口。 读取错误的原因多种多样:介质脏污,聚碳酸酯保护层刮擦,驱动器本身振动。
CDDA标准中
的原始错误校正代码有助于最大程度地减少很少使用的光盘上的声音失真,但不能完全还原带有大量错误的CD上的位流。 现代裂土器通过两种重要的错误检测方法解决了该问题:冗余读数和AccurateRip。
“
EAC:提取技术”页面介绍了EAC如何产生冗余读数:
在安全模式下,程序将读取每个扇区至少两次。如果发生错误(读取或同步),程序将继续读取该扇区,直到16次尝试中的8次相同。 此过程最多执行一次,三到五次(根据所选的错误恢复质量)。 因此,在最坏的情况下,坏扇区将被读取82次!
一切都很简单。 如果读取请求有时返回不正确的数据,请再次读取它,然后特别注意如果前两次读取给出不同的结果。
AccurateRip使用相同的原理,但是是以分布式的方式:翻录程序将复制的音频文件的校验和发送到此服务。 这个想法是,如果一千个人用相同的位复制曲目,那可能是正确的选择。
本文介绍了两种方法都无法解决时该怎么办。 如果每个读数返回不同的数据,EAC都不会给出结果,并且在AccurateRip数据库中,只有一个关于稀有磁盘的记录
[1] 。
“我通过了一万遍,一万遍去见你”
光驱Asus,LG,Lite-On,Pioneer和未知的OEM如果未复制CD,则使用其他驱动器是合乎逻辑的。 有时,某个特定型号更适合CDDA规范,或者是否有更好的固件来修复错误或其他问题。 DBpoweramp论坛具有
CD / DVD驱动器精度等级,可以选择最合适的翻录驱动器。
星期六早上,我从不同的制造商那里购买了五个新的CD驱动器
[2] ,我尝试了所有这些方法-并找到了一种能够使节奏保持同步的方法。 不幸的是,无法获得rip确认-在所有rip之间,大约有20,000个不同的字节。
但是现在磁盘上有了.wav文件,您可以从中受益。 我认为在错误的轨道上的读取错误接近“正确”的错误。 因此,有意义的是多次撕裂并找到不稳定字节的“共识”值。 这种方法最终是成功的,但是它比我预期的需要做更多的工作。
“数量决定质量”
我从在一个驱动器上重复复制磁盘开始,为每个字节写入所有值,如果一半以上的裂口为此位置生成了特定的字节值,则声明错误“可纠正”。 良好的开端是:不可纠正错误的数量从N = 4时的约6900字节减少到N = 10时的〜5000字节。 随着时间的流逝,每增加一次裂口所带来的好处就会减少,直到大约N = 80时,无法纠正的错误数量稳定在〜3700。 我在N = 100时停止撕裂。
撕裂次数的固定错误和致命错误然后,我尝试在第二个驱动器上将磁盘复制100次,并使用两个校正卡“填充”第一个驱动器中无法校正的错误位置。 但这是行不通的:每个驱动器上都有成千上万个与另一个校正不符的校正! 事实证明,无法通过将噪声与另一个但相关的噪声源组合来消除噪声。
同样的事情,但对于两个交叉验证的光盘手工艺术

EAC网站上还有一个很好的资源:
DAE质量测试 ,它可以通过修复的错误级别来确定驱动器固件的质量。 当驱动器
纠正读取错误而不仅仅是报告错误时,这是较低级别的错误处理。 问题是,只有在禁用此内置纠错码后,EAC的“安全模式”才可用,这表明它无法正常工作。
我通过将.wav文件刻录到CD-R,突出显示数据表面上的确切扇区并用黑色标记小心地进行绘制来准备测试。 这些都是确定性模式下的致命错误保证。
我测试了所有驱动器,并得到两个有趣的结果:

我使用Lite-On驱动器来解决同步错误。 他高兴地咀嚼着魔术标记,但是他对数据表面的直线感到非常困惑。 您会看到如何在右侧而不是三个单独的峰上出现一个巨大的故障Blob。
Errors total Num : 206645159
Errors (Loudness) Num : 965075 - Avg : -21.7 dB(A) - Max : -5.5 dB(A)
Error Muting Num : 154153 - Avg : 99.1 Samples - Max : 3584 Samples
Skips Num : 103 - Avg : 417.3 Samples - Max : 2939 Samples
Total Test Result : 45.3 points (of 100.0 maximum)

先锋驱动器获得了最高的DAE分数。 在我看来,该图表看起来没有什么特别之处,但是分析工具说,这是修复我的小型集中错误的最佳固件。
Errors total Num : 2331952
Errors (Loudness) Num : 147286 - Avg : -77.2 dB(A) - Max : -13.2 dB(A)
Error Muting Num : 8468 - Avg : 1.5 Samples - Max : 273 Samples
Skips Num : 50 - Avg : 6.5 Samples - Max : 30 Samples
Total Test Result : 62.7 points (of 100.0 maximum)
“从某一刻起,数字很重要”
如果EAC忽略“安全模式”,如何使用具有良好错误纠正功能的先锋固件? 非常简单:将EAC切换为“突发模式”,并以固件报告它们的形式将比特流写入磁盘。 然后如何像“安全模式”一样将这堆未经验证的.wav文件转换为高质量的文件? 是的,与我们在Lite-On的翻录中使用的错误分析工具相同!
经过一些EAC配置设置和一百次撕裂之后,我们得到了一张漂亮的图。
撕裂数量的固定和不可纠正的错误(先锋)需要注意的是:
- 致命位错误迅速趋于零,但从未达到。
- 在53-54裂口中修复的bug发生了巨大的跳跃。
- 实际上,在此大跳转之前和之后的错误数量几乎没有变化,这表明所复制数据的稳定性。
0xA595BC09
使用来自Pioneer的几乎完美的错误纠正,我生成了一个“最佳猜测”文件,并开始将其与Pioneer片段进行比较。 不出所料,发现了几个低质量的部分,我通过另外10条撕裂进行了纠正:
$ for RIP_ID in $(seq -w 1 100); do echo -n "rip$RIP_ID: "; cmp -l analysis-out.wav rips-cd1-pioneer/rip${RIP_ID}/*.wav | wc -l ; done | sort -rgk2 | head -n 10
rip054: 2865
rip099: 974
rip007: 533
rip037: 452
rip042: 438
rip035: 404
rip006: 392
rip059: 381
rip043: 327
rip014: 323
我还发现了一些非常有趣的东西:几个撕纸产生
的内容
完全相同 ! 请记住,这恰恰是在“安全模式” EAC中成功的标准。
shncat -q -e | rhash --print="%C"
命令
shncat -q -e | rhash --print="%C"
shncat -q -e | rhash --print="%C"
用于计算原始音频数据的CRC32校验和:这是EAC所使用的。
$ for wav in rips-cd1-pioneer/*/*.wav; do shncat "$wav" -q -e | rhash --printf="%C $wav\n" - ; done | sort -k1
[...]
9DD05FFF rips-cd1-pioneer/rip059/rip.wav
9F8D1B53 rips-cd1-pioneer/rip072/rip.wav
A2EA0283 rips-cd1-pioneer/rip082/rip.wav
A595BC09 rips-cd1-pioneer/rip021/rip.wav
A595BC09 rips-cd1-pioneer/rip022/rip.wav
A595BC09 rips-cd1-pioneer/rip023/rip.wav
A595BC09 rips-cd1-pioneer/rip024/rip.wav
A595BC09 rips-cd1-pioneer/rip025/rip.wav
A595BC09 rips-cd1-pioneer/rip026/rip.wav
A595BC09 rips-cd1-pioneer/rip027/rip.wav
A595BC09 rips-cd1-pioneer/rip028/rip.wav
A595BC09 rips-cd1-pioneer/rip030/rip.wav
A595BC09 rips-cd1-pioneer/rip031/rip.wav
A595BC09 rips-cd1-pioneer/rip040/rip.wav
A595BC09 rips-cd1-pioneer/rip055/rip.wav
A595BC09 rips-cd1-pioneer/rip058/rip.wav
AA3B5929 rips-cd1-pioneer/rip043/rip.wav
ABAAE784 rips-cd1-pioneer/rip033/rip.wav
[...]
同时,低质量部分的重复撕裂使我们能够以零致命错误完成分析。 当我检查此文件时,音频内容与“常规”翻录中的音频内容完全相同! 这足以宣布胜利。
我有99%的把握可以成功复制此有问题的CD,并且0xA595BC09是轨道号3的正确CRC数量。
附录A:compare.rs
我使用此工具来计算可能的字节错误。 它不适合长期使用,因此有点难看,但是对于那些偶然浏览此页面并解决相同问题的用户来说,可能会很有趣。
extern crate memmap; use std::cmp; use std::collections::HashMap; use std::env; use std::fs; use std::sync; use std::sync::mpsc; use std::thread; use memmap::Mmap; const CHUNK_SIZE: usize = 1 << 20; fn suspect_positions( mmaps: &HashMap<String, Mmap>, start_idx: usize, end_idx: usize, ) -> Vec<usize> { let mut positions = Vec::new(); for ii in start_idx..end_idx { let mut first = true; let mut byte: u8 = 0; for (_file_name, file_content) in mmaps { if first { byte = file_content[ii]; first = false; } else if byte != file_content[ii] { positions.push(ii); break; } } } positions } fn main() { let mut args: Vec<String> = env::args().collect(); args.remove(0); let mut first = true; let mut size: usize = 0; let mut files: Vec<fs::File> = Vec::new(); let mut mmaps: HashMap<String, Mmap> = HashMap::new(); for filename in args { let mut file = fs::File::open(&filename).unwrap(); files.push(file); let mmap = unsafe { Mmap::map(files.last().unwrap()).unwrap() }; if first { first = false; size = mmap.len(); } else { assert!(size == mmap.len()); } mmaps.insert(filename, mmap); } let (suspects_tx, suspects_rx) = mpsc::channel(); let mut start_idx = 0; let mmaps_ref = sync::Arc::new(mmaps); loop { let t_start_idx = start_idx; let t_end_idx = cmp::min(start_idx + CHUNK_SIZE, size); if start_idx == t_end_idx { break; } let mmaps_ref = mmaps_ref.clone(); let suspects_tx = suspects_tx.clone(); thread::spawn(move || { let suspects = suspect_positions(mmaps_ref.as_ref(), t_start_idx, t_end_idx); suspects_tx.send(suspects).unwrap(); }); start_idx = t_end_idx; } drop(suspects_tx); let mut suspects: Vec<usize> = Vec::with_capacity(size); for mut suspects_chunk in suspects_rx { suspects.append(&mut suspects_chunk); } suspects.sort(); println!("{{\"files\": ["); let mut first_file = true; for (file_name, file_content) in mmaps_ref.iter() { let file_comma = if first_file { "" } else { "," }; first_file = false; println!("{}{{\"name\": \"{}\", \"suspect_bytes\": [", file_comma, file_name); for (ii, position) in suspects.iter().enumerate() { let comma = if ii == suspects.len() - 1 { "" } else { "," }; println!("[{}, {}]{}", position, file_content[*position], comma); } println!("]}}"); } println!("]}}"); }
1。
在此单个AccurateRip记录中,除磁道号3以外的所有磁道的CRC都与我的光盘匹配:总和为0x84B9DD1A,我的磁盘为0xA595BC09。 我怀疑开膛手不明白他的开车不好。
[返回]2。
在2018年购买CD或DVD驱动器时,显而易见的问题是:“该死,我在哪里可以买到它们?” 我不需要一个,但需要
几个来自
不同品牌的东西 。 我知道附近只有一家商店有5.25英寸DVD驱动器。只有一家商店足够大,不至于后悔放置此类驱动器的货架空间,而且足够奇怪,不会在那儿显得不合时宜。当然,我谈论Frys Electronics。