在其中创建一个包含隐藏二进制数据的wav并读取它(Java)

时间:2011-06-23 09:00:24

标签: java text audio signal-processing wav

我愿意做的是将文本字符串转换为高频(18500Hz +)的wav文件格式:这将是编码器。 并创建一个引擎来解码来自wav格式化记录的文本字符串,该记录将支持错误控制,因为我不会明显地使用相同的文件来读取,而是录制这种声音。

由于

1 个答案:

答案 0 :(得分:1)

一个重要的考虑因素是你是否要将字符串隐藏到现有音频文件中(因此它听起来像普通文件,但有一个编码信息 - 称为steganography),或者是否你只是创建一个听起来像胡言乱语的文件,仅用于编码数据。我假设后者,因为你没有要求在现有文件中隐藏消息。

所以我假设您没有寻找有关编写WAV文件的低级细节(我相信您可以找到有关如何读取和写入WAV文件的单个样本的文档)。显然,最简单的方法是简单地获取源字符串的每个字节,并将其作为样本存储在WAV文件中(假设是8位记录。如果它是16位记录,则可以存储两个每个样本的字节数。如果是立体声16位记录,则每个样本可以存储4个字节)。然后你可以重新读取WAV文件并以字节形式读回样本。这是一种简单的方法,但正如您所说,您希望能够对声音进行(可能是模拟的)录制,然后将其读回WAV文件,并且仍然能够读取数据。 / p>

通过上述方法,如果模拟录制不完全(以及如何),您将丢失消息的字节。这意味着您需要以这样的方式存储消息:丢失的字节或具有轻微错误的字节不会成为问题。你如何做到这一点将在很大程度上取决于究竟是什么类型的损害"将发生在声音文件中。我希望有两种主要形式的伤​​害:

  • "垂直"损坏:样本(字节)的值略高或低于原来的值。
  • "水平"损坏:样品可以平均,拉伸或水平压扁。从字节的角度来看,这意味着可能会重复某些样本,而其他样本可能会丢失。

要解决此问题,您需要在邮件中添加一些冗余。更多冗余意味着消息将占用更多空间(更长),但会更可靠。

我建议考虑多久(移动前)电话拨号音的工作原理:每个键产生一个独特的音调并通过电线发送。音调足够长,并且在音高方面足够远,即使给出上述形式的损坏也可以区分它们。因此,请选择两个参数:a) length 和b) frequency-delta 。对于每个数据字节,选择一个频率,将256字节值 frequency-delta Hertz分开。然后,为该频率的长度毫秒生成正弦波。这比以上每个采样一个字节的方法编码冗余要多得多,因为每个字节占用了很多样本​​,如果丢失了一些样本,则无关紧要。

当您重读它们时,读取每个长度毫秒的音频数据,然后估算正弦波的频率。将其映射到具有最近频率的字节值。

显然,较长的长度和更远的 frequency-delta 值将使信号更可靠,但需要声音分别更长和更高频率。因此,您必须使用这些值来查看哪些有效。

最后的想法,因为你的标题是"隐藏"二进制数据:

  • 如果您确实希望数据被隐藏",请在将其编码为音频之前考虑对其进行加密。
  • 如果你想采用隐写方法,你将不得不阅读音频隐写术(我想你可以使用上述技术,但你必须将它们作为极低音量信号插入现有声音之上)。