我需要从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 package到format 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
python