package main import ( "bytes" "reflect" "syscall/js" "unsafe" "bitbucket.org/ausocean/av/codec/adpcm" ) func main() { dec := NewDecoder() dec.Start() } // Decoder is a client side adpcm decoder type Decoder struct { inBuf []uint8 onImgLoadCb, initMemCb, getDecLenCb js.Func console js.Value done chan struct{} } // NewDecoder returns a new instance of decoder func NewDecoder() *Decoder { return &Decoder{ console: js.Global().Get("console"), done: make(chan struct{}), } } func (s *Decoder) setupOnImgLoadCb() { s.onImgLoadCb = js.FuncOf(func(this js.Value, args []js.Value) interface{} { // reader := bytes.NewReader(s.inBuf) //DECODING HAPPENS HERE decoded := bytes.NewBuffer(make([]byte, 0, len(s.inBuf)*4)) dec := adpcm.NewDecoder(decoded) dec.Write(s.inBuf) s.inBuf = decoded.Bytes() return nil }) } func (s *Decoder) setupInitMemCb() { // The length of the data array buffer is passed. // Then the buf slice is initialized to that length. // A pointer to that slice is passed back to the browser. s.initMemCb = js.FuncOf(func(this js.Value, i []js.Value) interface{} { length := i[0].Int() s.console.Call("log", "length:", length) s.inBuf = make([]uint8, length) hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s.inBuf)) ptr := uintptr(unsafe.Pointer(hdr.Data)) s.console.Call("log", "ptr:", ptr) js.Global().Call("gotMem", ptr) return nil }) } func (s *Decoder) setupGetDecLenCb() { s.getDecLenCb = js.FuncOf(func(this js.Value, i []js.Value) interface{} { return len(s.inBuf) }) } // Start sets up all the callbacks and waits for the close signal // to be sent from the browser. func (s *Decoder) Start() { s.setupInitMemCb() js.Global().Set("initMem", s.initMemCb) s.setupOnImgLoadCb() js.Global().Set("loadData", s.onImgLoadCb) s.setupGetDecLenCb() js.Global().Set("getDecLen", s.getDecLenCb) <-s.done }