silence gofmt -s, go vet, most of golint

This commit is contained in:
Markus Tzoe 2016-02-26 14:10:17 +08:00
parent e0222d803b
commit 7f7eb3ec85
14 changed files with 670 additions and 667 deletions

View file

@ -1,9 +1,10 @@
# tta
[![Go Report Card](https://goreportcard.com/badge/github.com/zyxar/tta)](https://goreportcard.com/report/github.com/zyxar/tta)
[![GoDoc](https://godoc.org/github.com/zyxar/tta?status.svg)](https://godoc.org/github.com/zyxar/tta)
[TTA Lossless Audio Codec](http://en.true-audio.com/TTA_Lossless_Audio_Codec_-_Realtime_Audio_Compressor) Encoder/Decoder for #golang
## [API doc](https://godoc.org/github.com/zyxar/tta)
## *gotta* console tool
## `gotta` console tool
- install: `go get github.com/zyxar/tta/cmd/gotta`
- usage:

View file

@ -23,10 +23,10 @@ func init() {
}
func main() {
fmt.Fprintf(os.Stderr, "\r\nTTA1 lossless audio encoder/decoder, version %s{%d}\n\n", tta.VERSION, tta.BinaryVersion())
fmt.Fprintf(os.Stderr, "\r\nTTA1 lossless audio encoder/decoder, version %s{%d}\n\n", tta.Version, tta.BinaryVersion())
flag.Parse()
if help || flag.NArg() < 1 || (!decode && !encode) {
fmt.Fprintln(os.Stderr, "\rUsage of gotta: [encode|decode] [passwd PASSWORD] INPUT_FILE OUTPUT_FILE\n")
fmt.Fprintf(os.Stderr, "\rUsage of gotta: [encode|decode] [passwd PASSWORD] INPUT_FILE OUTPUT_FILE\n\n")
flag.PrintDefaults()
return
}

View file

@ -5,45 +5,45 @@ import (
)
const (
MAX_DEPTH = 3
MAX_BPS = (MAX_DEPTH * 8)
MIN_BPS = 16
MAX_NCH = 6
FIFO_BUFFER_SIZE = 5120
PCM_BUFFER_LENGTH = 5120
maxDepth = 3
maxBPS = (maxDepth * 8)
minBPS = 16
maxNCH = 6
fifoBufferSize = 5120
pcmBufferLength = 5120
// TTA audio format
FORMAT_SIMPLE = 1
FORMAT_ENCRYPTED = 2
formatSimple = 1
formatEncrypted = 2
VERSION = "0.0.1"
// Version of TTA lib
Version = "0.0.1"
)
var (
// TTA_CODEC_STATUS
NO_ERROR error = nil // no known errors found
OPEN_ERROR = errors.New("can't open file")
FORMAT_ERROR = errors.New("not compatible file format")
FILE_ERROR = errors.New("file is corrupted")
READ_ERROR = errors.New("can't read from input file")
WRITE_ERROR = errors.New("can't write to output file")
SEEK_ERROR = errors.New("file seek error")
PASSWORD_ERROR = errors.New("password protected file")
NOT_SUPPORTED = errors.New("unsupported architecture")
PARTIAL_WRITTEN_ERROR = errors.New("partial written")
PARTIAL_READ_ERROR = errors.New("partial read")
errOpen = errors.New("can't open file")
errFormat = errors.New("not compatible file format")
errFile = errors.New("file is corrupted")
errRead = errors.New("can't read from input file")
errWrite = errors.New("can't write to output file")
errSeek = errors.New("file seek error")
errPassword = errors.New("password protected file")
errNotSupported = errors.New("unsupported architecture")
// Partial io
errPartialWritten = errors.New("partial written")
errPartialRead = errors.New("partial read")
)
const ( // CPU_ARCH_TYPE
CPU_ARCH_UNDEFINED = iota
CPU_ARCH_IX86_SSE2
CPU_ARCH_IX86_SSE3
CPU_ARCH_IX86_SSE4_1
CPU_ARCH_IX86_SSE4_2
cpuArchUndefined = iota
cpuArchIx86Sse2
cpuArchIx86Sse3
cpuArchIx86Sse4_1
cpuArchIx86Sse4_2
)
var bit_mask = []uint32{
var bitMask = []uint32{
0x00000000, 0x00000001, 0x00000003, 0x00000007,
0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
@ -53,9 +53,9 @@ var bit_mask = []uint32{
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
0xffffffff,
} // bit_mask
}
var bit_shift = []uint32{
var bitShift = []uint32{
0x00000001, 0x00000002, 0x00000004, 0x00000008,
0x00000010, 0x00000020, 0x00000040, 0x00000080,
0x00000100, 0x00000200, 0x00000400, 0x00000800,
@ -66,11 +66,11 @@ var bit_shift = []uint32{
0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x80000000, 0x80000000, 0x80000000, 0x80000000,
0x80000000, 0x80000000, 0x80000000, 0x80000000,
} // bit_shift
}
var shift_16 = bit_shift[4:]
var shift16 = bitShift[4:]
var crc32_table = [256]uint32{
var crc32Table = [256]uint32{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
@ -114,9 +114,9 @@ var crc32_table = [256]uint32{
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
} // crc32_table
}
var crc64_table_lo = [256]uint32{
var crc64TableLow = [256]uint32{
0x00000000, 0xa9ea3693, 0x53d46d26, 0xfa3e5bb5, 0x0e42ecdf, 0xa7a8da4c,
0x5d9681f9, 0xf47cb76a, 0x1c85d9be, 0xb56fef2d, 0x4f51b498, 0xe6bb820b,
0x12c73561, 0xbb2d03f2, 0x41135847, 0xe8f96ed4, 0x90e185ef, 0x390bb37c,
@ -160,9 +160,9 @@ var crc64_table_lo = [256]uint32{
0x267cdbd3, 0x8f96ed40, 0x75a8b6f5, 0xdc428066, 0x283e370c, 0x81d4019f,
0x7bea5a2a, 0xd2006cb9, 0x3af9026d, 0x931334fe, 0x692d6f4b, 0xc0c759d8,
0x34bbeeb2, 0x9d51d821, 0x676f8394, 0xce85b507,
} // crc64_table_lo
}
var crc64_table_hi = [256]uint32{
var crc64TableHigh = [256]uint32{
0x00000000, 0x42f0e1eb, 0x85e1c3d7, 0xc711223c, 0x49336645, 0x0bc387ae,
0xccd2a592, 0x8e224479, 0x9266cc8a, 0xd0962d61, 0x17870f5d, 0x5577eeb6,
0xdb55aacf, 0x99a54b24, 0x5eb46918, 0x1c4488f3, 0x663d78ff, 0x24cd9914,
@ -206,7 +206,6 @@ var crc64_table_hi = [256]uint32{
0x86b86ed5, 0xc4488f3e, 0x0359ad02, 0x41a94ce9, 0xcf8b0890, 0x8d7be97b,
0x4a6acb47, 0x089a2aac, 0x14dea25f, 0x562e43b4, 0x913f6188, 0xd3cf8063,
0x5dedc41a, 0x1f1d25f1, 0xd80c07cd, 0x9afce626,
} // crc64_table_hi
}
var flt_set = [3]int32{10, 9, 10}
var SSE_Enabled bool
var fltSet = [3]int32{10, 9, 10}

4
cpu.go
View file

@ -4,8 +4,10 @@ import (
"github.com/klauspost/cpuid"
)
var sseEnabled bool
func init() {
if cpuid.CPU.SSE4() {
// SSE_Enabled = true // use this if SSE optimization is done
// sseEnabled = true // use this if SSE optimization is done
}
}

View file

@ -6,23 +6,23 @@ import (
)
type Decoder struct {
codec [MAX_NCH]tta_codec // 1 per channel
channels int // number of channels/codecs
data [8]byte // codec initialization data
fifo tta_fifo
password_set bool // password protection flag
seek_allowed bool // seek table flag
seek_table []uint64 // the playing position table
format uint32 // tta data format
rate uint32 // bitrate (kbps)
offset uint64 // data start position (header size, bytes)
frames uint32 // total count of frames
depth uint32 // bytes per sample
flen_std uint32 // default frame length in samples
flen_last uint32 // last frame length in samples
flen uint32 // current frame length in samples
fnum uint32 // currently playing frame index
fpos uint32 // the current position in frame
codec [maxNCH]ttaCodec // 1 per channel
channels int // number of channels/codecs
data [8]byte // codec initialization data
fifo ttaFifo
passwordSet bool // password protection flag
seekAllowed bool // seek table flag
seekTable []uint64 // the playing position table
format uint32 // tta data format
rate uint32 // bitrate (kbps)
offset uint64 // data start position (header size, bytes)
frames uint32 // total count of frames
depth uint32 // bytes per sample
flenStd uint32 // default frame length in samples
flenLast uint32 // last frame length in samples
flen uint32 // current frame length in samples
fnum uint32 // currently playing frame index
fpos uint32 // the current position in frame
}
func Decompress(infile, outfile io.ReadWriteSeeker, passwd string, cb Callback) (err error) {
@ -34,36 +34,36 @@ func Decompress(infile, outfile io.ReadWriteSeeker, passwd string, cb Callback)
if err = decoder.GetInfo(&info, 0); err != nil {
return
}
smp_size := info.nch * ((info.bps + 7) / 8)
data_size := info.samples * smp_size
wave_hdr := WaveHeader{
chunk_id: _RIFF_SIGN,
chunk_size: data_size + 36,
format: _WAVE_SIGN,
subchunk_id: _FMT_SIGN,
subchunk_size: 16,
audio_format: 1,
num_channels: uint16(info.nch),
sample_rate: info.sps,
bits_per_sample: uint16(info.bps),
byte_rate: info.sps * smp_size,
block_align: uint16(smp_size),
smpSize := info.nch * ((info.bps + 7) / 8)
dataSize := info.samples * smpSize
waveHdr := WaveHeader{
chunkId: riffSign,
chunkSize: dataSize + 36,
format: waveSign,
subchunkId: fmtSign,
subchunkSize: 16,
audioFormat: 1,
numChannels: uint16(info.nch),
sampleRate: info.sps,
bitsPerSample: uint16(info.bps),
byteRate: info.sps * smpSize,
blockAlign: uint16(smpSize),
}
if err = wave_hdr.Write(outfile, data_size); err != nil {
if err = waveHdr.Write(outfile, dataSize); err != nil {
return
}
buf_size := PCM_BUFFER_LENGTH * smp_size
buffer := make([]byte, buf_size)
var write_len int
bufSize := pcmBufferLength * smpSize
buffer := make([]byte, bufSize)
var writeLen int
for {
if write_len = int(uint32(decoder.ProcessStream(buffer, cb)) * smp_size); write_len == 0 {
if writeLen = int(uint32(decoder.ProcessStream(buffer, cb)) * smpSize); writeLen == 0 {
break
}
buf := buffer[:write_len]
if write_len, err = outfile.Write(buf); err != nil {
buf := buffer[:writeLen]
if writeLen, err = outfile.Write(buf); err != nil {
return
} else if write_len != len(buf) {
err = PARTIAL_WRITTEN_ERROR
} else if writeLen != len(buf) {
err = errPartialWritten
return
}
}
@ -76,26 +76,26 @@ func NewDecoder(iocb io.ReadWriteSeeker) *Decoder {
return &dec
}
func (this *Decoder) ProcessStream(out []byte, cb Callback) int32 {
var cache [MAX_NCH]int32
func (d *Decoder) ProcessStream(out []byte, cb Callback) int32 {
var cache [maxNCH]int32
var value int32
var ret int32 = 0
var ret int32
i := 0
out_ := out[:]
for this.fpos < this.flen && len(out_) > 0 {
value = this.fifo.get_value(&this.codec[i].rice)
outClone := out[:]
for d.fpos < d.flen && len(outClone) > 0 {
value = d.fifo.getValue(&d.codec[i].rice)
// decompress stage 1: adaptive hybrid filter
this.codec[i].filter.Decode(&value)
d.codec[i].filter.Decode(&value)
// decompress stage 2: fixed order 1 prediction
value += ((this.codec[i].prev * ((1 << 5) - 1)) >> 5)
this.codec[i].prev = value
value += ((d.codec[i].prev * ((1 << 5) - 1)) >> 5)
d.codec[i].prev = value
cache[i] = value
if i < this.channels-1 {
if i < d.channels-1 {
i++
} else {
if this.channels == 1 {
write_buffer(value, out_, this.depth)
out_ = out_[this.depth:]
if d.channels == 1 {
writeBuffer(value, outClone, d.depth)
outClone = outClone[d.depth:]
} else {
k := i - 1
cache[i] += cache[k] / 2
@ -105,62 +105,62 @@ func (this *Decoder) ProcessStream(out []byte, cb Callback) int32 {
}
cache[k] = cache[k+1] - cache[k]
for k <= i {
write_buffer(cache[k], out_, this.depth)
out_ = out_[this.depth:]
writeBuffer(cache[k], outClone, d.depth)
outClone = outClone[d.depth:]
k++
}
}
i = 0
this.fpos++
d.fpos++
ret++
}
if this.fpos == this.flen {
if d.fpos == d.flen {
// check frame crc
crc_flag := !this.fifo.read_crc32()
if crc_flag {
crcFlag := !d.fifo.readCrc32()
if crcFlag {
for i := 0; i < len(out); i++ {
out[i] = 0
}
if !this.seek_allowed {
if !d.seekAllowed {
break
}
}
this.fnum++
d.fnum++
// update dynamic info
this.rate = (this.fifo.count << 3) / 1070
d.rate = (d.fifo.count << 3) / 1070
if cb != nil {
cb(this.rate, this.fnum, this.frames)
cb(d.rate, d.fnum, d.frames)
}
if this.fnum == this.frames {
if d.fnum == d.frames {
break
}
this.frame_init(this.fnum, crc_flag)
d.frameInit(d.fnum, crcFlag)
}
}
return ret
}
func (this *Decoder) ProcessFrame(in_size uint32, out []byte) int32 {
func (d *Decoder) ProcessFrame(inSize uint32, out []byte) int32 {
i := 0
var cache [MAX_NCH]int32
var cache [maxNCH]int32
var value int32
var ret int32 = 0
out_ := out[:]
for this.fifo.count < in_size && len(out_) > 0 {
value = this.fifo.get_value(&this.codec[i].rice)
var ret int32
outClone := out[:]
for d.fifo.count < inSize && len(outClone) > 0 {
value = d.fifo.getValue(&d.codec[i].rice)
// decompress stage 1: adaptive hybrid filter
this.codec[i].filter.Decode(&value)
d.codec[i].filter.Decode(&value)
// decompress stage 2: fixed order 1 prediction
value += ((this.codec[i].prev * ((1 << 5) - 1)) >> 5)
this.codec[i].prev = value
value += ((d.codec[i].prev * ((1 << 5) - 1)) >> 5)
d.codec[i].prev = value
cache[i] = value
if i < this.channels-1 {
if i < d.channels-1 {
i++
} else {
if this.channels == 1 {
write_buffer(value, out_, this.depth)
out_ = out_[this.depth:]
if d.channels == 1 {
writeBuffer(value, outClone, d.depth)
outClone = outClone[d.depth:]
} else {
j := i
k := i - 1
@ -172,187 +172,187 @@ func (this *Decoder) ProcessFrame(in_size uint32, out []byte) int32 {
}
cache[k] = cache[j] - cache[k]
for k <= i {
write_buffer(cache[k], out_, this.depth)
out_ = out_[this.depth:]
writeBuffer(cache[k], outClone, d.depth)
outClone = outClone[d.depth:]
k++
}
}
i = 0
this.fpos++
d.fpos++
ret++
}
if this.fpos == this.flen || this.fifo.count == in_size-4 {
if d.fpos == d.flen || d.fifo.count == inSize-4 {
// check frame crc
if !this.fifo.read_crc32() {
if !d.fifo.readCrc32() {
for i := 0; i < len(out); i++ {
out[i] = 0
}
}
// update dynamic info
this.rate = (this.fifo.count << 3) / 1070
d.rate = (d.fifo.count << 3) / 1070
break
}
}
return ret
}
func (this *Decoder) read_seek_table() bool {
if this.seek_table == nil {
func (d *Decoder) readSeekTable() bool {
if d.seekTable == nil {
return false
}
this.fifo.reset()
tmp := this.offset + uint64(this.frames+1)*4
for i := uint32(0); i < this.frames; i++ {
this.seek_table[i] = tmp
tmp += uint64(this.fifo.read_uint32())
d.fifo.reset()
tmp := d.offset + uint64(d.frames+1)*4
for i := uint32(0); i < d.frames; i++ {
d.seekTable[i] = tmp
tmp += uint64(d.fifo.readUint32())
}
return this.fifo.read_crc32()
return d.fifo.readCrc32()
}
func (this *Decoder) SetPassword(pass string) {
this.data = compute_key_digits(convert_password(pass))
this.password_set = true
func (d *Decoder) SetPassword(pass string) {
d.data = computeKeyDigits(convertPassword(pass))
d.passwordSet = true
}
func (this *Decoder) frame_init(frame uint32, seek_needed bool) (err error) {
if frame >= this.frames {
func (d *Decoder) frameInit(frame uint32, seekNeeded bool) (err error) {
if frame >= d.frames {
return
}
shift := flt_set[this.depth-1]
this.fnum = frame
if seek_needed && this.seek_allowed {
pos := this.seek_table[this.fnum]
shift := fltSet[d.depth-1]
d.fnum = frame
if seekNeeded && d.seekAllowed {
pos := d.seekTable[d.fnum]
if pos != 0 {
if _, err = this.fifo.io.Seek(int64(pos), os.SEEK_SET); err != nil {
return SEEK_ERROR
if _, err = d.fifo.io.Seek(int64(pos), os.SEEK_SET); err != nil {
return errSeek
}
}
this.fifo.read_start()
d.fifo.readStart()
}
if this.fnum == this.frames-1 {
this.flen = this.flen_last
if d.fnum == d.frames-1 {
d.flen = d.flenLast
} else {
this.flen = this.flen_std
d.flen = d.flenStd
}
for i := 0; i < this.channels; i++ {
if SSE_Enabled {
this.codec[i].filter = NewSSEFilter(this.data, shift)
for i := 0; i < d.channels; i++ {
if sseEnabled {
d.codec[i].filter = NewSSEFilter(d.data, shift)
} else {
this.codec[i].filter = NewCompatibleFilter(this.data, shift)
d.codec[i].filter = NewCompatibleFilter(d.data, shift)
}
this.codec[i].rice.init(10, 10)
this.codec[i].prev = 0
d.codec[i].rice.init(10, 10)
d.codec[i].prev = 0
}
this.fpos = 0
this.fifo.reset()
d.fpos = 0
d.fifo.reset()
return
}
func (this *Decoder) frame_reset(frame uint32, iocb io.ReadWriteSeeker) {
this.fifo.io = iocb
this.fifo.read_start()
this.frame_init(frame, false)
func (d *Decoder) frameReset(frame uint32, iocb io.ReadWriteSeeker) {
d.fifo.io = iocb
d.fifo.readStart()
d.frameInit(frame, false)
}
func (this *Decoder) set_position(seconds uint32) (new_pos uint32, err error) {
var frame uint32 = (245 * (seconds) / 256)
new_pos = (256 * (frame) / 245)
if !this.seek_allowed || frame >= this.frames {
err = SEEK_ERROR
func (d *Decoder) setPosition(seconds uint32) (newPos uint32, err error) {
var frame = (245 * (seconds) / 256)
newPos = (256 * (frame) / 245)
if !d.seekAllowed || frame >= d.frames {
err = errSeek
return
}
this.frame_init(frame, true)
d.frameInit(frame, true)
return
}
func (this *Decoder) SetInfo(info *Info) error {
func (d *Decoder) SetInfo(info *Info) error {
if info.format > 2 ||
info.bps < MIN_BPS ||
info.bps > MAX_BPS ||
info.nch > MAX_NCH {
return FORMAT_ERROR
info.bps < minBPS ||
info.bps > maxBPS ||
info.nch > maxNCH {
return errFormat
}
this.format = info.format
this.depth = (info.bps + 7) / 8
this.flen_std = (256 * (info.sps) / 245)
this.flen_last = info.samples % this.flen_std
this.frames = info.samples / this.flen_std
if this.flen_last != 0 {
this.frames += 1
d.format = info.format
d.depth = (info.bps + 7) / 8
d.flenStd = (256 * (info.sps) / 245)
d.flenLast = info.samples % d.flenStd
d.frames = info.samples / d.flenStd
if d.flenLast != 0 {
d.frames++
} else {
this.flen_last = this.flen_std
d.flenLast = d.flenStd
}
this.rate = 0
this.channels = int(info.nch)
this.fifo.read_start()
this.frame_init(0, false)
d.rate = 0
d.channels = int(info.nch)
d.fifo.readStart()
d.frameInit(0, false)
return nil
}
func (this *Decoder) ReadHeader(info *Info) (uint32, error) {
size := this.fifo.skip_id3v2()
this.fifo.reset()
if 'T' != this.fifo.read_byte() ||
'T' != this.fifo.read_byte() ||
'A' != this.fifo.read_byte() ||
'1' != this.fifo.read_byte() {
return 0, FORMAT_ERROR
func (d *Decoder) ReadHeader(info *Info) (uint32, error) {
size := d.fifo.skipId3v2()
d.fifo.reset()
if 'T' != d.fifo.readByte() ||
'T' != d.fifo.readByte() ||
'A' != d.fifo.readByte() ||
'1' != d.fifo.readByte() {
return 0, errFormat
}
info.format = uint32(this.fifo.read_uint16())
info.nch = uint32(this.fifo.read_uint16())
info.bps = uint32(this.fifo.read_uint16())
info.sps = this.fifo.read_uint32()
info.samples = this.fifo.read_uint32()
if !this.fifo.read_crc32() {
return 0, FILE_ERROR
info.format = uint32(d.fifo.readUint16())
info.nch = uint32(d.fifo.readUint16())
info.bps = uint32(d.fifo.readUint16())
info.sps = d.fifo.readUint32()
info.samples = d.fifo.readUint32()
if !d.fifo.readCrc32() {
return 0, errFile
}
size += 22
return size, nil
}
func (this *Decoder) GetInfo(info *Info, pos int64) (err error) {
func (d *Decoder) GetInfo(info *Info, pos int64) (err error) {
if pos != 0 {
if _, err = this.fifo.io.Seek(pos, os.SEEK_SET); err != nil {
err = SEEK_ERROR
if _, err = d.fifo.io.Seek(pos, os.SEEK_SET); err != nil {
err = errSeek
return
}
}
this.fifo.read_start()
d.fifo.readStart()
var p uint32
if p, err = this.ReadHeader(info); err != nil {
if p, err = d.ReadHeader(info); err != nil {
return
}
if info.format > 2 ||
info.bps < MIN_BPS ||
info.bps > MAX_BPS ||
info.nch > MAX_NCH {
return FORMAT_ERROR
info.bps < minBPS ||
info.bps > maxBPS ||
info.nch > maxNCH {
return errFormat
}
if info.format == FORMAT_ENCRYPTED {
if !this.password_set {
return PASSWORD_ERROR
if info.format == formatEncrypted {
if !d.passwordSet {
return errPassword
}
} else {
// disregard password if file is not encrypted
this.password_set = false
this.data = [8]byte{}
d.passwordSet = false
d.data = [8]byte{}
}
this.offset = uint64(pos) + uint64(p)
this.format = info.format
this.depth = (info.bps + 7) / 8
this.flen_std = (256 * (info.sps) / 245)
this.flen_last = info.samples % this.flen_std
this.frames = info.samples / this.flen_std
if this.flen_last != 0 {
this.frames += 1
d.offset = uint64(pos) + uint64(p)
d.format = info.format
d.depth = (info.bps + 7) / 8
d.flenStd = (256 * (info.sps) / 245)
d.flenLast = info.samples % d.flenStd
d.frames = info.samples / d.flenStd
if d.flenLast != 0 {
d.frames++
} else {
this.flen_last = this.flen_std
d.flenLast = d.flenStd
}
this.rate = 0
this.seek_table = make([]uint64, this.frames)
this.seek_allowed = this.read_seek_table()
this.channels = int(info.nch)
this.frame_init(0, false)
d.rate = 0
d.seekTable = make([]uint64, d.frames)
d.seekAllowed = d.readSeekTable()
d.channels = int(info.nch)
d.frameInit(0, false)
return
}

View file

@ -7,72 +7,72 @@ import (
)
type Encoder struct {
codec [MAX_NCH]tta_codec // 1 per channel
channels int // number of channels/codecs
data [8]byte // codec initialization data
fifo tta_fifo
seek_table []uint64 // the playing position table
format uint32 // tta data format
rate uint32 // bitrate (kbps)
offset uint64 // data start position (header size, bytes)
frames uint32 // total count of frames
depth uint32 // bytes per sample
flen_std uint32 // default frame length in samples
flen_last uint32 // last frame length in samples
flen uint32 // current frame length in samples
fnum uint32 // currently playing frame index
fpos uint32 // the current position in frame
shift_bits uint32 // packing int to pcm
codec [maxNCH]ttaCodec // 1 per channel
channels int // number of channels/codecs
data [8]byte // codec initialization data
fifo ttaFifo
seekTable []uint64 // the playing position table
format uint32 // tta data format
rate uint32 // bitrate (kbps)
offset uint64 // data start position (header size, bytes)
frames uint32 // total count of frames
depth uint32 // bytes per sample
flenStd uint32 // default frame length in samples
flenLast uint32 // last frame length in samples
flen uint32 // current frame length in samples
fnum uint32 // currently playing frame index
fpos uint32 // the current position in frame
shiftBits uint32 // packing int to pcm
}
func Compress(infile, outfile io.ReadWriteSeeker, passwd string, cb Callback) (err error) {
wave_hdr := WaveHeader{}
var data_size uint32
if data_size, err = wave_hdr.Read(infile); err != nil {
err = READ_ERROR
waveHdr := WaveHeader{}
var dataSize uint32
if dataSize, err = waveHdr.Read(infile); err != nil {
err = errRead
return
} else if data_size >= 0x7FFFFFFF {
err = fmt.Errorf("incorrect data size info in wav file: %x", data_size)
} else if dataSize >= 0x7FFFFFFF {
err = fmt.Errorf("incorrect data size info in wav file: %x", dataSize)
return
}
if (wave_hdr.chunk_id != _RIFF_SIGN) ||
(wave_hdr.format != _WAVE_SIGN) ||
(wave_hdr.num_channels == 0) ||
(wave_hdr.num_channels > MAX_NCH) ||
(wave_hdr.bits_per_sample == 0) ||
(wave_hdr.bits_per_sample > MAX_BPS) {
err = FORMAT_ERROR
if (waveHdr.chunkId != riffSign) ||
(waveHdr.format != waveSign) ||
(waveHdr.numChannels == 0) ||
(waveHdr.numChannels > maxNCH) ||
(waveHdr.bitsPerSample == 0) ||
(waveHdr.bitsPerSample > maxBPS) {
err = errFormat
return
}
encoder := NewEncoder(outfile)
smp_size := uint32(wave_hdr.num_channels * ((wave_hdr.bits_per_sample + 7) / 8))
smpSize := uint32(waveHdr.numChannels * ((waveHdr.bitsPerSample + 7) / 8))
info := Info{
nch: uint32(wave_hdr.num_channels),
bps: uint32(wave_hdr.bits_per_sample),
sps: wave_hdr.sample_rate,
format: FORMAT_SIMPLE,
samples: data_size / smp_size,
nch: uint32(waveHdr.numChannels),
bps: uint32(waveHdr.bitsPerSample),
sps: waveHdr.sampleRate,
format: formatSimple,
samples: dataSize / smpSize,
}
if len(passwd) > 0 {
encoder.SetPassword(passwd)
info.format = FORMAT_ENCRYPTED
info.format = formatEncrypted
}
buf_size := PCM_BUFFER_LENGTH * smp_size
buffer := make([]byte, buf_size)
bufSize := pcmBufferLength * smpSize
buffer := make([]byte, bufSize)
if err = encoder.SetInfo(&info, 0); err != nil {
return
}
var read_len int = 0
for data_size > 0 {
if buf_size >= data_size {
buf_size = data_size
var readLen int
for dataSize > 0 {
if bufSize >= dataSize {
bufSize = dataSize
}
if read_len, err = infile.Read(buffer[:buf_size]); err != nil || read_len != int(buf_size) {
err = READ_ERROR
if readLen, err = infile.Read(buffer[:bufSize]); err != nil || readLen != int(bufSize) {
err = errRead
return
}
encoder.ProcessStream(buffer[:buf_size], cb)
data_size -= buf_size
encoder.ProcessStream(buffer[:bufSize], cb)
dataSize -= bufSize
}
encoder.Close()
return
@ -84,29 +84,29 @@ func NewEncoder(iocb io.ReadWriteSeeker) *Encoder {
return &enc
}
func (this *Encoder) ProcessStream(in []byte, cb Callback) {
func (e *Encoder) ProcessStream(in []byte, cb Callback) {
if len(in) == 0 {
return
}
var res, curr, next, tmp int32
next = read_buffer(in, this.depth)
in = in[this.depth:]
tmp = next << this.shift_bits
next = readBuffer(in, e.depth)
in = in[e.depth:]
tmp = next << e.shiftBits
i := 0
index := 0
for {
curr = next
if index < len(in) {
next = read_buffer(in[index:], this.depth)
tmp = next << this.shift_bits
next = readBuffer(in[index:], e.depth)
tmp = next << e.shiftBits
} else {
next = 0
tmp = 0
}
index += int(this.depth)
index += int(e.depth)
// transform data
if this.channels > 1 {
if i < this.channels-1 {
if e.channels > 1 {
if i < e.channels-1 {
res = next - curr
curr = res
} else {
@ -115,57 +115,57 @@ func (this *Encoder) ProcessStream(in []byte, cb Callback) {
}
// compress stage 1: fixed order 1 prediction
tmp = curr
curr -= ((this.codec[i].prev * ((1 << 5) - 1)) >> 5)
this.codec[i].prev = tmp
curr -= ((e.codec[i].prev * ((1 << 5) - 1)) >> 5)
e.codec[i].prev = tmp
// compress stage 2: adaptive hybrid filter
this.codec[i].filter.Encode(&curr)
this.fifo.put_value(&this.codec[i].rice, curr)
if i < this.channels-1 {
e.codec[i].filter.Encode(&curr)
e.fifo.putValue(&e.codec[i].rice, curr)
if i < e.channels-1 {
i++
} else {
i = 0
this.fpos++
e.fpos++
}
if this.fpos == this.flen {
this.fifo.flush_bit_cache()
this.seek_table[this.fnum] = uint64(this.fifo.count)
this.fnum++
if e.fpos == e.flen {
e.fifo.flushBitCache()
e.seekTable[e.fnum] = uint64(e.fifo.count)
e.fnum++
// update dynamic info
this.rate = (this.fifo.count << 3) / 1070
e.rate = (e.fifo.count << 3) / 1070
if cb != nil {
cb(this.rate, this.fnum, this.frames)
cb(e.rate, e.fnum, e.frames)
}
this.frame_init(this.fnum)
e.frameInit(e.fnum)
}
if index >= int(this.depth)+len(in) {
if index >= int(e.depth)+len(in) {
break
}
}
}
func (this *Encoder) ProcessFrame(in []byte) {
func (e *Encoder) ProcessFrame(in []byte) {
if len(in) == 0 {
return
}
var res, curr, next, tmp int32
next = read_buffer(in, this.depth)
in = in[this.depth:]
tmp = next << this.shift_bits
next = readBuffer(in, e.depth)
in = in[e.depth:]
tmp = next << e.shiftBits
i := 0
index := 0
for {
curr = next
if index < len(in) {
next = read_buffer(in[index:], this.depth)
tmp = next << this.shift_bits
next = readBuffer(in[index:], e.depth)
tmp = next << e.shiftBits
} else {
next = 0
tmp = 0
}
index += int(this.depth)
index += int(e.depth)
// transform data
if this.channels > 1 {
if i < this.channels-1 {
if e.channels > 1 {
if i < e.channels-1 {
res = next - curr
curr = res
} else {
@ -174,113 +174,113 @@ func (this *Encoder) ProcessFrame(in []byte) {
}
// compress stage 1: fixed order 1 prediction
tmp = curr
curr -= ((this.codec[i].prev * ((1 << 5) - 1)) >> 5)
this.codec[i].prev = tmp
curr -= ((e.codec[i].prev * ((1 << 5) - 1)) >> 5)
e.codec[i].prev = tmp
// compress stage 2: adaptive hybrid filter
this.codec[i].filter.Encode(&curr)
this.fifo.put_value(&this.codec[i].rice, curr)
if i < this.channels-1 {
e.codec[i].filter.Encode(&curr)
e.fifo.putValue(&e.codec[i].rice, curr)
if i < e.channels-1 {
i++
} else {
i = 0
this.fpos++
e.fpos++
}
if this.fpos == this.flen {
this.fifo.flush_bit_cache()
if e.fpos == e.flen {
e.fifo.flushBitCache()
// update dynamic info
this.rate = (this.fifo.count << 3) / 1070
e.rate = (e.fifo.count << 3) / 1070
break
}
if index >= int(this.depth)+len(in) {
if index >= int(e.depth)+len(in) {
break
}
}
}
func (this *Encoder) write_seek_table() (err error) {
if this.seek_table == nil {
func (e *Encoder) writeSeekTable() (err error) {
if e.seekTable == nil {
return
}
if _, err = this.fifo.io.Seek(int64(this.offset), os.SEEK_SET); err != nil {
if _, err = e.fifo.io.Seek(int64(e.offset), os.SEEK_SET); err != nil {
return
}
this.fifo.write_start()
this.fifo.reset()
for i := uint32(0); i < this.frames; i++ {
this.fifo.write_uint32(uint32(this.seek_table[i] & 0xFFFFFFFF))
e.fifo.writeStart()
e.fifo.reset()
for i := uint32(0); i < e.frames; i++ {
e.fifo.writeUint32(uint32(e.seekTable[i] & 0xFFFFFFFF))
}
this.fifo.write_crc32()
this.fifo.write_done()
e.fifo.writeCrc32()
e.fifo.writeDone()
return
}
func (this *Encoder) SetPassword(pass string) {
this.data = compute_key_digits(convert_password(pass))
func (e *Encoder) SetPassword(pass string) {
e.data = computeKeyDigits(convertPassword(pass))
}
func (this *Encoder) frame_init(frame uint32) (err error) {
if frame >= this.frames {
func (e *Encoder) frameInit(frame uint32) (err error) {
if frame >= e.frames {
return
}
shift := flt_set[this.depth-1]
this.fnum = frame
if this.fnum == this.frames-1 {
this.flen = this.flen_last
shift := fltSet[e.depth-1]
e.fnum = frame
if e.fnum == e.frames-1 {
e.flen = e.flenLast
} else {
this.flen = this.flen_std
e.flen = e.flenStd
}
// init entropy encoder
for i := 0; i < this.channels; i++ {
if SSE_Enabled {
this.codec[i].filter = NewSSEFilter(this.data, shift)
for i := 0; i < e.channels; i++ {
if sseEnabled {
e.codec[i].filter = NewSSEFilter(e.data, shift)
} else {
this.codec[i].filter = NewCompatibleFilter(this.data, shift)
e.codec[i].filter = NewCompatibleFilter(e.data, shift)
}
this.codec[i].rice.init(10, 10)
this.codec[i].prev = 0
e.codec[i].rice.init(10, 10)
e.codec[i].prev = 0
}
this.fpos = 0
this.fifo.reset()
e.fpos = 0
e.fifo.reset()
return
}
func (this *Encoder) frame_reset(frame uint32, iocb io.ReadWriteSeeker) {
this.fifo.io = iocb
this.fifo.read_start()
this.frame_init(frame)
func (e *Encoder) frameReset(frame uint32, iocb io.ReadWriteSeeker) {
e.fifo.io = iocb
e.fifo.readStart()
e.frameInit(frame)
}
func (this *Encoder) WriteHeader(info *Info) (size uint32, err error) {
this.fifo.reset()
func (e *Encoder) WriteHeader(info *Info) (size uint32, err error) {
e.fifo.reset()
// write TTA1 signature
if err = this.fifo.write_byte('T'); err != nil {
if err = e.fifo.writeByte('T'); err != nil {
return
}
if err = this.fifo.write_byte('T'); err != nil {
if err = e.fifo.writeByte('T'); err != nil {
return
}
if err = this.fifo.write_byte('A'); err != nil {
if err = e.fifo.writeByte('A'); err != nil {
return
}
if err = this.fifo.write_byte('1'); err != nil {
if err = e.fifo.writeByte('1'); err != nil {
return
}
if err = this.fifo.write_uint16(uint16(info.format)); err != nil {
if err = e.fifo.writeUint16(uint16(info.format)); err != nil {
return
}
if err = this.fifo.write_uint16(uint16(info.nch)); err != nil {
if err = e.fifo.writeUint16(uint16(info.nch)); err != nil {
return
}
if err = this.fifo.write_uint16(uint16(info.bps)); err != nil {
if err = e.fifo.writeUint16(uint16(info.bps)); err != nil {
return
}
if err = this.fifo.write_uint32(info.sps); err != nil {
if err = e.fifo.writeUint32(info.sps); err != nil {
return
}
if err = this.fifo.write_uint32(info.samples); err != nil {
if err = e.fifo.writeUint32(info.samples); err != nil {
return
}
if err = this.fifo.write_crc32(); err != nil {
if err = e.fifo.writeCrc32(); err != nil {
return
}
size = 22
@ -288,50 +288,50 @@ func (this *Encoder) WriteHeader(info *Info) (size uint32, err error) {
}
func (this *Encoder) SetInfo(info *Info, pos int64) (err error) {
func (e *Encoder) SetInfo(info *Info, pos int64) (err error) {
if info.format > 2 ||
info.bps < MIN_BPS ||
info.bps > MAX_BPS ||
info.nch > MAX_NCH {
return FORMAT_ERROR
info.bps < minBPS ||
info.bps > maxBPS ||
info.nch > maxNCH {
return errFormat
}
// set start position if required
if pos != 0 {
if _, err = this.fifo.io.Seek(int64(pos), os.SEEK_SET); err != nil {
err = SEEK_ERROR
if _, err = e.fifo.io.Seek(int64(pos), os.SEEK_SET); err != nil {
err = errSeek
return
}
}
this.fifo.write_start()
e.fifo.writeStart()
var p uint32
if p, err = this.WriteHeader(info); err != nil {
if p, err = e.WriteHeader(info); err != nil {
return
}
this.offset = uint64(pos) + uint64(p)
this.format = info.format
this.depth = (info.bps + 7) / 8
this.flen_std = (256 * (info.sps) / 245)
this.flen_last = info.samples % this.flen_std
this.frames = info.samples / this.flen_std
if this.flen_last != 0 {
this.frames += 1
e.offset = uint64(pos) + uint64(p)
e.format = info.format
e.depth = (info.bps + 7) / 8
e.flenStd = (256 * (info.sps) / 245)
e.flenLast = info.samples % e.flenStd
e.frames = info.samples / e.flenStd
if e.flenLast != 0 {
e.frames++
} else {
this.flen_last = this.flen_std
e.flenLast = e.flenStd
}
this.rate = 0
this.fifo.write_skip_bytes((this.frames + 1) * 4)
this.seek_table = make([]uint64, this.frames)
this.channels = int(info.nch)
this.shift_bits = (4 - this.depth) << 3
this.frame_init(0)
e.rate = 0
e.fifo.writeSkipBytes((e.frames + 1) * 4)
e.seekTable = make([]uint64, e.frames)
e.channels = int(info.nch)
e.shiftBits = (4 - e.depth) << 3
e.frameInit(0)
return
}
func (this *Encoder) Close() {
this.Finalize()
func (e *Encoder) Close() {
e.Finalize()
}
func (this *Encoder) Finalize() {
this.fifo.write_done()
this.write_seek_table()
func (e *Encoder) Finalize() {
e.fifo.writeDone()
e.writeSeekTable()
}

142
fifo.go
View file

@ -1,84 +1,84 @@
package tta
func (s *tta_fifo) read_byte() (v byte) {
func (s *ttaFifo) readByte() (v byte) {
if s.pos >= s.end {
v, _ := s.io.Read(s.buffer[:]) // FIXME: handle this error
s.end = int32(v)
s.pos = 0
}
s.crc = crc32_table[(s.crc^uint32(s.buffer[s.pos]))&0xFF] ^ (s.crc >> 8)
s.crc = crc32Table[(s.crc^uint32(s.buffer[s.pos]))&0xFF] ^ (s.crc >> 8)
s.count++
v = s.buffer[s.pos]
s.pos++
return
}
func (s *tta_fifo) read_uint16() (v uint16) {
func (s *ttaFifo) readUint16() (v uint16) {
v = 0
v |= uint16(s.read_byte())
v |= uint16(s.read_byte()) << 8
v |= uint16(s.readByte())
v |= uint16(s.readByte()) << 8
return
}
func (s *tta_fifo) read_uint32() (v uint32) {
func (s *ttaFifo) readUint32() (v uint32) {
v = 0
v |= uint32(s.read_byte())
v |= uint32(s.read_byte()) << 8
v |= uint32(s.read_byte()) << 16
v |= uint32(s.read_byte()) << 24
v |= uint32(s.readByte())
v |= uint32(s.readByte()) << 8
v |= uint32(s.readByte()) << 16
v |= uint32(s.readByte()) << 24
return
}
func (s *tta_fifo) read_crc32() bool {
func (s *ttaFifo) readCrc32() bool {
crc := s.crc ^ 0xFFFFFFFF
return crc == s.read_uint32()
return crc == s.readUint32()
}
func (s *tta_fifo) read_start() {
func (s *ttaFifo) readStart() {
s.pos = s.end
}
func (s *tta_fifo) reset() {
func (s *ttaFifo) reset() {
s.crc = 0xFFFFFFFF
s.bcache = 0
s.bcount = 0
s.count = 0
}
func (s *tta_fifo) read_skip_bytes(size uint32) {
func (s *ttaFifo) readSkipBytes(size uint32) {
for size > 0 {
size--
s.read_byte()
s.readByte()
}
}
func (s *tta_fifo) skip_id3v2() (size uint32) {
func (s *ttaFifo) skipId3v2() (size uint32) {
s.reset()
if 'I' != s.read_byte() || 'D' != s.read_byte() || '3' != s.read_byte() {
if 'I' != s.readByte() || 'D' != s.readByte() || '3' != s.readByte() {
s.pos = 0
return 0
}
s.pos += 2 // skip version bytes
if s.read_byte()&0x10 != 0 {
if s.readByte()&0x10 != 0 {
size += 10
}
size += uint32(s.read_byte() & 0x7F)
size = (size << 7) | uint32(s.read_byte()&0x7F)
size = (size << 7) | uint32(s.read_byte()&0x7F)
size = (size << 7) | uint32(s.read_byte()&0x7F)
s.read_skip_bytes(size)
size += uint32(s.readByte() & 0x7F)
size = (size << 7) | uint32(s.readByte()&0x7F)
size = (size << 7) | uint32(s.readByte()&0x7F)
size = (size << 7) | uint32(s.readByte()&0x7F)
s.readSkipBytes(size)
size += 10
return
}
func (s *tta_fifo) get_value(rice *tta_adapt) (value int32) {
if s.bcache^bit_mask[s.bcount] == 0 {
func (s *ttaFifo) getValue(rice *ttaAdapt) (value int32) {
if s.bcache^bitMask[s.bcount] == 0 {
value += int32(s.bcount)
s.bcache = uint32(s.read_byte())
s.bcache = uint32(s.readByte())
s.bcount = 8
for s.bcache == 0xFF {
value += 8
s.bcache = uint32(s.read_byte())
s.bcache = uint32(s.readByte())
}
}
@ -101,29 +101,29 @@ func (s *tta_fifo) get_value(rice *tta_adapt) (value int32) {
}
if k != 0 {
for s.bcount < k {
tmp = uint32(s.read_byte())
tmp = uint32(s.readByte())
s.bcache |= tmp << s.bcount
s.bcount += 8
}
value = (value << k) + int32(s.bcache&bit_mask[k])
value = (value << k) + int32(s.bcache&bitMask[k])
s.bcache >>= k
s.bcount -= k
s.bcache &= bit_mask[s.bcount]
s.bcache &= bitMask[s.bcount]
}
if level != 0 {
rice.sum1 += uint32(value) - (rice.sum1 >> 4)
if rice.k1 > 0 && rice.sum1 < shift_16[rice.k1] {
if rice.k1 > 0 && rice.sum1 < shift16[rice.k1] {
rice.k1--
} else if rice.sum1 > shift_16[rice.k1+1] {
} else if rice.sum1 > shift16[rice.k1+1] {
rice.k1++
}
value += int32(bit_shift[rice.k0])
value += int32(bitShift[rice.k0])
}
rice.sum0 += uint32(value) - (rice.sum0 >> 4)
if rice.k0 > 0 && rice.sum0 < shift_16[rice.k0] {
if rice.k0 > 0 && rice.sum0 < shift16[rice.k0] {
rice.k0--
} else if rice.sum0 > shift_16[rice.k0+1] {
} else if rice.sum0 > shift16[rice.k0+1] {
rice.k0++
}
// ((x & 1)?((x + 1) >> 1):(-x >> 1))
@ -135,64 +135,64 @@ func (s *tta_fifo) get_value(rice *tta_adapt) (value int32) {
return
}
func (s *tta_fifo) write_start() {
func (s *ttaFifo) writeStart() {
s.pos = 0
}
func (s *tta_fifo) write_done() error {
func (s *ttaFifo) writeDone() error {
if s.pos > 0 {
if n, err := s.io.Write(s.buffer[:s.pos]); err != nil || n != int(s.pos) {
return WRITE_ERROR
return errWrite
}
s.pos = 0
}
return nil
}
func (s *tta_fifo) write_byte(v byte) error {
if s.pos == FIFO_BUFFER_SIZE {
if n, err := s.io.Write(s.buffer[:]); err != nil || n != FIFO_BUFFER_SIZE {
return WRITE_ERROR
func (s *ttaFifo) writeByte(v byte) error {
if s.pos == fifoBufferSize {
if n, err := s.io.Write(s.buffer[:]); err != nil || n != fifoBufferSize {
return errWrite
}
s.pos = 0
}
s.crc = crc32_table[(s.crc^uint32(v))&0xFF] ^ (s.crc >> 8)
s.crc = crc32Table[(s.crc^uint32(v))&0xFF] ^ (s.crc >> 8)
s.count++
s.buffer[s.pos] = v
s.pos++
return nil
}
func (s *tta_fifo) write_uint16(v uint16) error {
if err := s.write_byte(byte(v)); err != nil {
func (s *ttaFifo) writeUint16(v uint16) error {
if err := s.writeByte(byte(v)); err != nil {
return err
}
if err := s.write_byte(byte(v >> 8)); err != nil {
if err := s.writeByte(byte(v >> 8)); err != nil {
return err
}
return nil
}
func (s *tta_fifo) write_uint32(v uint32) error {
if err := s.write_byte(byte(v)); err != nil {
func (s *ttaFifo) writeUint32(v uint32) error {
if err := s.writeByte(byte(v)); err != nil {
return err
}
if err := s.write_byte(byte(v >> 8)); err != nil {
if err := s.writeByte(byte(v >> 8)); err != nil {
return err
}
if err := s.write_byte(byte(v >> 16)); err != nil {
if err := s.writeByte(byte(v >> 16)); err != nil {
return err
}
return s.write_byte(byte(v >> 24))
return s.writeByte(byte(v >> 24))
}
func (s *tta_fifo) write_crc32() error {
return s.write_uint32(s.crc ^ 0xFFFFFFFF)
func (s *ttaFifo) writeCrc32() error {
return s.writeUint32(s.crc ^ 0xFFFFFFFF)
}
func (s *tta_fifo) write_skip_bytes(size uint32) error {
func (s *ttaFifo) writeSkipBytes(size uint32) error {
for size > 0 {
if err := s.write_byte(0); err != nil {
if err := s.writeByte(0); err != nil {
return err
}
size--
@ -200,7 +200,7 @@ func (s *tta_fifo) write_skip_bytes(size uint32) error {
return nil
}
func (s *tta_fifo) put_value(rice *tta_adapt, value int32) {
func (s *ttaFifo) putValue(rice *ttaAdapt, value int32) {
var k, unary, outval uint32
if value > 0 {
outval = (uint32(value) << 1) - 1
@ -210,19 +210,19 @@ func (s *tta_fifo) put_value(rice *tta_adapt, value int32) {
// encode Rice unsigned
k = rice.k0
rice.sum0 += outval - (rice.sum0 >> 4)
if rice.k0 > 0 && rice.sum0 < shift_16[rice.k0] {
if rice.k0 > 0 && rice.sum0 < shift16[rice.k0] {
rice.k0--
} else if rice.sum0 > shift_16[rice.k0+1] {
} else if rice.sum0 > shift16[rice.k0+1] {
rice.k0++
}
if outval >= bit_shift[k] {
outval -= bit_shift[k]
if outval >= bitShift[k] {
outval -= bitShift[k]
k = rice.k1
rice.sum1 += outval - (rice.sum1 >> 4)
if rice.k1 > 0 && rice.sum1 < shift_16[rice.k1] {
if rice.k1 > 0 && rice.sum1 < shift16[rice.k1] {
rice.k1--
} else if rice.sum1 > shift_16[rice.k1+1] {
} else if rice.sum1 > shift16[rice.k1+1] {
rice.k1++
}
unary = 1 + (outval >> k)
@ -232,16 +232,16 @@ func (s *tta_fifo) put_value(rice *tta_adapt, value int32) {
for { // put unary
for s.bcount >= 8 {
s.write_byte(byte(s.bcache))
s.writeByte(byte(s.bcache))
s.bcache >>= 8
s.bcount -= 8
}
if unary > 23 {
s.bcache |= bit_mask[23] << s.bcount
s.bcache |= bitMask[23] << s.bcount
s.bcount += 23
unary -= 23
} else {
s.bcache |= bit_mask[unary] << s.bcount
s.bcache |= bitMask[unary] << s.bcount
s.bcount += unary + 1
unary = 0
}
@ -250,19 +250,19 @@ func (s *tta_fifo) put_value(rice *tta_adapt, value int32) {
}
}
for s.bcount >= 8 { // put binary
s.write_byte(byte(s.bcache))
s.writeByte(byte(s.bcache))
s.bcache >>= 8
s.bcount -= 8
}
if k != 0 {
s.bcache |= (outval & bit_mask[k]) << s.bcount
s.bcache |= (outval & bitMask[k]) << s.bcount
s.bcount += k
}
}
func (s *tta_fifo) flush_bit_cache() {
func (s *ttaFifo) flushBitCache() {
for s.bcount > 0 {
s.write_byte(byte(s.bcache))
s.writeByte(byte(s.bcache))
s.bcache >>= 8
if s.bcount > 8 {
s.bcount -= 8
@ -270,5 +270,5 @@ func (s *tta_fifo) flush_bit_cache() {
break
}
}
s.write_crc32()
s.writeCrc32()
}

View file

@ -5,106 +5,106 @@ import (
)
func TestReadByte(t *testing.T) {
fifo := tta_fifo{}
for i := 0; i < FIFO_BUFFER_SIZE; i++ {
fifo := ttaFifo{}
for i := 0; i < fifoBufferSize; i++ {
fifo.buffer[i] = byte(i)
}
fifo.pos = 0
fifo.end = FIFO_BUFFER_SIZE
for i := 0; i < FIFO_BUFFER_SIZE; i++ {
if fifo.read_byte() != byte(i&0xFF) {
t.Errorf("read_byte fail @ %d\n", i)
fifo.end = fifoBufferSize
for i := 0; i < fifoBufferSize; i++ {
if fifo.readByte() != byte(i&0xFF) {
t.Errorf("readByte fail @ %d\n", i)
}
if fifo.count != uint32(i+1) {
t.Errorf("read_byte fail @ count - %d\n", i)
t.Errorf("readByte fail @ count - %d\n", i)
}
if fifo.pos != int32(i+1) {
t.Errorf("read_byte fail @ pos - %d\n", i)
t.Errorf("readByte fail @ pos - %d\n", i)
}
}
if fifo.count != FIFO_BUFFER_SIZE {
t.Error("read_byte fail @ count")
if fifo.count != fifoBufferSize {
t.Error("readByte fail @ count")
}
if fifo.pos != FIFO_BUFFER_SIZE {
t.Error("read_byte fail @ pos")
if fifo.pos != fifoBufferSize {
t.Error("readByte fail @ pos")
}
}
func TestReadUint16(t *testing.T) {
fifo := tta_fifo{}
for i := 0; i < FIFO_BUFFER_SIZE; i++ {
fifo := ttaFifo{}
for i := 0; i < fifoBufferSize; i++ {
fifo.buffer[i] = byte(i)
}
fifo.pos = 0
fifo.end = FIFO_BUFFER_SIZE
fifo.end = fifoBufferSize
var v uint16
for i := 0; i < FIFO_BUFFER_SIZE/2; i++ {
for i := 0; i < fifoBufferSize/2; i++ {
v = uint16((i*2+1)<<8) | (uint16(i*2) & 0xFF)
if fifo.read_uint16() != v {
t.Errorf("read_uint16 fail @ %d\n", i)
if fifo.readUint16() != v {
t.Errorf("readUint16 fail @ %d\n", i)
}
if fifo.count != uint32(i*2+2) {
t.Errorf("read_uint16 fail @ count - %d\n", i)
t.Errorf("readUint16 fail @ count - %d\n", i)
}
if fifo.pos != int32(i*2+2) {
t.Errorf("read_uint16 fail @ pos - %d\n", i)
t.Errorf("readUint16 fail @ pos - %d\n", i)
}
}
if fifo.count != FIFO_BUFFER_SIZE {
t.Error("read_uint16 fail @ count")
if fifo.count != fifoBufferSize {
t.Error("readUint16 fail @ count")
}
if fifo.pos != FIFO_BUFFER_SIZE {
t.Error("read_uint16 fail @ pos")
if fifo.pos != fifoBufferSize {
t.Error("readUint16 fail @ pos")
}
}
func TestReadUint32(t *testing.T) {
fifo := tta_fifo{}
for i := 0; i < FIFO_BUFFER_SIZE; i++ {
fifo := ttaFifo{}
for i := 0; i < fifoBufferSize; i++ {
fifo.buffer[i] = byte(i)
}
fifo.pos = 0
fifo.end = FIFO_BUFFER_SIZE
fifo.end = fifoBufferSize
var v uint32
for i := 0; i < FIFO_BUFFER_SIZE/4; i++ {
for i := 0; i < fifoBufferSize/4; i++ {
if fifo.count != uint32(i*4) {
t.Errorf("read_uint32 fail @ count - %d\n", i)
t.Errorf("readUint32 fail @ count - %d\n", i)
}
if fifo.pos != int32(i*4) {
t.Errorf("read_uint32 fail @ pos - %d\n", i)
t.Errorf("readUint32 fail @ pos - %d\n", i)
}
v = uint32((i*4+3)<<24&0xFF000000) | uint32((i*4+2)<<16&0xFF0000) | uint32((i*4+1)<<8&0xFF00) | (uint32(i*4) & 0xFF)
if fifo.read_uint32() != v {
t.Errorf("read_uint32 fail @ %d\n", i)
if fifo.readUint32() != v {
t.Errorf("readUint32 fail @ %d\n", i)
}
}
if fifo.count != FIFO_BUFFER_SIZE {
t.Error("read_uint32 fail @ count")
if fifo.count != fifoBufferSize {
t.Error("readUint32 fail @ count")
}
if fifo.pos != FIFO_BUFFER_SIZE {
t.Error("read_uint32 fail @ pos")
if fifo.pos != fifoBufferSize {
t.Error("readUint32 fail @ pos")
}
}
func TestWriteByte(t *testing.T) {
fifo := tta_fifo{}
fifo := ttaFifo{}
fifo.pos = 0
fifo.end = FIFO_BUFFER_SIZE
for i := 0; i < FIFO_BUFFER_SIZE; i++ {
if err := fifo.write_byte(byte(i)); err != nil {
t.Errorf("write_byte fail @ %d, %v\n", i, err)
fifo.end = fifoBufferSize
for i := 0; i < fifoBufferSize; i++ {
if err := fifo.writeByte(byte(i)); err != nil {
t.Errorf("writeByte fail @ %d, %v\n", i, err)
}
if fifo.count != uint32(i+1) {
t.Errorf("write_byte fail @ count - %d\n", i)
t.Errorf("writeByte fail @ count - %d\n", i)
}
if fifo.pos != int32(i+1) {
t.Errorf("write_byte fail @ pos - %d\n", i)
t.Errorf("writeByte fail @ pos - %d\n", i)
}
}
if fifo.count != FIFO_BUFFER_SIZE {
t.Error("write_byte fail @ count")
if fifo.count != fifoBufferSize {
t.Error("writeByte fail @ count")
}
if fifo.pos != FIFO_BUFFER_SIZE {
t.Error("write_byte fail @ pos")
if fifo.pos != fifoBufferSize {
t.Error("writeByte fail @ pos")
}
}

View file

@ -1,27 +1,28 @@
// TODO: SSE4 optimization
package tta
// TODO: SSE4 optimization
func NewCompatibleFilter(data [8]byte, shift int32) Filter {
this := tta_filter_compat{}
this.shift = shift
this.round = 1 << uint32(shift-1)
this.qm[0] = int32(int8(data[0]))
this.qm[1] = int32(int8(data[1]))
this.qm[2] = int32(int8(data[2]))
this.qm[3] = int32(int8(data[3]))
this.qm[4] = int32(int8(data[4]))
this.qm[5] = int32(int8(data[5]))
this.qm[6] = int32(int8(data[6]))
this.qm[7] = int32(int8(data[7]))
return &this
t := ttaFilterCompat{}
t.shift = shift
t.round = 1 << uint32(shift-1)
t.qm[0] = int32(int8(data[0]))
t.qm[1] = int32(int8(data[1]))
t.qm[2] = int32(int8(data[2]))
t.qm[3] = int32(int8(data[3]))
t.qm[4] = int32(int8(data[4]))
t.qm[5] = int32(int8(data[5]))
t.qm[6] = int32(int8(data[6]))
t.qm[7] = int32(int8(data[7]))
return &t
}
func (this *tta_filter_compat) Decode(in *int32) {
pa := this.dl[:]
pb := this.qm[:]
pm := this.dx[:]
sum := this.round
if this.error < 0 {
func (t *ttaFilterCompat) Decode(in *int32) {
pa := t.dl[:]
pb := t.qm[:]
pm := t.dx[:]
sum := t.round
if t.error < 0 {
pb[0] -= pm[0]
pb[1] -= pm[1]
pb[2] -= pm[2]
@ -30,7 +31,7 @@ func (this *tta_filter_compat) Decode(in *int32) {
pb[5] -= pm[5]
pb[6] -= pm[6]
pb[7] -= pm[7]
} else if this.error > 0 {
} else if t.error > 0 {
pb[0] += pm[0]
pb[1] += pm[1]
pb[2] += pm[2]
@ -56,8 +57,8 @@ func (this *tta_filter_compat) Decode(in *int32) {
pm[5] = ((pa[5] >> 30) | 2) & ^1
pm[6] = ((pa[6] >> 30) | 2) & ^1
pm[7] = ((pa[7] >> 30) | 4) & ^3
this.error = *in
*in += (sum >> uint32(this.shift))
t.error = *in
*in += (sum >> uint32(t.shift))
pa[4] = -pa[5]
pa[5] = -pa[6]
pa[6] = *in - pa[7]
@ -66,12 +67,12 @@ func (this *tta_filter_compat) Decode(in *int32) {
pa[4] += pa[5]
}
func (this *tta_filter_compat) Encode(in *int32) {
pa := this.dl[:]
pb := this.qm[:]
pm := this.dx[:]
sum := this.round
if this.error < 0 {
func (t *ttaFilterCompat) Encode(in *int32) {
pa := t.dl[:]
pb := t.qm[:]
pm := t.dx[:]
sum := t.round
if t.error < 0 {
pb[0] -= pm[0]
pb[1] -= pm[1]
pb[2] -= pm[2]
@ -80,7 +81,7 @@ func (this *tta_filter_compat) Encode(in *int32) {
pb[5] -= pm[5]
pb[6] -= pm[6]
pb[7] -= pm[7]
} else if this.error > 0 {
} else if t.error > 0 {
pb[0] += pm[0]
pb[1] += pm[1]
pb[2] += pm[2]
@ -115,27 +116,27 @@ func (this *tta_filter_compat) Encode(in *int32) {
pa[5] += pa[6]
pa[4] += pa[5]
*in -= (sum >> uint32(this.shift))
this.error = *in
*in -= (sum >> uint32(t.shift))
t.error = *in
}
func NewSSEFilter(data [8]byte, shift int32) Filter {
this := tta_filter_sse{}
this.shift = shift
this.round = 1 << uint32(shift-1)
this.qm[0] = int32(int8(data[0]))
this.qm[1] = int32(int8(data[1]))
this.qm[2] = int32(int8(data[2]))
this.qm[3] = int32(int8(data[3]))
this.qm[4] = int32(int8(data[4]))
this.qm[5] = int32(int8(data[5]))
this.qm[6] = int32(int8(data[6]))
this.qm[7] = int32(int8(data[7]))
return &this
t := ttaFilterSse{}
t.shift = shift
t.round = 1 << uint32(shift-1)
t.qm[0] = int32(int8(data[0]))
t.qm[1] = int32(int8(data[1]))
t.qm[2] = int32(int8(data[2]))
t.qm[3] = int32(int8(data[3]))
t.qm[4] = int32(int8(data[4]))
t.qm[5] = int32(int8(data[5]))
t.qm[6] = int32(int8(data[6]))
t.qm[7] = int32(int8(data[7]))
return &t
}
func (this *tta_filter_sse) Decode(in *int32) {
func (t *ttaFilterSse) Decode(in *int32) {
}
func (this *tta_filter_sse) Encode(in *int32) {
func (t *ttaFilterSse) Encode(in *int32) {
}

20
tta.go
View file

@ -17,7 +17,7 @@ type Filter interface {
Encode(*int32)
}
type tta_filter_compat struct {
type ttaFilterCompat struct {
index int32
error int32
round int32
@ -27,30 +27,30 @@ type tta_filter_compat struct {
dl [24]int32
}
type tta_filter_sse tta_filter_compat
type ttaFilterSse ttaFilterCompat
type tta_adapt struct {
type ttaAdapt struct {
k0 uint32
k1 uint32
sum0 uint32
sum1 uint32
}
func (rice *tta_adapt) init(k0, k1 uint32) {
func (rice *ttaAdapt) init(k0, k1 uint32) {
rice.k0 = k0
rice.k1 = k1
rice.sum0 = shift_16[k0]
rice.sum1 = shift_16[k1]
rice.sum0 = shift16[k0]
rice.sum1 = shift16[k1]
}
type tta_codec struct {
type ttaCodec struct {
filter Filter
rice tta_adapt
rice ttaAdapt
prev int32
}
type tta_fifo struct {
buffer [FIFO_BUFFER_SIZE]byte
type ttaFifo struct {
buffer [fifoBufferSize]byte
pos int32
end int32
bcount uint32 // count of bits in cache

42
util.go
View file

@ -5,34 +5,34 @@ import (
)
func BinaryVersion() byte {
if SSE_Enabled {
return CPU_ARCH_IX86_SSE4_1
if sseEnabled {
return cpuArchIx86Sse4_1
}
return CPU_ARCH_UNDEFINED
return cpuArchUndefined
}
func compute_key_digits(p []byte) [8]byte {
var crc_lo, crc_hi uint32 = 0xFFFFFFFF, 0xFFFFFFFF
func computeKeyDigits(p []byte) [8]byte {
var crcLow, crcHigh uint32 = 0xFFFFFFFF, 0xFFFFFFFF
for i := 0; i < len(p); i++ {
index := (crc_hi >> 24) ^ uint32(p[i])&0xFF
crc_hi = crc64_table_hi[index] ^ ((crc_hi << 8) | (crc_lo >> 24))
crc_lo = crc64_table_lo[index] ^ (crc_lo << 8)
index := (crcHigh >> 24) ^ uint32(p[i])&0xFF
crcHigh = crc64TableHigh[index] ^ ((crcHigh << 8) | (crcLow >> 24))
crcLow = crc64TableLow[index] ^ (crcLow << 8)
}
crc_lo ^= 0xFFFFFFFF
crc_hi ^= 0xFFFFFFFF
crcLow ^= 0xFFFFFFFF
crcHigh ^= 0xFFFFFFFF
return [8]byte{
byte((crc_lo) & 0xFF),
byte((crc_lo >> 8) & 0xFF),
byte((crc_lo >> 16) & 0xFF),
byte((crc_lo >> 24) & 0xFF),
byte((crc_hi) & 0xFF),
byte((crc_hi >> 8) & 0xFF),
byte((crc_hi >> 16) & 0xFF),
byte((crc_hi >> 24) & 0xFF),
byte((crcLow) & 0xFF),
byte((crcLow >> 8) & 0xFF),
byte((crcLow >> 16) & 0xFF),
byte((crcLow >> 24) & 0xFF),
byte((crcHigh) & 0xFF),
byte((crcHigh >> 8) & 0xFF),
byte((crcHigh >> 16) & 0xFF),
byte((crcHigh >> 24) & 0xFF),
}
}
func convert_password(src string) []byte {
func convertPassword(src string) []byte {
dst := make([]byte, len(src))
for i := 0; i < len(src); i++ {
if src[i]&0xF0 == 0xF0 {
@ -50,7 +50,7 @@ func convert_password(src string) []byte {
return dst
}
func write_buffer(src int32, p []byte, depth uint32) {
func writeBuffer(src int32, p []byte, depth uint32) {
switch depth {
case 2:
binary.LittleEndian.PutUint16(p, uint16(0xFFFF&src))
@ -61,7 +61,7 @@ func write_buffer(src int32, p []byte, depth uint32) {
}
}
func read_buffer(p []byte, depth uint32) (v int32) {
func readBuffer(p []byte, depth uint32) (v int32) {
switch depth {
case 2:
v = int32(int16(binary.LittleEndian.Uint16(p)))

View file

@ -8,17 +8,17 @@ import (
func TestComputeKeyDigits(t *testing.T) {
var strs = [...]string{"whatisthis?", "1", "", "12", "089q3eoib*(*U(*#$", "~*)(*)@&("}
var digits = [...][8]byte{
[8]byte{37, 121, 62, 136, 117, 151, 236, 181},
[8]byte{90, 13, 77, 214, 205, 142, 75, 114},
[8]byte{0, 0, 0, 0, 0, 0, 0, 0},
[8]byte{215, 206, 228, 105, 229, 41, 119, 11},
[8]byte{35, 135, 48, 205, 86, 61, 214, 216},
[8]byte{112, 92, 200, 162, 200, 114, 105, 141},
{37, 121, 62, 136, 117, 151, 236, 181},
{90, 13, 77, 214, 205, 142, 75, 114},
{0, 0, 0, 0, 0, 0, 0, 0},
{215, 206, 228, 105, 229, 41, 119, 11},
{35, 135, 48, 205, 86, 61, 214, 216},
{112, 92, 200, 162, 200, 114, 105, 141},
}
for i := 0; i < len(strs); i++ {
b := compute_key_digits([]byte(strs[i]))
b := computeKeyDigits([]byte(strs[i]))
if bytes.Compare(b[:], digits[i][:]) != 0 {
t.Errorf("compute_key_digits fail @ %d\n", i)
t.Errorf("computeKeyDigits fail @ %d\n", i)
}
}
}
@ -30,13 +30,13 @@ func TestConvertPassword(t *testing.T) {
"AB",
"akljsdlfkja;oslduy 98283r7 qiweyr9823475&@^#U#$Y$"}
var slices = [...][]byte{
[]byte{},
[]byte{49},
[]byte{65, 66},
[]byte{97, 107, 108, 106, 115, 100, 108, 102, 107, 106, 97, 59, 111, 115, 108, 100, 117, 121, 32, 57, 56, 50, 56, 51, 114, 55, 32, 32, 113, 105, 119, 101, 121, 114, 57, 56, 50, 51, 52, 55, 53, 38, 64, 94, 35, 85, 35, 36, 89, 36}}
{},
{49},
{65, 66},
{97, 107, 108, 106, 115, 100, 108, 102, 107, 106, 97, 59, 111, 115, 108, 100, 117, 121, 32, 57, 56, 50, 56, 51, 114, 55, 32, 32, 113, 105, 119, 101, 121, 114, 57, 56, 50, 51, 52, 55, 53, 38, 64, 94, 35, 85, 35, 36, 89, 36}}
for i := 0; i < len(strs); i++ {
if bytes.Compare(slices[i], convert_password(strs[i])) != 0 {
t.Errorf("convert_password fail @ %v\n", strs[i])
if bytes.Compare(slices[i], convertPassword(strs[i])) != 0 {
t.Errorf("convertPassword fail @ %v\n", strs[i])
}
}
}

130
wav.go
View file

@ -8,39 +8,39 @@ import (
)
const (
_RIFF_SIGN = 0x46464952
_WAVE_SIGN = 0x45564157
_FMT_SIGN = 0x20746D66
_DATA_SIGN = 0x61746164
riffSign = 0x46464952
waveSign = 0x45564157
fmtSign = 0x20746D66
dataSign = 0x61746164
_WAVE_FORMAT_PCM = 1
_WAVE_FORMAT_EXTENSIBLE = 0xFFFE
waveFormatPcm = 1
waveFormatExtensible = 0xFFFE
)
type WaveHeader struct {
chunk_id uint32
chunk_size uint32
format uint32
subchunk_id uint32
subchunk_size uint32
audio_format uint16
num_channels uint16
sample_rate uint32
byte_rate uint32
block_align uint16
bits_per_sample uint16
chunkId uint32
chunkSize uint32
format uint32
subchunkId uint32
subchunkSize uint32
audioFormat uint16
numChannels uint16
sampleRate uint32
byteRate uint32
blockAlign uint16
bitsPerSample uint16
}
type WaveSubchunkHeader struct {
subchunk_id uint32
subchunk_size uint32
subchunkId uint32
subchunkSize uint32
}
type WaveExtHeader struct {
cb_size uint16
valid_bits uint16
ch_mask uint32
est struct {
cbSize uint16
validBits uint16
chMask uint32
est struct {
f1 uint32
f2 uint16
f3 uint16
@ -48,99 +48,99 @@ type WaveExtHeader struct {
} // WaveSubformat
}
func (this *WaveHeader) Bytes() []byte {
size := int(unsafe.Sizeof(*this))
func (w *WaveHeader) Bytes() []byte {
size := int(unsafe.Sizeof(*w))
return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(this)),
Data: uintptr(unsafe.Pointer(w)),
Len: size,
Cap: size,
}))
}
func (this *WaveSubchunkHeader) Bytes() []byte {
size := int(unsafe.Sizeof(*this))
func (w *WaveSubchunkHeader) Bytes() []byte {
size := int(unsafe.Sizeof(*w))
return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(this)),
Data: uintptr(unsafe.Pointer(w)),
Len: size,
Cap: size,
}))
}
func (this *WaveExtHeader) Bytes() []byte {
size := int(unsafe.Sizeof(*this))
func (w *WaveExtHeader) Bytes() []byte {
size := int(unsafe.Sizeof(*w))
return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(this)),
Data: uintptr(unsafe.Pointer(w)),
Len: size,
Cap: size,
}))
}
func (this *WaveHeader) Read(fd io.ReadSeeker) (subchunk_size uint32, err error) {
var default_subchunk_size uint32 = 16
b := this.Bytes()
var read_len int
func (w *WaveHeader) Read(fd io.ReadSeeker) (subchunkSize uint32, err error) {
var defaultSubchunkSize uint32 = 16
b := w.Bytes()
var readLen int
// Read WAVE header
if read_len, err = fd.Read(b); err != nil {
if readLen, err = fd.Read(b); err != nil {
return
} else if read_len != len(b) {
err = PARTIAL_READ_ERROR
} else if readLen != len(b) {
err = errPartialRead
return
}
if this.audio_format == _WAVE_FORMAT_EXTENSIBLE {
wave_hdr_ex := WaveExtHeader{}
if read_len, err = fd.Read(wave_hdr_ex.Bytes()); err != nil {
if w.audioFormat == waveFormatExtensible {
waveHdrEx := WaveExtHeader{}
if readLen, err = fd.Read(waveHdrEx.Bytes()); err != nil {
return
} else if read_len != int(unsafe.Sizeof(wave_hdr_ex)) {
err = PARTIAL_READ_ERROR
} else if readLen != int(unsafe.Sizeof(waveHdrEx)) {
err = errPartialRead
return
}
default_subchunk_size += uint32(unsafe.Sizeof(wave_hdr_ex))
this.audio_format = uint16(wave_hdr_ex.est.f1)
defaultSubchunkSize += uint32(unsafe.Sizeof(waveHdrEx))
w.audioFormat = uint16(waveHdrEx.est.f1)
}
// Skip extra format bytes
if this.subchunk_size > default_subchunk_size {
extra_len := this.subchunk_size - default_subchunk_size
if _, err = fd.Seek(int64(extra_len), os.SEEK_SET); err != nil {
if w.subchunkSize > defaultSubchunkSize {
extraLen := w.subchunkSize - defaultSubchunkSize
if _, err = fd.Seek(int64(extraLen), os.SEEK_SET); err != nil {
return
}
}
// Skip unsupported chunks
subchunk_hdr := WaveSubchunkHeader{}
subchunkHdr := WaveSubchunkHeader{}
for {
if read_len, err = fd.Read(subchunk_hdr.Bytes()); err != nil {
if readLen, err = fd.Read(subchunkHdr.Bytes()); err != nil {
return
} else if read_len != int(unsafe.Sizeof(subchunk_hdr)) {
err = PARTIAL_READ_ERROR
} else if readLen != int(unsafe.Sizeof(subchunkHdr)) {
err = errPartialRead
return
}
if subchunk_hdr.subchunk_id == _DATA_SIGN {
if subchunkHdr.subchunkId == dataSign {
break
}
if _, err = fd.Seek(int64(subchunk_hdr.subchunk_size), os.SEEK_SET); err != nil {
if _, err = fd.Seek(int64(subchunkHdr.subchunkSize), os.SEEK_SET); err != nil {
return
}
}
subchunk_size = subchunk_hdr.subchunk_size
subchunkSize = subchunkHdr.subchunkSize
return
}
func (this *WaveHeader) Write(fd io.Writer, size uint32) (err error) {
var write_len int
func (w *WaveHeader) Write(fd io.Writer, size uint32) (err error) {
var writeLen int
// Write WAVE header
if write_len, err = fd.Write(this.Bytes()); err != nil {
if writeLen, err = fd.Write(w.Bytes()); err != nil {
return
} else if write_len != int(unsafe.Sizeof(*this)) {
err = PARTIAL_WRITTEN_ERROR
} else if writeLen != int(unsafe.Sizeof(*w)) {
err = errPartialWritten
return
}
// Write Subchunk header
subchunk_hdr := WaveSubchunkHeader{_DATA_SIGN, size}
if write_len, err = fd.Write(subchunk_hdr.Bytes()); err != nil {
subchunkHdr := WaveSubchunkHeader{dataSign, size}
if writeLen, err = fd.Write(subchunkHdr.Bytes()); err != nil {
return
} else if write_len != int(unsafe.Sizeof(subchunk_hdr)) {
err = PARTIAL_WRITTEN_ERROR
} else if writeLen != int(unsafe.Sizeof(subchunkHdr)) {
err = errPartialWritten
return
}
return

View file

@ -6,10 +6,10 @@ import (
"testing"
)
var wav_slice = []byte{0x52, 0x49, 0x46, 0x46, 0x98, 0x03, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20,
var wavSlice = []byte{0x52, 0x49, 0x46, 0x46, 0x98, 0x03, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20,
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00,
0x04, 0x00, 0x10, 0x00}
var wav_size = uint32(0x0374)
var wavSize = uint32(0x0374)
func TestReadHeader(t *testing.T) {
file, err := os.Open("./data/sample.wav")
@ -21,7 +21,7 @@ func TestReadHeader(t *testing.T) {
if size, err := wav.Read(file); err != nil {
t.Error(err)
} else {
if bytes.Compare(wav_slice, wav.Bytes()) != 0 || size != wav_size {
if bytes.Compare(wavSlice, wav.Bytes()) != 0 || size != wavSize {
t.Error("WaveHeader::Read fail")
}
}
@ -36,8 +36,8 @@ func TestWriteHeader(t *testing.T) {
defer file.Close()
defer os.Remove(filename)
wav := WaveHeader{}
copy(wav.Bytes(), wav_slice)
if err = wav.Write(file, wav_size); err != nil {
copy(wav.Bytes(), wavSlice)
if err = wav.Write(file, wavSize); err != nil {
t.Error(err)
}
}