【直接上代码】
******
def add_watermark(self, audio, message):
if self.watermark_model is None:
return audio
device = self.device
bits = utils.string_to_bits(message).reshape(-1)
n_repeat = len(bits) // 32
K = 16000
coeff = 2
for n in range(n_repeat):
trunck = audio[(coeff * n) * K: (coeff * n + 1) * K]
if len(trunck) != K:
print('Audio too short, fail to add watermark')
break
message_npy = bits[n * 32: (n + 1) * 32]
with torch.no_grad():
signal = torch.FloatTensor(trunck).to(device)[None]
message_tensor = torch.FloatTensor(message_npy).to(device)[None]
signal_wmd_tensor = self.watermark_model.encode(signal, message_tensor)
signal_wmd_npy = signal_wmd_tensor.detach().cpu().squeeze()
audio[(coeff * n) * K: (coeff * n + 1) * K] = signal_wmd_npy
return audio
这段代码使用预训练的水印模型向音频中添加水印。水印是一段隐藏的信息,可以嵌入到音频中,而不影响音频的可听性。
原理:
- **比特转换:**将水印信息(文本消息)转换为比特流。
- **分段:**将比特流划分为 32 位长的块。
- **嵌入:**对于每个 32 位块:
- 将音频信号的指定部分(长度为 16000 个采样点)转换为张量。
- 将水印比特块转换为张量。
- 使用预训练的水印模型将水印比特块嵌入到音频信号张量中。
- 将嵌入水印的音频信号张量转换回 NumPy 数组。
- 将嵌入水印的音频片段替换到原始音频中。
- **重复:**重复以上过程,直到嵌入所有水印比特块。
预训练水印模型的作用:
预训练的水印模型是一个神经网络,它可以学习如何将水印比特块嵌入到音频信号中,同时最大程度地减少对音频质量的影响。该模型通过在大量音频数据上进行训练来学习这种映射。嵌入后,水印信息隐藏在音频信号中,并且可以稍后通过使用相同的预训练模型提取。