我需要从Python读取音频WAVE文件,并将数据传输到侦听MATLAB中特定端口的远程服务器套接字。我正在尝试为此使用Python中的soundfile模块。我发现音频数据没有按原样传输到MATLAB服务器,因此,传输的音频数据没有在服务器中播放。

这是我在客户端(Python)上的代码:

   import soundfile as sf
   s = socket.socket()
   port = 30000
   s.connect(('127.0.0.1',port))

   data, samplerate = sf.read('speechrecord.wav')
   s.send(data)
   s.close()

这是MATLAB服务器端的代码:
   t=tcpip('127.0.0.1', 30000, 'NetworkRole', 'server');
   fopen(t);
   data = char(fread(t,128,'float'))
   fclose(t);

尝试了使用fread的不同用法在MATLAB端读取音频数据的不同组合。但是这些组合似乎都不起作用。

连接成功。 Python客户端代码已成功连接到MATLAB服务器(服务器中的“fopen”调用退出了阻塞状态)。客户端上还会生成一些数据,然后将其发送到服务器。但是,使用此fread调用在MATLAB服务器上接收的数据与客户端发送的数据完全不同(甚至没有一个字节匹配)。

如果任何人都可以通过这种组合来传输音频数据,那么请告知实现此目标的最佳方法。

最佳答案

问题

可悲的是您的问题是多种多样的。它们主要源于以下几行,可能还有一些误解。

MATLAB

data = char(fread(t, 128, 'float'))

Python
s.send(data)

在Python中,您要在套接字上发送浮点数,然后将其强制转换为字符数组。这只会将所有内容四舍五入到0,最后以ASCII 0 / NULL字符数组结束。 Check the char docs for more info

我也不认为从python发送数据时的字节序是正确的。因此,您需要研究使用struct packageformat your data correctly



我想说,在尝试连接到python中的指定套接字/端口之前,为了避免ConnectionRefusedError,将MATLAB服务器设置为侦听更为重要

您需要将彩车打包到bytearray中,这就是为什么要导入struct包的原因。对于单个样本,可以通过以下函数调用实现:

bytearray(struct.pack(">f", sample))

注意:默认情况下,仪器工具箱tcpip()对象显示为big-endian。

以下脚本仅发送音频文件的第一个100示例。下一个任务是创建一个系统,在其中检查传输是否成功。用套接字文档的话:

应用程序负责检查所有数据是否已发送;如果仅传输了一些数据,则应用程序需要尝试传送其余数据。有关此主题的更多信息,请查询Socket Programming HOWTO

对于回放, soundsc() 应该执行此操作,因为它将在回放之前将音频标准化,并避免任何讨厌的噪音。

MATLAB

请记住,这仍然只会读取100值。

t = tcpip('localhost', 30000, 'NetworkRole', 'server');
fopen(t);                       % this is blocking block until a connection is made
data = fread(t, 100, 'float');  % this is blocking until it receives 100 floats
fclose(t);
plot(data);
disp(data); % sanity check, should be the same as Python script print

Python

并且只会发送第一个100值。

import soundfile as sf
import socket
import struct

audio_file_path = 'path/to/audio.wav'
data, sample_rate = sf.read(audio_file_path)
data_bytes = bytearray()

s = socket.socket()
port = 30000
s.connect(('127.0.0.1', port))

for sample in data[0:100]:
    data_bytes = data_bytes + bytearray(struct.pack(">f", sample))

s.send(data_bytes) # blocks until all data sent
s.close()

print(data[0:100]) # sanity check

依存关系

以上代码的依赖项为:

的MATLAB
  • Instrument Control Toolbox

  • python
  • SoundFile
  • 10-07 15:59
    查看更多