如何在Python中计算波形声音文件的逆?
我正在尝试使用 Python 计算 16 位单声道波形文件(8000Hz)的逆,而不使用几乎任何外部模块,除了用于从波形文件读取样本的 wave
之外。我尝试读取所有 16 位样本并计算每个样本的 0xFFFF - 样本并将其写入另一个波形文件。但是当我将两个音频文件混合在一起时,它们不会彼此静音。我在互联网上读过一些关于 DFT、FFT 等的内容,但即使我有很强的高中数学背景,但我对它们的理解并不多。任何提示表示赞赏。我的代码:
import wave
from dataclasses import dataclass
from typing import List
@dataclass
class SoundClip16b:
data: List["int"]
def __len__(self):
return len(self.data)
def inverted(self):
inv = list()
for d in self.data:
inv.append(0xFFFF - d)
return SoundClip16b(data=inv)
def to_bytes(self):
databyte = b""
for i in self.data:
b1 = i >> 8
b2 = i & 0xFF
databyte += bytes([b1, b2])
return databyte
@staticmethod
def from_bytes(bytedata):
data = list()
for index, byte in enumerate(bytedata[:-1:2]):
next_byte = bytedata[index+1]
data.append((byte << 8) + next_byte)
return SoundClip16b(data=data)
w_noise = wave.open("noise.wav")
w_antinoise = wave.open("antinoise.wav", "w")
clip = SoundClip16b.from_bytes(w_noise.readframes(-1))
inverted_clip = clip.inverted()
w_antinoise.setnchannels(1)
w_antinoise.setsampwidth(2)
w_antinoise.setframerate(8000)
w_antinoise.writeframes(inverted_clip.to_bytes())
w_antinoise.close()
编辑:我也尝试过假设 16 位样本是有符号整数而不是无符号整数。
I am trying to compute inverse of a 16 bit mono wave file(8000Hz) using Python without using almost any external module except wave
which is used to read samples from the wave file. I've tried reading all the 16 bit samples and computing 0xFFFF - sample
for each sample and writing that to another wave file. But when I mix the two audio files together, they don't silence each other. I've read some stuff on the internet about DFT, FFT and such these but I don't understand much from them even through I've got a strong mathematics background from highschool. Any hint is appreciated. My code:
import wave
from dataclasses import dataclass
from typing import List
@dataclass
class SoundClip16b:
data: List["int"]
def __len__(self):
return len(self.data)
def inverted(self):
inv = list()
for d in self.data:
inv.append(0xFFFF - d)
return SoundClip16b(data=inv)
def to_bytes(self):
databyte = b""
for i in self.data:
b1 = i >> 8
b2 = i & 0xFF
databyte += bytes([b1, b2])
return databyte
@staticmethod
def from_bytes(bytedata):
data = list()
for index, byte in enumerate(bytedata[:-1:2]):
next_byte = bytedata[index+1]
data.append((byte << 8) + next_byte)
return SoundClip16b(data=data)
w_noise = wave.open("noise.wav")
w_antinoise = wave.open("antinoise.wav", "w")
clip = SoundClip16b.from_bytes(w_noise.readframes(-1))
inverted_clip = clip.inverted()
w_antinoise.setnchannels(1)
w_antinoise.setsampwidth(2)
w_antinoise.setframerate(8000)
w_antinoise.writeframes(inverted_clip.to_bytes())
w_antinoise.close()
Edit: I also have tried by assuming that the 16 bit samples are signed integers rather than unsigned ones.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
感谢 Jan,问题出在字节顺序上。波是小端字节序,而我的代码假设它是大端字节序。这段代码对我有用:
Thanks to Jan, the problem was with endianess. The wave was little endian while my code was assuming it was big endian. This code worked for me right: