evanwashere / opus Goto Github PK
View Code? Open in Web Editor NEWfast opus bindings for node and browsers
License: MIT License
fast opus bindings for node and browsers
License: MIT License
Hello, thank you for creating this library. I had some questions about how to use it.
From what I understand in wasm/index.js
, the encode/decode functions are synchronous and they block the main thread in browser/node. Is that true?
If so, is it possible to load this library from a worker, to make it async/non-blocking? I'll see if I can achieve it and report back here if successful.
Looking at other similar libraries, wasm-media-encoders, wasm-audio-decoders, and opusscript, I see their API is synchronous and blocking also. ffmpeg.wasm and lame-wasm are async.
That's interesting because I would have expected, for most purposes, async encode/decode is preferred for both browser and server side, so as not to block the main thread. For example, how AudioContext.decodeAudioData()
works.
Currently, I'm encountering some difficulties trying to encode (and decode back) an instance of AudioBuffer.
First, I noticed that if the sample rate is 44100
, the Encoder/Decoder constructor throws an error, opus: invalid argument
.
const { encode } = new Encoder({
channels: audioBuffer.numberOfChannels,
sample_rate: audioBuffer.sampleRate
})
If I force it to 48000
, it doesn't throw.
Next, I learned how to extract PCM data from an AudioBuffer using getChannelData()
.
const buffers = [] // Float32Array per channel
for (let i=0, len=audioBuffer.numberOfChannels; i < len; i++) {
buffers.push(audioBuffer.getChannelData(i))
}
When I pass a channel's data to encode()
, it throws RangeError: source array is too long
.
The error is from the first line of RawEncoder.encode()
in @evan/wasm/target/opus/deno.js
.
encode(buffer) {
bptrs.set(buffer = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength));
return pptrs.slice(0, err(wasm.opus_encode(this.#ptr, bptr, buffer.length / 2 / this.channels, pptr, pptrl)));
}
..So I should convert my Float32Array
to an Uint8Array
before passing it to encode. Is that correct?
const channelData = buffers[0].buffer // Get ArrayBuffer from Float32Array
const pcm = new Uint8Array(channelData)
const opusData = encode(pcm)
The conversion seems to work, but still results in the same error, RangeError: source array is too long
.
EDIT: I'm guessing it's because I set the wrong sample rate when instantiating the encoder. And probably it's impossible (or unwise, haha) to try to up-scale from 44.1 to 48 kHz.
Well, I'll try to figure out these questions on my own, but if you have any thoughts, I'd appreciate it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.