mirror of https://bitbucket.org/ausocean/av.git
audio-player: wasm decoding merged with pcm player
This commit is contained in:
parent
1842319957
commit
e23c1aac7e
|
@ -1,27 +1,73 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"bytes"
|
||||
"reflect"
|
||||
"syscall/js"
|
||||
"unsafe"
|
||||
|
||||
"bitbucket.org/ausocean/av/codec/adpcm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := make(chan struct{}, 0)
|
||||
|
||||
println("WASM Go Initialized")
|
||||
// register functions
|
||||
registerCallbacks()
|
||||
|
||||
<-c
|
||||
dec := NewDecoder()
|
||||
dec.Start()
|
||||
}
|
||||
|
||||
func registerCallbacks() {
|
||||
js.Global().Set("decode", js.FuncOf(decode))
|
||||
// Decoder is a client side adpcm decoder
|
||||
type Decoder struct {
|
||||
inBuf []uint8
|
||||
onImgLoadCb, initMemCb js.Func
|
||||
console js.Value
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func decode(this js.Value, args []js.Value) interface{} {
|
||||
fmt.Println("calculating")
|
||||
return adpcm.EncBytes(args[0].Int())
|
||||
// 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
|
||||
})
|
||||
}
|
||||
|
||||
// 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.done
|
||||
}
|
||||
|
|
|
@ -1,59 +1,81 @@
|
|||
const go = new Go()
|
||||
// memoryBytes is an Uint8Array pointing to the webassembly linear memory.
|
||||
let memoryBytes;
|
||||
let bytes;
|
||||
let mod, inst
|
||||
console.log("Initializing wasm...")
|
||||
WebAssembly.instantiateStreaming(
|
||||
fetch('lib.wasm'), go.importObject).then(
|
||||
result => {
|
||||
mod = result.module
|
||||
inst = result.instance
|
||||
memoryBytes = new Uint8Array(inst.exports.mem.buffer)
|
||||
console.log("Initialization complete.")
|
||||
run()
|
||||
}
|
||||
)
|
||||
|
||||
async function run() {
|
||||
await go.run(inst)
|
||||
inst = await WebAssembly.instantiate(mod, go.importObject) // reset instance
|
||||
}
|
||||
|
||||
// gotMem sets the webassembly linear memory with the data buffer result
|
||||
// at the slice header pointer passed from Go.
|
||||
function gotMem(pointer) {
|
||||
memoryBytes.set(bytes, pointer);
|
||||
// Now the data can be loaded from the slice.
|
||||
loadData();
|
||||
}
|
||||
|
||||
// // displayImage takes the pointer to the target image in the wasm linear memory
|
||||
// // and its length. Gets the resulting byte slice and creates an image blob.
|
||||
// function displayImage(pointer, length) {
|
||||
// let resultBytes = memoryBytes.slice(pointer, pointer + length);
|
||||
// let blob = new Blob([resultBytes], {
|
||||
// 'type': imageType
|
||||
// });
|
||||
// document.getElementById('targetImg').src = URL.createObjectURL(blob);
|
||||
// }
|
||||
|
||||
// document.getElementById('input').addEventListener('change', function () {
|
||||
// let reader = new FileReader();
|
||||
|
||||
// reader.onload = (ev) => {
|
||||
// bytes = new Uint8Array(ev.target.result);
|
||||
// initMem(bytes.length);
|
||||
// let blob = new Blob([bytes], {
|
||||
// 'type': imageType
|
||||
// });
|
||||
// document.getElementById("sourceImg").src = URL.createObjectURL(blob);
|
||||
// };
|
||||
// imageType = this.files[0].type;
|
||||
// reader.readAsArrayBuffer(this.files[0]);
|
||||
// });
|
||||
window.onload = function () {
|
||||
initWasm()
|
||||
document.getElementById('input').addEventListener('change', playFile)
|
||||
}
|
||||
|
||||
function playFile() {
|
||||
console.log(decode(48000))
|
||||
const input = event.target.files[0]
|
||||
document.getElementById('input').addEventListener('change', function () {
|
||||
const input = event.target.files[0]
|
||||
const reader = new FileReader()
|
||||
|
||||
const reader = new FileReader()
|
||||
reader.onload = event => playData(event.target.result)
|
||||
reader.onerror = error => reject(error)
|
||||
reader.readAsArrayBuffer(input)
|
||||
}
|
||||
reader.onload = event => {
|
||||
bytes = new Uint8Array(event.target.result)
|
||||
|
||||
function playData(array) {
|
||||
var data = new Uint8Array(array)
|
||||
console.log("playing file")
|
||||
var player = new PCMPlayer({
|
||||
encoding: '16bitInt',
|
||||
channels: 1,
|
||||
sampleRate: 48000,
|
||||
flushingTime: 2000
|
||||
});
|
||||
player.feed(data)
|
||||
}
|
||||
initMem(bytes.length)
|
||||
|
||||
function initWasm() {
|
||||
if (!WebAssembly.instantiateStreaming) {
|
||||
// polyfill
|
||||
WebAssembly.instantiateStreaming = async (resp, importObject) => {
|
||||
const source = await (await resp).arrayBuffer()
|
||||
return await WebAssembly.instantiate(source, importObject)
|
||||
// bytes should be decoded at this point, if not try memoryBytes.set(bytes, pointer)
|
||||
|
||||
console.log("playing file")
|
||||
var player = new PCMPlayer({
|
||||
encoding: '16bitInt',
|
||||
channels: 1,
|
||||
sampleRate: 48000,
|
||||
flushingTime: 2000
|
||||
});
|
||||
player.feed(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
const go = new Go()
|
||||
let mod, inst
|
||||
// memoryBytes is an Uint8Array pointing to the webassembly linear memory.
|
||||
let memoryBytes;
|
||||
console.log("Initializing wasm...")
|
||||
WebAssembly.instantiateStreaming(
|
||||
fetch('lib.wasm'), go.importObject).then(
|
||||
result => {
|
||||
mod = result.module
|
||||
inst = result.instance
|
||||
memoryBytes = new Uint8Array(inst.exports.mem.buffer)
|
||||
console.log("Initialization complete.")
|
||||
run()
|
||||
}
|
||||
)
|
||||
|
||||
async function run() {
|
||||
await go.run(inst)
|
||||
inst = await WebAssembly.instantiate(mod, go.importObject) // reset instance
|
||||
}
|
||||
|
||||
reader.onerror = error => reject(error)
|
||||
reader.readAsArrayBuffer(input)
|
||||
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue