Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

opus-decoder

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

opus-decoder - npm Package Compare versions

Comparing version 0.3.5 to 0.4.0

25

package.json
{
"name": "opus-decoder",
"version": "0.3.5",
"version": "0.4.0",
"description": "Web Assembly streaming Opus decoder",
"main": "dist/opus-decoder.min.js",
"module": "index.js",
"type": "module",
"main": "./index.js",
"exports": "./index.js",
"types": "types.d.ts",

@@ -17,7 +18,2 @@ "files": [

],
"repository": {
"type": "git",
"url": "git+https://github.com/eshaz/wasm-audio-decoders.git"
},
"type": "module",
"keywords": [

@@ -27,2 +23,4 @@ "Opus",

"decoder",
"multichannel",
"surround",
"stream",

@@ -44,5 +42,14 @@ "streams",

"homepage": "https://github.com/eshaz/wasm-audio-decoders/tree/master/src/opus-decoder",
"repository": {
"type": "git",
"url": "git+https://github.com/eshaz/wasm-audio-decoders.git",
"directory": "src/opus-decoder"
},
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/eshaz"
},
"dependencies": {
"@wasm-audio-decoders/common": "1.0.0"
"@wasm-audio-decoders/common": "2.0.0"
}
}
# `opus-decoder`
`opus-decoder` is a Web Assembly Opus audio decoder.
* 87.7 KiB minified bundle size
* 89.9 KiB minified bundle size
* Browser and NodeJS support

@@ -77,3 +77,2 @@ * Built in Web Worker support

## API
Decoded audio is always returned in the below structure.

@@ -85,3 +84,4 @@

leftAudio, // Float32Array of PCM samples for the left channel
rightAudio // Float32Array of PCM samples for the right channel
rightAudio, // Float32Array of PCM samples for the right channel
... // additional channels
],

@@ -95,2 +95,19 @@ samplesDecoded: 1234, // number of PCM samples that were decoded per channel

### Multichannel Output
Each channel is assigned to a speaker location in a conventional surround arrangement. Specific locations depend on the number of channels, and are given below in order of the corresponding channel indices. This set of surround options and speaker location orderings is the same as those used by the Vorbis codec.
* 1 channel: monophonic (mono).
* 2 channels: stereo (left, right).
* 3 channels: linear surround (left, center, right).
* 4 channels: quadraphonic (front left, front right, rear left, rear right).
* 5 channels: 5.0 surround (front left, front center, front right, rear left, rear right).
* 6 channels: 5.1 surround (front left, front center, front right, rear left, rear right, LFE).
* 7 channels: 6.1 surround (front left, front center, front right, side left, side right, rear center, LFE).
* 8 channels: 7.1 surround (front left, front center, front right, side left, side right, rear left, rear right, LFE).
See: https://datatracker.ietf.org/doc/html/rfc7845.html#section-5.1.1.2
Each Float32Array within `channelData` can be used directly in the WebAudio API for playback.
## `OpusDecoder`

@@ -100,2 +117,28 @@

### Options
```javascript
const decoder = new OpusDecoder({
preSkip: 0,
channels: 2,
streamCount: 1,
coupledStreamCount: 1,
channelMappingTable: [0, 1]
});
```
#### **The below options should be obtained from the Opus Header.**
See this [documentation](https://wiki.xiph.org/OggOpus#ID_Header) on the Opus header for more information. If you don't have access to the Opus header, the default values will successfully decode most stereo Opus streams.
* `preSkip` *optional, defaults to `0`*
* Number of samples to skip at the beginning reported by the Opus header.
#### ***Required for Multichannel Decoding.** (Channel Mapping Family >= 1)*
* `channels` *optional, defaults to `2`*
* Number of channels reported by the Opus header.
* `streamCount` *optional, defaults to `1`*
* Number of streams reported by the Opus header.
* `coupledStreamCount` *optional, defaults to: `1` when 2 channels, `0` when 1 channel*
* Number of coupled streams reported by the Opus header.
* `channelMappingTable` *optional, defaults to `[0, 1]` when 2 channels, `[0]` when 1 channel*
* Channel mapping reported by the Opus header.
### Getters

@@ -123,2 +166,27 @@ * `decoder.ready` *async*

### Options
```javascript
const decoder = new OpusDecoderWebWorker({
preSkip: 0,
channels: 2,
streamCount: 1,
coupledStreamCount: 1,
channelMappingTable: [0, 1]
});
```
#### **The below options should be obtained from the Opus Header.**
See this [documentation](https://wiki.xiph.org/OggOpus#ID_Header) on the Opus header for more information. If you don't have access to the Opus header, the default values will successfully decode most stereo Opus streams.
* `preSkip` *optional, defaults to `0`*
* Number of samples to skip at the beginning reported by the Opus header.
#### ***Required for Multichannel Decoding.** (Channel Mapping Family >= 1)*
* `channels` *optional, defaults to `2`*
* Number of channels reported by the Opus header.
* `streamCount` *optional, defaults to `1`*
* Number of streams reported by the Opus header.
* `coupledStreamCount` *optional, defaults to: `1` when 2 channels, `0` when 1 channel*
* Number of coupled streams reported by the Opus header.
* `channelMappingTable` *optional, defaults to `[0, 1]` when 2 channels, `[0]` when 1 channel*
* Channel mapping reported by the Opus header.
### Getters

@@ -125,0 +193,0 @@ * `decoder.ready` *async*

@@ -13,7 +13,42 @@ import { WASMAudioDecoderCommon } from "@wasm-audio-decoders/common";

this._inputPtrSize = (0.12 * 510000) / 8;
const isNumber = (param) => typeof param === "number";
// channel mapping family >= 1
if (
options.channels > 2 &&
(!isNumber(options.streamCount) ||
!isNumber(options.coupledStreamCount) ||
!Array.isArray(options.channelMappingTable))
) {
throw new Error(
"Invalid Opus Decoder Options for multichannel decoding."
);
}
// channel mapping family 0
this._channels = isNumber(options.channels) ? options.channels : 2;
this._streamCount = isNumber(options.streamCount) ? options.streamCount : 1;
this._coupledStreamCount = isNumber(options.coupledStreamCount)
? options.coupledStreamCount
: this._channels - 1;
this._channelMappingTable =
options.channelMappingTable || (this._channels === 2 ? [0, 1] : [0]);
this._preSkip = options.preSkip || 0;
this._inputPtrSize = 32000 * 0.12 * this._channels; // 256kbs per channel
this._outputPtrSize = 120 * 48;
this._outputChannels = 2;
this._outputChannels = this._channels;
this._ready = this._init();
// prettier-ignore
this._errors = {
[-1]: "OPUS_BAD_ARG: One or more invalid/out of range arguments",
[-2]: "OPUS_BUFFER_TOO_SMALL: Not enough bytes allocated in the buffer",
[-3]: "OPUS_INTERNAL_ERROR: An internal error was detected",
[-4]: "OPUS_INVALID_PACKET: The compressed data passed is corrupted",
[-5]: "OPUS_UNIMPLEMENTED: Invalid/unsupported request number",
[-6]: "OPUS_INVALID_STATE: An encoder or decoder structure is invalid or already freed",
[-7]: "OPUS_ALLOC_FAIL: Memory allocation has failed"
}
}

@@ -27,3 +62,15 @@

this._decoder = this._common.wasm._opus_frame_decoder_create();
const [mappingPtr, mappingArr] = this._common.allocateTypedArray(
this._channels,
Uint8Array
);
mappingArr.set(this._channelMappingTable);
this._decoder = this._common.wasm._opus_frame_decoder_create(
this._channels,
this._streamCount,
this._coupledStreamCount,
mappingPtr,
this._preSkip
);
}

@@ -46,3 +93,3 @@

decodeFrame(opusFrame) {
_decode(opusFrame) {
if (!(opusFrame instanceof Uint8Array))

@@ -63,7 +110,17 @@ throw Error(

return this._WASMAudioDecoderCommon.getDecodedAudio(
[
this._output.slice(0, samplesDecoded),
this._output.slice(samplesDecoded, samplesDecoded * 2),
],
if (samplesDecoded < 0) {
console.error(
`libopus ${samplesDecoded} ${this._errors[samplesDecoded]}`
);
return 0;
}
return samplesDecoded;
}
decodeFrame(opusFrame) {
const samplesDecoded = this._decode(opusFrame);
return this._WASMAudioDecoderCommon.getDecodedAudioMultiChannel(
this._output,
this._channels,
samplesDecoded,

@@ -75,20 +132,27 @@ 48000

decodeFrames(opusFrames) {
let left = [],
right = [],
samples = 0;
let outputBuffers = [],
outputSamples = 0;
opusFrames.forEach((frame) => {
const { channelData, samplesDecoded } = this.decodeFrame(frame);
const samplesDecoded = this._decode(frame);
left.push(channelData[0]);
right.push(channelData[1]);
samples += samplesDecoded;
outputBuffers.push(
this._common.getOutputChannels(
this._output,
this._channels,
samplesDecoded
)
);
outputSamples += samplesDecoded;
});
return this._WASMAudioDecoderCommon.getDecodedAudioConcat(
[left, right],
samples,
const data = this._WASMAudioDecoderCommon.getDecodedAudioMultiChannel(
outputBuffers,
this._channels,
outputSamples,
48000
);
return data;
}
}

@@ -1,9 +0,16 @@

type OpusDecodedAudio = {
channelData: Float32Array[];
samplesDecoded: number;
sampleRate: 48000;
};
declare module "opus-decoder" {
export interface OpusDecodedAudio {
channelData: Float32Array[];
samplesDecoded: number;
sampleRate: 48000;
}
declare module 'opus-decoder' {
export class OpusDecoder {
constructor(options?: {
preSkip?: number;
channels?: number;
streamCount?: number;
coupledStreamCount?: number;
channelMappingTable?: number[];
});
ready: Promise<void>;

@@ -17,2 +24,9 @@ reset: () => Promise<void>;

export class OpusDecoderWebWorker {
constructor(options?: {
preSkip?: number;
channels?: number;
streamCount?: number;
coupledStreamCount?: number;
channelMappingTable?: number[];
});
ready: Promise<void>;

@@ -19,0 +33,0 @@ reset: () => Promise<void>;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc