so I think questions like this have been asked before but I'm having quite a bit of trouble getting this implemented.
I'm dealing with CSV files that contain floating points between -1 and 1. All of these floating points have to be converted to 16 bit 2s complement without the leading '0b'. From there, I will convert that number to a string representation of the 2s complement, and all of those from the CSV will be written will be written to a .dat file with no space in between. So for example, if I read in the CSV file and it has two entries [0.006534, -.1232], I will convert each entry to their respective 2s complement and write them one after another onto a .dat file.
The problem is I'm getting stuck in my code on how to convert the floating point to a 16 bit 2s complement. I've been looking at other posts like this and I've been told to use the .float() function but I've had no luck.
Can someone help me write a script that will take in a floating point number, and return the 16 bit 2s complement string of it? It has to be exactly 16 bits because I'm dealing with the MIT 16 standard.
I am using python 3.4 btw
To answer the question in the title: to convert a Python float
to IEEE 754 half-precision binary floating-point format, you could use binary16
:
>>> from binary16 import binary16
>>> binary16(0.006534)
b'\xb0\x1e'
>>> binary16(-.1232)
b'\xe2\xaf'
numpy
produces similar results:
>>> import numpy as np
>>> np.array([0.006534, -.1232], np.float16).tostring()
b'\xb1\x1e\xe3\xaf'
>>> np.array([0.006534, -.1232], '>f2').tostring() # big-endian
b'\x1e\xb1\xaf\xe3'
My goal was to save the amplitudes as the ecg mit signal format 16
..snip..
the input is a .CSV file containing the f.p. values of the amplitude from a .WAV file (which is the recording of an ECG).
You could read the wav file directly and write the corresponding 16-bit two's complement amplitudes in little-endian byte order where any unused high-order bits are sign-extended from the most significant bit ('<h'
struct format):
#!/usr/bin/env python3
import wavewith wave.open('ecg.wav') as wavfile, open('ecg.mit16', 'wb') as output_file:assert wavfile.getnchannels() == 1 # monoassert wavfile.getsampwidth() == 2 # 16bitoutput_file.writelines(iter(lambda: wavfile.readframes(4096), b''))
There is a bug in Python 3 that .readframes()
returns str
instead of bytes
sometimes. To workaround it, use if not data
test that works on both empty str
and bytes
:
#!/usr/bin/env python3
import wavewith wave.open('ecg.wav') as wavfile, open('ecg.mit16', 'wb') as output_file:assert wavfile.getnchannels() == 1 # monoassert wavfile.getsampwidth() == 2 # 16bitwhile True:data = wavfile.readframes(4096)if not data:breakoutput_file.write(data)