minor change: struct rename

This commit is contained in:
Markus Tzoe 2017-04-19 11:02:24 +08:00
parent 7554c6e624
commit 02f13a5195
8 changed files with 153 additions and 153 deletions

31
codec.go Normal file
View file

@ -0,0 +1,31 @@
package tta
type Info struct {
format uint32 // audio format
nch uint32 // number of channels
bps uint32 // bits per sample
sps uint32 // samplerate (sps)
samples uint32 // data length in samples
}
type adapter struct {
k0 uint32
k1 uint32
sum0 uint32
sum1 uint32
}
func (a *adapter) init(k0, k1 uint32) {
a.k0 = k0
a.k1 = k1
a.sum0 = shift16[k0]
a.sum1 = shift16[k1]
}
type codec struct {
filter Filter
adapter adapter
prev int32
}
type Callback func(uint32, uint32, uint32)

View file

@ -208,4 +208,4 @@ var crc64TableHigh = [256]uint32{
0x5dedc41a, 0x1f1d25f1, 0xd80c07cd, 0x9afce626, 0x5dedc41a, 0x1f1d25f1, 0xd80c07cd, 0x9afce626,
} }
var fltSet = [3]int32{10, 9, 10} var shifts = [3]uint32{10, 9, 10}

View file

@ -6,10 +6,10 @@ import (
) )
type Decoder struct { type Decoder struct {
codec [maxNCH]ttaCodec // 1 per channel codecs [maxNCH]codec // 1 per channel
channels int // number of channels/codecs channels int // number of channels/codecs
data [8]byte // codec initialization data data [8]byte // codec initialization data
fifo ttaFifo fifo fifo
passwordSet bool // password protection flag passwordSet bool // password protection flag
seekAllowed bool // seek table flag seekAllowed bool // seek table flag
seekTable []uint64 // the playing position table seekTable []uint64 // the playing position table
@ -83,12 +83,12 @@ func (d *Decoder) ProcessStream(out []byte, cb Callback) int32 {
i := 0 i := 0
outClone := out[:] outClone := out[:]
for d.fpos < d.flen && len(outClone) > 0 { for d.fpos < d.flen && len(outClone) > 0 {
value = d.fifo.getValue(&d.codec[i].rice) value = d.fifo.getValue(&d.codecs[i].adapter)
// decompress stage 1: adaptive hybrid filter // decompress stage 1: adaptive hybrid filter
d.codec[i].filter.Decode(&value) d.codecs[i].filter.Decode(&value)
// decompress stage 2: fixed order 1 prediction // decompress stage 2: fixed order 1 prediction
value += ((d.codec[i].prev * ((1 << 5) - 1)) >> 5) value += ((d.codecs[i].prev * ((1 << 5) - 1)) >> 5)
d.codec[i].prev = value d.codecs[i].prev = value
cache[i] = value cache[i] = value
if i < d.channels-1 { if i < d.channels-1 {
i++ i++
@ -148,12 +148,12 @@ func (d *Decoder) ProcessFrame(inSize uint32, out []byte) int32 {
var ret int32 var ret int32
outClone := out[:] outClone := out[:]
for d.fifo.count < inSize && len(outClone) > 0 { for d.fifo.count < inSize && len(outClone) > 0 {
value = d.fifo.getValue(&d.codec[i].rice) value = d.fifo.getValue(&d.codecs[i].adapter)
// decompress stage 1: adaptive hybrid filter // decompress stage 1: adaptive hybrid filter
d.codec[i].filter.Decode(&value) d.codecs[i].filter.Decode(&value)
// decompress stage 2: fixed order 1 prediction // decompress stage 2: fixed order 1 prediction
value += ((d.codec[i].prev * ((1 << 5) - 1)) >> 5) value += ((d.codecs[i].prev * ((1 << 5) - 1)) >> 5)
d.codec[i].prev = value d.codecs[i].prev = value
cache[i] = value cache[i] = value
if i < d.channels-1 { if i < d.channels-1 {
i++ i++
@ -219,7 +219,7 @@ func (d *Decoder) frameInit(frame uint32, seekNeeded bool) (err error) {
if frame >= d.frames { if frame >= d.frames {
return return
} }
shift := fltSet[d.depth-1] shift := shifts[d.depth-1]
d.fnum = frame d.fnum = frame
if seekNeeded && d.seekAllowed { if seekNeeded && d.seekAllowed {
pos := d.seekTable[d.fnum] pos := d.seekTable[d.fnum]
@ -237,12 +237,12 @@ func (d *Decoder) frameInit(frame uint32, seekNeeded bool) (err error) {
} }
for i := 0; i < d.channels; i++ { for i := 0; i < d.channels; i++ {
if sseEnabled { if sseEnabled {
d.codec[i].filter = NewSSEFilter(d.data, shift) d.codecs[i].filter = NewSSEFilter(d.data, shift)
} else { } else {
d.codec[i].filter = NewCompatibleFilter(d.data, shift) d.codecs[i].filter = NewCompatibleFilter(d.data, shift)
} }
d.codec[i].rice.init(10, 10) d.codecs[i].adapter.init(10, 10)
d.codec[i].prev = 0 d.codecs[i].prev = 0
} }
d.fpos = 0 d.fpos = 0
d.fifo.reset() d.fifo.reset()

View file

@ -7,10 +7,10 @@ import (
) )
type Encoder struct { type Encoder struct {
codec [maxNCH]ttaCodec // 1 per channel codecs [maxNCH]codec // 1 per channel
channels int // number of channels/codecs channels int // number of channels/codecs
data [8]byte // codec initialization data data [8]byte // codec initialization data
fifo ttaFifo fifo fifo
seekTable []uint64 // the playing position table seekTable []uint64 // the playing position table
format uint32 // tta data format format uint32 // tta data format
rate uint32 // bitrate (kbps) rate uint32 // bitrate (kbps)
@ -115,11 +115,11 @@ func (e *Encoder) ProcessStream(in []byte, cb Callback) {
} }
// compress stage 1: fixed order 1 prediction // compress stage 1: fixed order 1 prediction
tmp = curr tmp = curr
curr -= ((e.codec[i].prev * ((1 << 5) - 1)) >> 5) curr -= ((e.codecs[i].prev * ((1 << 5) - 1)) >> 5)
e.codec[i].prev = tmp e.codecs[i].prev = tmp
// compress stage 2: adaptive hybrid filter // compress stage 2: adaptive hybrid filter
e.codec[i].filter.Encode(&curr) e.codecs[i].filter.Encode(&curr)
e.fifo.putValue(&e.codec[i].rice, curr) e.fifo.putValue(&e.codecs[i].adapter, curr)
if i < e.channels-1 { if i < e.channels-1 {
i++ i++
} else { } else {
@ -174,11 +174,11 @@ func (e *Encoder) ProcessFrame(in []byte) {
} }
// compress stage 1: fixed order 1 prediction // compress stage 1: fixed order 1 prediction
tmp = curr tmp = curr
curr -= ((e.codec[i].prev * ((1 << 5) - 1)) >> 5) curr -= ((e.codecs[i].prev * ((1 << 5) - 1)) >> 5)
e.codec[i].prev = tmp e.codecs[i].prev = tmp
// compress stage 2: adaptive hybrid filter // compress stage 2: adaptive hybrid filter
e.codec[i].filter.Encode(&curr) e.codecs[i].filter.Encode(&curr)
e.fifo.putValue(&e.codec[i].rice, curr) e.fifo.putValue(&e.codecs[i].adapter, curr)
if i < e.channels-1 { if i < e.channels-1 {
i++ i++
} else { } else {
@ -222,7 +222,7 @@ func (e *Encoder) frameInit(frame uint32) (err error) {
if frame >= e.frames { if frame >= e.frames {
return return
} }
shift := fltSet[e.depth-1] shift := shifts[e.depth-1]
e.fnum = frame e.fnum = frame
if e.fnum == e.frames-1 { if e.fnum == e.frames-1 {
e.flen = e.flenLast e.flen = e.flenLast
@ -232,12 +232,12 @@ func (e *Encoder) frameInit(frame uint32) (err error) {
// init entropy encoder // init entropy encoder
for i := 0; i < e.channels; i++ { for i := 0; i < e.channels; i++ {
if sseEnabled { if sseEnabled {
e.codec[i].filter = NewSSEFilter(e.data, shift) e.codecs[i].filter = NewSSEFilter(e.data, shift)
} else { } else {
e.codec[i].filter = NewCompatibleFilter(e.data, shift) e.codecs[i].filter = NewCompatibleFilter(e.data, shift)
} }
e.codec[i].rice.init(10, 10) e.codecs[i].adapter.init(10, 10)
e.codec[i].prev = 0 e.codecs[i].prev = 0
} }
e.fpos = 0 e.fpos = 0
e.fifo.reset() e.fifo.reset()

101
fifo.go
View file

@ -1,6 +1,21 @@
package tta package tta
func (s *ttaFifo) readByte() (v byte) { import (
"io"
)
type fifo struct {
buffer [fifoBufferSize]byte
pos int32
end int32
bcount uint32 // count of bits in cache
bcache uint32 // bit cache
crc uint32
count uint32
io io.ReadWriteSeeker
}
func (s *fifo) readByte() (v byte) {
if s.pos >= s.end { if s.pos >= s.end {
v, _ := s.io.Read(s.buffer[:]) // FIXME: handle this error v, _ := s.io.Read(s.buffer[:]) // FIXME: handle this error
s.end = int32(v) s.end = int32(v)
@ -13,14 +28,14 @@ func (s *ttaFifo) readByte() (v byte) {
return return
} }
func (s *ttaFifo) readUint16() (v uint16) { func (s *fifo) readUint16() (v uint16) {
v = 0 v = 0
v |= uint16(s.readByte()) v |= uint16(s.readByte())
v |= uint16(s.readByte()) << 8 v |= uint16(s.readByte()) << 8
return return
} }
func (s *ttaFifo) readUint32() (v uint32) { func (s *fifo) readUint32() (v uint32) {
v = 0 v = 0
v |= uint32(s.readByte()) v |= uint32(s.readByte())
v |= uint32(s.readByte()) << 8 v |= uint32(s.readByte()) << 8
@ -29,30 +44,30 @@ func (s *ttaFifo) readUint32() (v uint32) {
return return
} }
func (s *ttaFifo) readCrc32() bool { func (s *fifo) readCrc32() bool {
crc := s.crc ^ 0xFFFFFFFF crc := s.crc ^ 0xFFFFFFFF
return crc == s.readUint32() return crc == s.readUint32()
} }
func (s *ttaFifo) readStart() { func (s *fifo) readStart() {
s.pos = s.end s.pos = s.end
} }
func (s *ttaFifo) reset() { func (s *fifo) reset() {
s.crc = 0xFFFFFFFF s.crc = 0xFFFFFFFF
s.bcache = 0 s.bcache = 0
s.bcount = 0 s.bcount = 0
s.count = 0 s.count = 0
} }
func (s *ttaFifo) readSkipBytes(size uint32) { func (s *fifo) readSkipBytes(size uint32) {
for size > 0 { for size > 0 {
size-- size--
s.readByte() s.readByte()
} }
} }
func (s *ttaFifo) skipId3v2() (size uint32) { func (s *fifo) skipId3v2() (size uint32) {
s.reset() s.reset()
if 'I' != s.readByte() || 'D' != s.readByte() || '3' != s.readByte() { if 'I' != s.readByte() || 'D' != s.readByte() || '3' != s.readByte() {
s.pos = 0 s.pos = 0
@ -71,7 +86,7 @@ func (s *ttaFifo) skipId3v2() (size uint32) {
return return
} }
func (s *ttaFifo) getValue(rice *ttaAdapt) (value int32) { func (s *fifo) getValue(ad *adapter) (value int32) {
if s.bcache^bitMask[s.bcount] == 0 { if s.bcache^bitMask[s.bcount] == 0 {
value += int32(s.bcount) value += int32(s.bcount)
s.bcache = uint32(s.readByte()) s.bcache = uint32(s.readByte())
@ -93,11 +108,11 @@ func (s *ttaFifo) getValue(rice *ttaAdapt) (value int32) {
var level, k, tmp uint32 var level, k, tmp uint32
if value != 0 { if value != 0 {
level = 1 level = 1
k = rice.k1 k = ad.k1
value-- value--
} else { } else {
level = 0 level = 0
k = rice.k0 k = ad.k0
} }
if k != 0 { if k != 0 {
for s.bcount < k { for s.bcount < k {
@ -111,20 +126,20 @@ func (s *ttaFifo) getValue(rice *ttaAdapt) (value int32) {
s.bcache &= bitMask[s.bcount] s.bcache &= bitMask[s.bcount]
} }
if level != 0 { if level != 0 {
rice.sum1 += uint32(value) - (rice.sum1 >> 4) ad.sum1 += uint32(value) - (ad.sum1 >> 4)
if rice.k1 > 0 && rice.sum1 < shift16[rice.k1] { if ad.k1 > 0 && ad.sum1 < shift16[ad.k1] {
rice.k1-- ad.k1--
} else if rice.sum1 > shift16[rice.k1+1] { } else if ad.sum1 > shift16[ad.k1+1] {
rice.k1++ ad.k1++
} }
value += int32(bitShift[rice.k0]) value += int32(bitShift[ad.k0])
} }
rice.sum0 += uint32(value) - (rice.sum0 >> 4) ad.sum0 += uint32(value) - (ad.sum0 >> 4)
if rice.k0 > 0 && rice.sum0 < shift16[rice.k0] { if ad.k0 > 0 && ad.sum0 < shift16[ad.k0] {
rice.k0-- ad.k0--
} else if rice.sum0 > shift16[rice.k0+1] { } else if ad.sum0 > shift16[ad.k0+1] {
rice.k0++ ad.k0++
} }
// ((x & 1)?((x + 1) >> 1):(-x >> 1)) // ((x & 1)?((x + 1) >> 1):(-x >> 1))
if value&1 != 0 { if value&1 != 0 {
@ -135,11 +150,11 @@ func (s *ttaFifo) getValue(rice *ttaAdapt) (value int32) {
return return
} }
func (s *ttaFifo) writeStart() { func (s *fifo) writeStart() {
s.pos = 0 s.pos = 0
} }
func (s *ttaFifo) writeDone() error { func (s *fifo) writeDone() error {
if s.pos > 0 { if s.pos > 0 {
if n, err := s.io.Write(s.buffer[:s.pos]); err != nil || n != int(s.pos) { if n, err := s.io.Write(s.buffer[:s.pos]); err != nil || n != int(s.pos) {
return errWrite return errWrite
@ -149,7 +164,7 @@ func (s *ttaFifo) writeDone() error {
return nil return nil
} }
func (s *ttaFifo) writeByte(v byte) error { func (s *fifo) writeByte(v byte) error {
if s.pos == fifoBufferSize { if s.pos == fifoBufferSize {
if n, err := s.io.Write(s.buffer[:]); err != nil || n != fifoBufferSize { if n, err := s.io.Write(s.buffer[:]); err != nil || n != fifoBufferSize {
return errWrite return errWrite
@ -163,7 +178,7 @@ func (s *ttaFifo) writeByte(v byte) error {
return nil return nil
} }
func (s *ttaFifo) writeUint16(v uint16) error { func (s *fifo) writeUint16(v uint16) error {
if err := s.writeByte(byte(v)); err != nil { if err := s.writeByte(byte(v)); err != nil {
return err return err
} }
@ -173,7 +188,7 @@ func (s *ttaFifo) writeUint16(v uint16) error {
return nil return nil
} }
func (s *ttaFifo) writeUint32(v uint32) error { func (s *fifo) writeUint32(v uint32) error {
if err := s.writeByte(byte(v)); err != nil { if err := s.writeByte(byte(v)); err != nil {
return err return err
} }
@ -186,11 +201,11 @@ func (s *ttaFifo) writeUint32(v uint32) error {
return s.writeByte(byte(v >> 24)) return s.writeByte(byte(v >> 24))
} }
func (s *ttaFifo) writeCrc32() error { func (s *fifo) writeCrc32() error {
return s.writeUint32(s.crc ^ 0xFFFFFFFF) return s.writeUint32(s.crc ^ 0xFFFFFFFF)
} }
func (s *ttaFifo) writeSkipBytes(size uint32) error { func (s *fifo) writeSkipBytes(size uint32) error {
for size > 0 { for size > 0 {
if err := s.writeByte(0); err != nil { if err := s.writeByte(0); err != nil {
return err return err
@ -200,7 +215,7 @@ func (s *ttaFifo) writeSkipBytes(size uint32) error {
return nil return nil
} }
func (s *ttaFifo) putValue(rice *ttaAdapt, value int32) { func (s *fifo) putValue(ad *adapter, value int32) {
var k, unary, outval uint32 var k, unary, outval uint32
if value > 0 { if value > 0 {
outval = (uint32(value) << 1) - 1 outval = (uint32(value) << 1) - 1
@ -208,22 +223,22 @@ func (s *ttaFifo) putValue(rice *ttaAdapt, value int32) {
outval = uint32(-value) << 1 outval = uint32(-value) << 1
} }
// encode Rice unsigned // encode Rice unsigned
k = rice.k0 k = ad.k0
rice.sum0 += outval - (rice.sum0 >> 4) ad.sum0 += outval - (ad.sum0 >> 4)
if rice.k0 > 0 && rice.sum0 < shift16[rice.k0] { if ad.k0 > 0 && ad.sum0 < shift16[ad.k0] {
rice.k0-- ad.k0--
} else if rice.sum0 > shift16[rice.k0+1] { } else if ad.sum0 > shift16[ad.k0+1] {
rice.k0++ ad.k0++
} }
if outval >= bitShift[k] { if outval >= bitShift[k] {
outval -= bitShift[k] outval -= bitShift[k]
k = rice.k1 k = ad.k1
rice.sum1 += outval - (rice.sum1 >> 4) ad.sum1 += outval - (ad.sum1 >> 4)
if rice.k1 > 0 && rice.sum1 < shift16[rice.k1] { if ad.k1 > 0 && ad.sum1 < shift16[ad.k1] {
rice.k1-- ad.k1--
} else if rice.sum1 > shift16[rice.k1+1] { } else if ad.sum1 > shift16[ad.k1+1] {
rice.k1++ ad.k1++
} }
unary = 1 + (outval >> k) unary = 1 + (outval >> k)
} else { } else {
@ -260,7 +275,7 @@ func (s *ttaFifo) putValue(rice *ttaAdapt, value int32) {
} }
} }
func (s *ttaFifo) flushBitCache() { func (s *fifo) flushBitCache() {
for s.bcount > 0 { for s.bcount > 0 {
s.writeByte(byte(s.bcache)) s.writeByte(byte(s.bcache))
s.bcache >>= 8 s.bcache >>= 8

View file

@ -6,7 +6,7 @@ import (
func TestReadByte(t *testing.T) { func TestReadByte(t *testing.T) {
t.Parallel() t.Parallel()
fifo := ttaFifo{} fifo := fifo{}
for i := 0; i < fifoBufferSize; i++ { for i := 0; i < fifoBufferSize; i++ {
fifo.buffer[i] = byte(i) fifo.buffer[i] = byte(i)
} }
@ -33,7 +33,7 @@ func TestReadByte(t *testing.T) {
func TestReadUint16(t *testing.T) { func TestReadUint16(t *testing.T) {
t.Parallel() t.Parallel()
fifo := ttaFifo{} fifo := fifo{}
for i := 0; i < fifoBufferSize; i++ { for i := 0; i < fifoBufferSize; i++ {
fifo.buffer[i] = byte(i) fifo.buffer[i] = byte(i)
} }
@ -62,7 +62,7 @@ func TestReadUint16(t *testing.T) {
func TestReadUint32(t *testing.T) { func TestReadUint32(t *testing.T) {
t.Parallel() t.Parallel()
fifo := ttaFifo{} fifo := fifo{}
for i := 0; i < fifoBufferSize; i++ { for i := 0; i < fifoBufferSize; i++ {
fifo.buffer[i] = byte(i) fifo.buffer[i] = byte(i)
} }
@ -91,7 +91,7 @@ func TestReadUint32(t *testing.T) {
func TestWriteByte(t *testing.T) { func TestWriteByte(t *testing.T) {
t.Parallel() t.Parallel()
fifo := ttaFifo{} fifo := fifo{}
fifo.pos = 0 fifo.pos = 0
fifo.end = fifoBufferSize fifo.end = fifoBufferSize
for i := 0; i < fifoBufferSize; i++ { for i := 0; i < fifoBufferSize; i++ {

View file

@ -2,8 +2,25 @@ package tta
// TODO: SSE4 optimization // TODO: SSE4 optimization
func NewCompatibleFilter(data [8]byte, shift int32) Filter { type Filter interface {
t := ttaFilterCompat{} Decode(*int32)
Encode(*int32)
}
type filterCompat struct {
index int32
error int32
round int32
shift uint32
qm [8]int32
dx [24]int32
dl [24]int32
}
type filterSse filterCompat
func NewCompatibleFilter(data [8]byte, shift uint32) Filter {
t := filterCompat{}
t.shift = shift t.shift = shift
t.round = 1 << uint32(shift-1) t.round = 1 << uint32(shift-1)
t.qm[0] = int32(int8(data[0])) t.qm[0] = int32(int8(data[0]))
@ -17,7 +34,7 @@ func NewCompatibleFilter(data [8]byte, shift int32) Filter {
return &t return &t
} }
func (t *ttaFilterCompat) Decode(in *int32) { func (t *filterCompat) Decode(in *int32) {
pa := t.dl[:] pa := t.dl[:]
pb := t.qm[:] pb := t.qm[:]
pm := t.dx[:] pm := t.dx[:]
@ -67,7 +84,7 @@ func (t *ttaFilterCompat) Decode(in *int32) {
pa[4] += pa[5] pa[4] += pa[5]
} }
func (t *ttaFilterCompat) Encode(in *int32) { func (t *filterCompat) Encode(in *int32) {
pa := t.dl[:] pa := t.dl[:]
pb := t.qm[:] pb := t.qm[:]
pm := t.dx[:] pm := t.dx[:]
@ -120,8 +137,8 @@ func (t *ttaFilterCompat) Encode(in *int32) {
t.error = *in t.error = *in
} }
func NewSSEFilter(data [8]byte, shift int32) Filter { func NewSSEFilter(data [8]byte, shift uint32) Filter {
t := ttaFilterSse{} t := filterSse{}
t.shift = shift t.shift = shift
t.round = 1 << uint32(shift-1) t.round = 1 << uint32(shift-1)
t.qm[0] = int32(int8(data[0])) t.qm[0] = int32(int8(data[0]))
@ -135,8 +152,8 @@ func NewSSEFilter(data [8]byte, shift int32) Filter {
return &t return &t
} }
func (t *ttaFilterSse) Decode(in *int32) { func (t *filterSse) Decode(in *int32) {
} }
func (t *ttaFilterSse) Encode(in *int32) { func (t *filterSse) Encode(in *int32) {
} }

63
tta.go
View file

@ -1,63 +0,0 @@
package tta
import (
"io"
)
type Info struct {
format uint32 // audio format
nch uint32 // number of channels
bps uint32 // bits per sample
sps uint32 // samplerate (sps)
samples uint32 // data length in samples
}
type Filter interface {
Decode(*int32)
Encode(*int32)
}
type ttaFilterCompat struct {
index int32
error int32
round int32
shift int32
qm [8]int32
dx [24]int32
dl [24]int32
}
type ttaFilterSse ttaFilterCompat
type ttaAdapt struct {
k0 uint32
k1 uint32
sum0 uint32
sum1 uint32
}
func (rice *ttaAdapt) init(k0, k1 uint32) {
rice.k0 = k0
rice.k1 = k1
rice.sum0 = shift16[k0]
rice.sum1 = shift16[k1]
}
type ttaCodec struct {
filter Filter
rice ttaAdapt
prev int32
}
type ttaFifo struct {
buffer [fifoBufferSize]byte
pos int32
end int32
bcount uint32 // count of bits in cache
bcache uint32 // bit cache
crc uint32
count uint32
io io.ReadWriteSeeker
}
type Callback func(uint32, uint32, uint32)