Normalizes a float32 LE raw file
// | |
// Normalizes a float32 little-endian raw file to the first few averaged values. | |
// The averaged values will be treated as the baseline and all values in the | |
// file will be relative to that. | |
// | |
// 2020.11.04 darell tan | |
// | |
package main | |
import ( | |
"fmt" | |
"io" | |
"math" | |
"os" | |
) | |
var avgSamples = 10 // number of values to average | |
func readFloat(buf []byte) float32 { | |
v := uint32(buf[0]) << 0 | |
v |= uint32(buf[1]) << 8 | |
v |= uint32(buf[2]) << 16 | |
v |= uint32(buf[3]) << 24 | |
return math.Float32frombits(v) | |
} | |
func writeFloat(buf []byte, v float32) { | |
v2 := math.Float32bits(v) | |
buf[0] = byte(v2 >> 0) | |
buf[1] = byte(v2 >> 8) | |
buf[2] = byte(v2 >> 16) | |
buf[3] = byte(v2 >> 24) | |
} | |
func main() { | |
fname := os.Args[1] | |
f, err := os.OpenFile(fname, os.O_RDWR, 0644) | |
if err != nil { | |
panic(err) | |
} | |
defer f.Close() | |
buf := make([]byte, 1024*4) | |
// read samples for averaging | |
if _, err = f.Read(buf[:4*avgSamples]); err != nil { | |
panic(err) | |
} | |
normValueSum := float64(0) | |
for i := 0; i < avgSamples; i++ { | |
v := readFloat(buf[i*4 : i*4+4]) | |
normValueSum += float64(v) | |
} | |
normValue := float32(normValueSum / float64(avgSamples)) | |
fmt.Printf("normal value: %f\n", normValue) | |
f.Seek(0, 0) // restart | |
for offset := uint64(0); ; { | |
n, err := f.Read(buf) | |
if err == io.EOF { | |
break | |
} | |
if err != nil { | |
panic(err) | |
} | |
for i := 0; i < n; i += 4 { | |
v := readFloat(buf[i : i+4]) | |
v -= normValue | |
writeFloat(buf[i:], v) | |
} | |
f.Seek(int64(offset), 0) | |
f.Write(buf) | |
offset += uint64(n) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment