Create new packet codec QuantizedDoubleCodec

This commit is contained in:
tfarley 2016-07-24 19:09:11 -07:00 committed by pschord
parent 4a4f0b4466
commit d2b6a8c451
3 changed files with 98 additions and 0 deletions

View file

@ -0,0 +1,54 @@
// Copyright (c) 2016 PSForever.net to present
package net.psforever.newcodecs
import scodec.{ Attempt, Codec, DecodeResult, Err, SizeBound }
import scodec.bits.{ BitVector, ByteOrdering }
final class QuantizedDoubleCodec(min: Double, max: Double, bits: Int) extends Codec[Double] {
require(bits > 0 && bits <= 32, "bits must be in range [1, 32]")
private val bitsL = bits.toLong
private def description = s"$bits-bit q_double [$min, $max]"
override def sizeBound = SizeBound.exact(bitsL)
def QuantizeDouble(value : Double) : Int = {
val range : Double = max - min;
if (range == 0.0)
return 0
val bit_max : Int = 1 << bits;
val rounded_quantized : Int = math.floor((value - min) * bit_max.toDouble / range + 0.5).toInt
if (rounded_quantized < 0)
return 0
if (rounded_quantized > bit_max - 1)
return (bit_max - 1)
return rounded_quantized
}
def UnquantizeDouble(value : Int) : Double = {
return ((max - min) * value.toDouble / (1 << bitsL).toDouble + min)
}
override def encode(value: Double) = {
if (value == 0.0)
Attempt.successful(BitVector.fromInt(0, bits))
else
Attempt.successful(BitVector.fromInt(QuantizeDouble(value), bits, ByteOrdering.LittleEndian))
}
override def decode(buffer: BitVector) = {
if (buffer.sizeGreaterThanOrEqual(bitsL))
Attempt.successful(DecodeResult(UnquantizeDouble(buffer.take(bitsL).toInt(false, ByteOrdering.LittleEndian)), buffer.drop(bitsL)))
else
Attempt.failure(Err.insufficientBits(bitsL, buffer.size))
}
override def toString = description
}

View file

@ -0,0 +1,10 @@
// Copyright (c) 2016 PSForever.net to present
package net.psforever.newcodecs
import scodec.Codec
package object newcodecs {
def q_double(min: Double, max: Double, bits: Int): Codec[Double] = new QuantizedDoubleCodec(min, max, bits)
}