You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
3.9 KiB
Go

package utils
import (
"fmt"
"github.com/fatih/color"
"github.com/dhogborg/go-pocsag/internal/datatypes"
)
var (
DEBUG bool
LEVEL int
)
var (
green = color.New(color.FgGreen)
red = color.New(color.FgRed)
blue = color.New(color.FgBlue)
)
// Tell the package to print debug data
func SetDebug(d bool, verbosity int) {
DEBUG = d
LEVEL = verbosity
}
// StreamToBits converts samples to bits using the bitlength specified.
// Observe that POCSAG signifies a high bit with a low frequency.
func StreamToBits(stream []int16, bitlength int) []datatypes.Bit {
bits := make([]datatypes.Bit, (len(stream)/bitlength)+1)
b := 0
for a := 0; a < len(stream); a += bitlength {
sample := stream[a]
if a > 2 && a < len(stream)-2 {
// let the samples before and after influence our sample, to prevent spike errors
sample = (stream[a-1] / 2) + stream[a] + (stream[a+1] / 2)
}
bits[b] = datatypes.Bit((sample < 0))
b += 1
}
return bits
}
// MSBBitsToBytes converts bitsream to bytes using MSB to LSB order.
func MSBBitsToBytes(bits []datatypes.Bit, bitsPerByte int) []byte {
var b uint8
bytes := []byte{}
power := bitsPerByte - 1
for a := 0; a < len(bits); a += 1 {
bit := bits[a].UInt8()
mod := a % bitsPerByte
if mod == 0 && a > 0 {
bytes = append(bytes, b)
b = 0
}
pow := uint(power - mod)
b += (bit * (1 << pow))
}
if len(bits)%bitsPerByte == 0 {
bytes = append(bytes, b)
}
return bytes
}
// LSBBitsToBytes converts bitsream to bytes using LSB to MSB order.
func LSBBitsToBytes(bits []datatypes.Bit, bitsPerByte int) []byte {
var b uint8
bytes := []byte{}
for a := 0; a < len(bits); a += 1 {
bit := bits[a].UInt8()
mod := a % bitsPerByte
if mod == 0 && a > 0 {
bytes = append(bytes, b)
b = 0
}
pow := uint(mod)
b += (bit * (1 << pow))
}
if len(bits)%bitsPerByte == 0 {
bytes = append(bytes, b)
}
return bytes
}
// simple parity check
func ParityCheck(bits []datatypes.Bit, even_bit datatypes.Bit) bool {
sum := even_bit.Int()
for _, b := range bits {
if b {
sum += 1
}
}
return (sum % 2) == 0
}
// BitcodedDecimals takes 4 bits per decimal to create values between 0 and 15.
// *) values 0-9 are used as is
// *) values 10-14 are special characters translated by bcdSpecial()
// *) value = 15 is not used.
func BitcodedDecimals(bits []datatypes.Bit) string {
msg := ""
var foo uint8 = 0
bitsPerByte := 4
for a := 0; a < len(bits); a += 1 {
bit := bits[a].UInt8()
mod := a % bitsPerByte
if mod == 0 && a > 0 {
msg += bcdChar(foo)
foo = 0
}
pow := uint(mod)
foo += (bit * (1 << pow))
}
if len(bits)%bitsPerByte == 0 {
msg += bcdChar(foo)
}
return msg
}
// bcdChar translates digits and non-digit bitcoded entitis to charaters as per POCSAG protocol
func bcdChar(foo uint8) string {
if foo < 10 {
return fmt.Sprintf("%d", foo)
}
if foo == 10 {
return ""
}
chars := []string{
"",
"U",
" ",
"-",
")",
"(",
}
return chars[foo-10]
}
func Btouint32(bytes []byte) uint32 {
var a uint32 = 0
a += uint32(bytes[0]) << 24
a += uint32(bytes[1]) << 16
a += uint32(bytes[2]) << 8
a += uint32(bytes[3])
return a
}
func TernaryStr(condition bool, a, b string) string {
if condition {
return a
} else {
return b
}
}
// PrintStream, used for debugging of streams
func PrintStream(samples []int16) {
for _, sample := range samples {
PrintSample(sample)
}
println("")
}
// PrintBitstream, used for debugging of streams
func PrintBitstream(bits []datatypes.Bit) {
for _, b := range bits {
PrintSample(int16(b.Int()))
}
println("")
}
// PrintSample, used for debugging of streams
func PrintSample(sample int16) {
if sample > 0 {
green.Printf("%d ", sample)
} else {
red.Printf("%d ", sample)
}
}
func PrintUint32(i uint32) {
var x uint32 = 1 << 31
for a := 0; a < 32; a += 1 {
if (i & x) > 0 {
green.Print("1 ")
} else {
red.Print("0 ")
}
x >>= 1
}
println("")
}