(sampleRate int, channelCount int, format mux.Format, bufferSizeInBytes int)
| 34 | } |
| 35 | |
| 36 | func newContext(sampleRate int, channelCount int, format mux.Format, bufferSizeInBytes int) (*context, chan struct{}, error) { |
| 37 | ready := make(chan struct{}) |
| 38 | |
| 39 | class := js.Global().Get("AudioContext") |
| 40 | if !class.Truthy() { |
| 41 | class = js.Global().Get("webkitAudioContext") |
| 42 | } |
| 43 | if !class.Truthy() { |
| 44 | return nil, nil, errors.New("oto: AudioContext or webkitAudioContext was not found") |
| 45 | } |
| 46 | options := js.Global().Get("Object").New() |
| 47 | options.Set("sampleRate", sampleRate) |
| 48 | |
| 49 | d := &context{ |
| 50 | audioContext: class.New(options), |
| 51 | mux: mux.New(sampleRate, channelCount, format), |
| 52 | } |
| 53 | |
| 54 | if bufferSizeInBytes == 0 { |
| 55 | // 4096 was not great at least on Safari 15. |
| 56 | bufferSizeInBytes = 8192 * channelCount |
| 57 | } |
| 58 | |
| 59 | buf32 := make([]float32, bufferSizeInBytes/4) |
| 60 | |
| 61 | if w := d.audioContext.Get("audioWorklet"); w.Truthy() { |
| 62 | script := fmt.Sprintf(` |
| 63 | class OtoWorkletProcessor extends AudioWorkletProcessor { |
| 64 | constructor() { |
| 65 | super(); |
| 66 | this.bufferSize_ = %[1]d; |
| 67 | this.channelCount_ = %[2]d; |
| 68 | this.buf_ = new Float32Array(); |
| 69 | this.waitRecv_ = false; |
| 70 | |
| 71 | // Receive data from the main thread. |
| 72 | this.port.onmessage = (event) => { |
| 73 | const buf = event.data; |
| 74 | const newBuf = new Float32Array(this.buf_.length + buf.length); |
| 75 | newBuf.set(this.buf_); |
| 76 | newBuf.set(buf, this.buf_.length); |
| 77 | this.buf_ = newBuf; |
| 78 | this.waitRecv_ = false; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | process(inputs, outputs, parameters) { |
| 83 | const output = outputs[0]; |
| 84 | |
| 85 | // If the buffer is too short, request more data and return silence. |
| 86 | if (this.buf_.length < output[0].length*this.channelCount_) { |
| 87 | if (!this.waitRecv_) { |
| 88 | this.waitRecv_ = true; |
| 89 | this.port.postMessage(null); |
| 90 | } |
| 91 | for (let i = 0; i < output.length; i++) { |
| 92 | output[i].fill(0); |
| 93 | } |
no test coverage detected
searching dependent graphs…