简体   繁体   English

Python f.read()和Octave fread()。 =>读取显示相同值的二进制文件

[英]Python f.read() and Octave fread(). => Reading a binary file showing the same values

I'm reading a binary file with signal samples both in Octave and Python. 我正在用Octave和Python读取带有信号样本的二进制文件。

The thing is, I want to obtain the same values for both codes, which is not the case. 问题是,我想为两个代码获得相同的值,事实并非如此。

The binary file is basically a signal in complex format I,Q recorded as a 16bits Int. 二进制文件基本上是一个复杂格式为I,Q的信号,记录为16位Int。

So, based on the Octave code: 因此,基于八度代码:

[data, cnt_data] = fread(fid, 2 * secondOfData * fs, 'int16');

and then: 接着:

data = data(1:2:end) + 1i * data(2:2:end);

It seems simple, just reading the binary data as 16 bits ints. 看起来很简单,只需将二进制数据读取为16位int。 And then creating the final array of complex numbers. 然后创建最终的复数数组。

Threfore I assume that in Python I need to do as follows: 因此,我假设在Python中我需要执行以下操作:

rel=int(f.read(2).encode("hex"),16)
img=int(f.read(2).encode("hex"),16)
in_clean.append(complex(rel,img))

Ok, the main problem I have is that both real and imaginary parts values are not the same. 好的,我的主要问题是实部和虚部的值都不相同。

For instance, in Octave, the first value is: -20390 - 10053i 例如,在八度中,第一个值是: -20390-10053i

While in Python (applying the code above), the value is: (23216+48088j) 在Python中(应用上面的代码),值是:(23216 + 48088j)

As signs are different, the first thing I thought was that maybe the endianness of the computer that recorded the file and the one I'm using for reading the file are different. 由于符号不同,所以我首先想到的是,记录该文件的计算机的字节序可能与我用来读取该文件的计算机的字节序不同。 So I turned to unpack function, as it allows you to force the endian type. 因此,我转向解压缩功能,因为它允许您强制使用字节序类型。

I was not able to find an "int16" in the unpack documentation: https://docs.python.org/2/library/struct.html 我在解压缩文档中找不到“ int16”: https ://docs.python.org/2/library/struct.html

Therefore I went for the "i" option adding "x" (padding bytes) in order to meet the requirement of 32 bits from the table in the "struct" documentation. 因此,我选择添加“ x”(填充字节)的“ i”选项,以满足“结构”文档中表中32位的要求。

So with: 因此:

struct.unpack("i","xx"+f.read(2))[0]

the result is (-1336248200-658802568j) Using struct.unpack("<i","xx"+f.read(2))[0] provides the same result. 结果为(-1336248200-658802568j)使用struct.unpack("<i","xx"+f.read(2))[0]提供相同的结果。

With: 附:

struct.unpack(">i","xx"+f.read(2))[0]

The value is: (2021153456+2021178328j) 值是:(2021153456 + 2021178328j)

With: 附:

struct.unpack(">i",f.read(2)+"xx")[0]

The value is: (1521514616-1143441288j) 值是:(1521514616-1143441288j)

With: 附:

struct.unpack("<i",f.read(2)+"xx")[0]

The value is: (2021175386+2021185723j) 值是:(2021175386 + 2021185723j)

I also tried with numpy and "frombuffer": 我也尝试了numpy和“ frombuffer”:

np.frombuffer(f.read(1).encode("hex"),dtype=np.int16)

With provides: (24885+12386j) 具有提供:(24885 + 12386j)

So, any idea about what I'm doing wrong? 那么,关于我在做什么错的任何想法吗? I'd like to obtain the same value as in Octave. 我想获得与八度相同的值。

What is the proper way of reading and interpreting the values in Python so I can obtain the same value as in Octave by applying fread with an'int16'? 在Python中读取和解释值的正确方法是什么,以便通过使用带'int16'的fread来获得与Octave相同的值?

I've been searching on the Internet for an answer for this but I was not able to find a method that provides the same value 我一直在互联网上寻找答案,但是找不到能够提供相同价值的方法

Thanks a lot Best regards 非常感谢

It looks like the binary data in your question is 5ab0bbd8 . 看来您问题中的二进制数据是5ab0bbd8 To unpack signed 16 bit integers with struct.unpack , you use the 'h' format character. 要使用struct.unpack解压缩带符号的16位整数,请使用'h'格式字符。 From that (23216+48088j) output, it appears that the data is encoded as little-endian, so we need to use < as the first item in the format string. (23216+48088j)输出来看,数据似乎被编码为little-endian,因此我们需要使用<作为格式字符串中的第一项。

from struct import unpack

data = b'\x5a\xb0\xbb\xd8'

# The wrong way
rel=int(data[:2].encode("hex"),16)
img=int(data[2:].encode("hex"),16)
c = complex(rel, img)
print c

# The right way
rel, img = unpack('<hh', data)
c = complex(rel, img)
print c 

output 产量

(23216+48088j)
(-20390-10053j)

Note that rel, img = unpack('<hh', data) will also work correctly on Python 3. 请注意, rel, img = unpack('<hh', data)也将在Python 3上正常工作。


FWIW, in Python 3, you could also decode 2 bytes to a signed integer like this: FWIW,在Python 3,你也可以解码2个字节,以这样的符号整数:

def int16_bytes_to_int(b):
    n = int.from_bytes(b, 'little')
    if n > 0x7fff:
        n -= 0x10000
    return n

The rough equivalent in Python 2 is: Python 2中的大致等效项是:

def int16_bytes_to_int(b):
    lo, hi = b
    n = (ord(hi) << 8) + ord(lo)
    if n > 0x7fff:
        n -= 0x10000
    return n

But having to do that subtraction to handle signed numbers is annoying, and using struct.unpack is bound to be much more efficient. 但是必须进行这种减法处理带符号的数字很烦人,并且使用struct.unpack肯定会更加高效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM