如何让语音延迟消失?

How do I make the voice delay disappear?

我试图做一些类似于 VoIP 的事情,我在其中录制语音并使用 UDP 将其发送到网络上的另一个程序,这不是关于加密的问题,但是当我 运行 代码工作时,除了音频断断续续的事实。

换句话说,在我掉落的一些词中我可以完整地听到它们,但其他更长的短语总能识别信号中断的时刻,他等待另一个数据包被传递以继续 t运行击打。

请问如何让接收方的声音听起来柔和?因为我尝试使用 Threading 来尝试优化录音,但效果不大,我不知道还能去哪里。

服务器端:

import sounddevice as sd
import socket, pickle

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

h = socket.gethostbyname(socket.gethostname())

s.bind((h,9001))

print("Servidor Rodando em "+str(h)+":9001")

while True:
    r = pickle.loads(s.recvfrom(102400)[0])
    sd.play(r,4410)

客户端:

import sounddevice as sd
import socket, pickle, threading

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

ip = input("IP >> ")

data = None

def Enviar():
    global data
    s.sendto(pickle.dumps(data),(ip,9001))

while True:
    data = sd.rec(4410, samplerate=4410, channels=2)
    sd.wait()
    threading.Thread(target=Enviar, args=()).start()

对于计算机音频,接收计算机的声卡有一个采样时钟,用于确定它将音频采样值转换为驱动扬声器的电信号的速度。采样时钟以固定速率运行(例如每秒 48000 次采样,或您设置的任何值)并且为了使音频听起来正确,必须每 1/48000 次将新的音频采样送入声卡一秒钟。

为了减轻CPU主机的负载,声卡通常有一个内置的音频缓冲区,而不是强制CPU每1/ 48000 秒只发送一个样本,您可以改为让 CPU 唤醒,例如每 100mS 一次,一次写入 4800 个样本。然后,声卡的内部电子设备将改为管理从该缓冲区馈送各个样本。

因此,声卡连续播放的秘诀就是永远不要让声卡的缓冲区变空。当缓冲区被清空(因此声卡无法在需要播放的瞬间播放下一个样本)时,这被称为 音频欠载 并且它如您所闻,导致音频出现故障。

防止数据不足的最简单方法是在接收计算机上缓冲更多音频,以便在发生数据不足之前有更多的时间没有接收到数据。当然,这样做的缺点是发送方发送数据和接收方播放数据之间会有更多的延迟;这可能没问题,例如流式传输录制的音乐,但不适合现场语音对话。

更难的方法是确保所有数据在短时间内通过网络;要保证可靠性,您需要 special networking switch that allows devices to pre-reserve bandwidth 以便他们可以保证他们的音频数据包不会被丢弃。没有这种保证,您只能寄希望于最好的结果;在有线以太网连接上,您通常可以通过少量音频通道摆脱它,但通过 WiFi,正如您所见,网络通常非常不可靠,因此在许多情况下您可能会听到欠载故障,除非你调了很多缓冲。

一些协议使用 Forward Error Correction 数学对音频进行编码,即使 UDP 数据包的某些子集丢失,原始音频样本值仍然可以从接收到的剩余数据包中重建.这会稍微增加整体带宽使用量,但只要丢弃的数据包数量相对较少,它就可以避免音频出现故障。不过我不太了解它们的工作原理,所以我不能多说。

最后一种方法(我认为这就是您要问的)是让接收计算机以某种方式尝试通过为丢失的音频制作自己的替换样本值来“掩盖”丢失的音频。有一些语音协议试图做到这一点,并取得了不同程度的成功(你可能在通过坏的 cell-phone 连接交谈时听到了结果),但恕我直言,它并不值得实施,因为仍然会有音频中有明显的故障;只是一个听起来不同的故障。如果您没有更多样本可以跟随它们(至少避免突然的“流行”)然后在新的(post-underrun 之后,将接收到的音频的最后一个样本淡化为零可能是值得的) 接收到音频,也淡化新接收到的音频的第一个样本(以避免第二次“爆破”),但这只会使故障不那么烦人;它没有摆脱它。