Python 实时将GSM编解码器音频从网络传输到扬声器

Python 实时将GSM编解码器音频从网络传输到扬声器,python,audio,codec,Python,Audio,Codec,我用python编写了一个VoIP软件,我试图重新创建一个特定的ham无线电节目协议,它使用GSM音频编解码器。 由于python没有简单的方法来播放gsm文件,我至少设法用它转换了一个文件,所以我知道这是可能的 data, samplerate = sf.read('temppi.gsm') sf.write('temppi.wav', data, samplerate) 我使用网络流中的myfile.write(数据3)在硬盘上写入.gsm文件。 然后我使用pysoundfile将其转换为

我用python编写了一个VoIP软件,我试图重新创建一个特定的ham无线电节目协议,它使用GSM音频编解码器。 由于python没有简单的方法来播放gsm文件,我至少设法用它转换了一个文件,所以我知道这是可能的

data, samplerate = sf.read('temppi.gsm')
sf.write('temppi.wav', data, samplerate)
我使用网络流中的myfile.write(数据3)在硬盘上写入.gsm文件。 然后我使用pysoundfile将其转换为wav文件

data, samplerate = sf.read('temppi.gsm')
sf.write('temppi.wav', data, samplerate)
之后我可以用pyaudio播放它。它给了巨大的延迟,需要在飞行中,而不是在音频包进来之后

data, samplerate = sf.read('temppi.gsm')
sf.write('temppi.wav', data, samplerate)
我的问题是,如何使用soundfile直接动态播放流中的文件?我试着在谷歌上搜索所有关于转换文件的东西,没有办法在飞行中直接播放吗?我能做些什么。谢谢,新年快乐:)

data, samplerate = sf.read('temppi.gsm')
sf.write('temppi.wav', data, samplerate)
编辑: 现在我有它的飞行,但这是坏的。。而且它会发出很多的声音

data, samplerate = sf.read('temppi.gsm')
sf.write('temppi.wav', data, samplerate)
here we start thread aaniulos

if ekabitti == b'\x01':
dataaa = self.socket.recv(198)
data3 = io.BytesIO(bytes(dataaa))

    while True:
        global aani
        #global data3
        if aani:
            print ('Ääni saije lopetetaan..')
            break
        data, samplerate = sf.read(io.BytesIO(bytes(data3.getbuffer())), format = 'RAW', channels = 1, samplerate=8000, dtype ='int16', subtype='GSM610', endian ='FILE')
        virtuaalifilu = io.BytesIO()
        sf.write (virtuaalifilu, data, 8000, format='wav', subtype= 'PCM_16')
        sound_file = io.BytesIO(bytes(virtuaalifilu.getbuffer()))
        print ('striimataan ääntä nyt kaijuttimiin!!!')

    stream.stop_stream()  
    stream.close()
    return

由于您省略了很多细节,我只能猜测您的实现是如何工作的。听起来你做得不对。我的猜测是,你经历的巨大延迟是因为你在每个数据包中发送了太多的音频,甚至可能是整个音频文件?要实现低延迟的音频流,您基本上需要遵循以下粗略方案:

data, samplerate = sf.read('temppi.gsm')
sf.write('temppi.wav', data, samplerate)
在发件人处:

data, samplerate = sf.read('temppi.gsm')
sf.write('temppi.wav', data, samplerate)
  • 将音频录制到缓冲区
  • 以预定义长度(例如20毫秒)的块连续切片缓冲区
  • 使用合适的音频编解码器(如GSM)对每个数据块进行编码
  • 最好使用基于数据报的协议(如UDP)将数据包中的每个数据块发送给接收方
  • 在接收器处:

    data, samplerate = sf.read('temppi.gsm')
    sf.write('temppi.wav', data, samplerate)
    
  • 从网络读取可用的数据包
  • 将每个数据包解码为原始音频数据,并将其放入音频缓冲区
  • 从音频缓冲区连续播放音频
  • 如果使用UDP作为传输协议,您还需要处理数据包丢失和无序数据包。根据延迟要求,您可能还可以使用(或至少尝试)TCP发送每个音频块

    data, samplerate = sf.read('temppi.gsm')
    sf.write('temppi.wav', data, samplerate)
    
    实现连续录音和播放似乎是一个不错的选择。要进行录制,请查看
    InputStream
    RawInputStream
    。要播放,请查看
    OutputStream
    RawOutputStream

    data, samplerate = sf.read('temppi.gsm')
    sf.write('temppi.wav', data, samplerate)
    

    可能仍然可以使用
    SoundFile
    将GSM编解码器转换为原始音频,但您需要为每个块执行此操作。数据块必须非常小,例如20毫秒。

    让我更具体一点:data3=self.socket.recv(198)这183个字节中包含多少个样本?取样器是什么?这将对应于延迟或延迟。你能以连续无缝隙的方式播放不同的音频块吗?samplerate是8000,我不知道音频块,音频在流的中间等处播放良好,它是TCP流。我已经更新了我的问题,把所有的代码放在那里,我现在是怎么做的,我使用了bytesio,但它仍然很糟糕,我可以在飞行中完成它。
    data, samplerate = sf.read('temppi.gsm')
    sf.write('temppi.wav', data, samplerate)