Skip to content

Commit 50c8095

Browse files
committed
Rename to encode-audio
1 parent 2ff8054 commit 50c8095

5 files changed

Lines changed: 52 additions & 86 deletions

File tree

README.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ Encode raw audio samples to any format.<br>
44
JS / WASM – no ffmpeg, no native bindings, works in both node and browser.<br>
55
Small API, minimal size, near-native performance, stream encoding.
66

7-
[![npm install audio-encode](https://nodei.co/npm/audio-encode.png?mini=true)](https://npmjs.org/package/audio-encode/)
7+
[![npm install encode-audio](https://nodei.co/npm/encode-audio.png?mini=true)](https://npmjs.org/package/encode-audio/)
88

99
```js
10-
import encode from 'audio-encode';
10+
import encode from 'encode-audio';
1111

1212
const buf = await encode.wav(channelData, { sampleRate: 44100 });
1313
```
@@ -16,19 +16,19 @@ const buf = await encode.wav(channelData, { sampleRate: 44100 });
1616

1717
| Format | Package | Engine |
1818
|--------|---------|--------|
19-
| WAV | [@audio/wav-encode](https://github.com/audiojs/wav-encode) | JS |
20-
| MP3 | [@audio/mp3-encode](https://github.com/audiojs/mp3-encode) | WASM |
21-
| OGG Vorbis | [@audio/ogg-encode](https://github.com/audiojs/ogg-encode) | WASM |
22-
| Opus | [@audio/opus-encode](https://github.com/audiojs/opus-encode) | WASM |
23-
| FLAC | [@audio/flac-encode](https://github.com/audiojs/flac-encode) | WASM |
24-
| AIFF | [@audio/aiff-encode](https://github.com/audiojs/aiff-encode) | JS |
19+
| WAV | [@audio/wav-encode](https://npmjs.com/package/@audio/wav-encode) | JS |
20+
| MP3 | [@audio/mp3-encode](https://npmjs.com/package/@audio/mp3-encode) | WASM |
21+
| OGG Vorbis | [@audio/ogg-encode](https://npmjs.com/package/@audio/ogg-encode) | WASM |
22+
| Opus | [@audio/opus-encode](https://npmjs.com/package/@audio/opus-encode) | WASM |
23+
| FLAC | [@audio/flac-encode](https://npmjs.com/package/@audio/flac-encode) | WASM |
24+
| AIFF | [@audio/aiff-encode](https://npmjs.com/package/@audio/aiff-encode) | JS |
2525

2626
### Whole-file encode
2727

28-
Specify the format as method name. Input is _Float32Array[]_ (one per channel) or a single _Float32Array_ (mono).
28+
Specify the format as method name. Input is _Float32Array[]_ (one per channel), a single _Float32Array_ (mono), or an [AudioBuffer](https://npmjs.com/package/audio-buffer).
2929

3030
```js
31-
import encode from 'audio-encode';
31+
import encode from 'encode-audio';
3232

3333
const wav = await encode.wav(channelData, { sampleRate: 44100 });
3434
const aiff = await encode.aiff(channelData, { sampleRate: 44100 });
@@ -43,7 +43,7 @@ const opus = await encode.opus(channelData, { sampleRate: 48000, bitrate: 96 });
4343
For chunk-by-chunk encoding, use `.stream()`:
4444

4545
```js
46-
import encode from 'audio-encode';
46+
import encode from 'encode-audio';
4747

4848
const encoder = await encode.mp3.stream({ sampleRate: 44100, bitrate: 128 });
4949

@@ -72,7 +72,7 @@ const c = await encoder.encode(); // end of stream — flush + free
7272
The `encode` registry is extensible:
7373

7474
```js
75-
import encode from 'audio-encode';
75+
import encode from 'encode-audio';
7676
encode.myformat = Object.assign(
7777
async (data, opts) => { /* ... */ },
7878
{ stream: async (opts) => ({ encode: chunk => ..., free() {} }) }
@@ -82,9 +82,8 @@ encode.myformat = Object.assign(
8282
## See also
8383

8484
* [audio-decode](https://github.com/audiojs/audio-decode) – decode any audio format to raw samples.
85-
* [wasm-media-encoders](https://github.com/nicodemus26/wasm-media-encoders) – compact WASM MP3 & Vorbis encoders.
85+
* [wasm-media-encoders](https://github.com/arseneyr/wasm-media-encoders) – compact WASM MP3 & Vorbis encoders.
8686
* [AudioEncoder](https://developer.mozilla.org/en-US/docs/Web/API/AudioEncoder) – native WebCodecs encoder API.
87-
* [ffmpeg.wasm](https://github.com/ffmpegwasm/ffmpeg.wasm) – full encoding/decoding library.
8887

8988
## License
9089

audio-encode.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Audio encoder: whole-file and streaming
3-
* @module audio-encode
3+
* @module encode-audio
44
*
55
* let buf = await encode.wav(channelData, { sampleRate: 44100 })
66
*
@@ -59,6 +59,12 @@ function channels(data) {
5959
return []
6060
}
6161
if (data instanceof Float32Array) return [data]
62+
// AudioBuffer or AudioBuffer-like ({ numberOfChannels, getChannelData })
63+
if (data.getChannelData && data.numberOfChannels) {
64+
let ch = []
65+
for (let i = 0; i < data.numberOfChannels; i++) ch.push(data.getChannelData(i))
66+
return ch
67+
}
6268
return []
6369
}
6470

@@ -118,5 +124,3 @@ function merge(a, b) {
118124
return out
119125
}
120126

121-
export { fmt, channels, norm, merge }
122-

package-lock.json

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "audio-encode",
2+
"name": "encode-audio",
33
"version": "1.0.0",
44
"description": "Encode audio data in node or browser",
55
"type": "module",
@@ -59,6 +59,7 @@
5959
"@audio/wav-encode": "^1.0.0"
6060
},
6161
"devDependencies": {
62+
"audio-buffer": "^7.3.0",
6263
"audio-decode": "^4.0.0",
6364
"audio-lena": "^3.0.0",
6465
"tst": "^9.2.2"

test.js

Lines changed: 20 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,26 @@
11
import t, { is, ok, almost } from 'tst'
2-
import encode, { streamEncoder, fmt, channels, norm, merge } from './audio-encode.js'
2+
import encode from './audio-encode.js'
33
import decode from 'audio-decode'
4-
// --- test utilities ---
5-
6-
function sine(sampleRate = 44100, freq = 440, duration = 1) {
7-
let n = sampleRate * duration
8-
let data = new Float32Array(n)
9-
for (let i = 0; i < n; i++) data[i] = Math.sin(2 * Math.PI * freq * i / sampleRate)
10-
return [data]
11-
}
4+
import AudioBuffer from 'audio-buffer'
125

136
function rms(arr) {
147
let sum = 0
158
for (let i = 0; i < arr.length; i++) sum += arr[i] * arr[i]
169
return Math.sqrt(sum / arr.length)
1710
}
1811

19-
// decode lena wav to get reference audio
12+
function sine(sr = 44100, freq = 440, dur = 1) {
13+
let n = sr * dur, d = new Float32Array(n)
14+
for (let i = 0; i < n; i++) d[i] = Math.sin(2 * Math.PI * freq * i / sr)
15+
return [d]
16+
}
17+
2018
let lenaPCM
2119
async function getLena() {
22-
if (!lenaPCM) {
23-
let wav = (await import('audio-lena/wav')).default
24-
lenaPCM = await decode(wav)
25-
}
20+
if (!lenaPCM) lenaPCM = await decode((await import('audio-lena/wav')).default)
2621
return lenaPCM
2722
}
2823

29-
// --- core helpers ---
30-
31-
t('channels', () => {
32-
let mono = new Float32Array([1, 2, 3])
33-
let stereo = [new Float32Array([1, 2]), new Float32Array([3, 4])]
34-
is(channels(null).length, 0)
35-
is(channels(undefined).length, 0)
36-
is(channels([]).length, 0)
37-
is(channels(mono).length, 1)
38-
is(channels(mono)[0], mono)
39-
is(channels(stereo).length, 2)
40-
})
41-
42-
t('norm', () => {
43-
is(norm(null).length, 0)
44-
let buf = new Uint8Array([1, 2, 3])
45-
is(norm(buf), buf)
46-
ok(norm(new Int8Array([1, 2])) instanceof Uint8Array)
47-
})
48-
49-
t('merge', () => {
50-
let a = new Uint8Array([1, 2]), b = new Uint8Array([3, 4])
51-
is(merge(a, b).length, 4)
52-
is(merge(a, null), a)
53-
is(merge(null, b), b)
54-
})
55-
56-
t('streamEncoder', async () => {
57-
let enc = streamEncoder(
58-
ch => new Uint8Array([ch[0].length]),
59-
() => new Uint8Array([0xFF]),
60-
() => {}
61-
)
62-
let r1 = await enc.encode([new Float32Array([1, 2, 3])])
63-
is(r1[0], 3)
64-
let r2 = await enc.encode()
65-
is(r2[0], 0xFF)
66-
is((await enc.encode()).length, 0)
67-
})
68-
69-
t('fmt', async () => {
70-
let encoder = fmt(async (opts) => streamEncoder(
71-
ch => new Uint8Array(ch[0].length * 2),
72-
() => new Uint8Array([0xFE]),
73-
() => {}
74-
))
75-
is(typeof encoder, 'function')
76-
is(typeof encoder.stream, 'function')
77-
let result = await encoder([new Float32Array(100)], { sampleRate: 44100 })
78-
is(result.length, 201)
79-
})
80-
8124
// --- format round-trip tests with lena ---
8225

8326
t('wav round-trip (lena)', async () => {
@@ -144,3 +87,14 @@ t('wav streaming', async () => {
14487
let final = await enc.encode()
14588
ok(c1.length > 0 || c2.length > 0 || final.length > 0)
14689
})
90+
91+
t('AudioBuffer input', async () => {
92+
let ab = new AudioBuffer({ sampleRate: 44100, length: 44100 })
93+
let ch = ab.getChannelData(0)
94+
for (let i = 0; i < ch.length; i++) ch[i] = Math.sin(2 * Math.PI * 440 * i / 44100)
95+
let buf = await encode.wav(ab, { sampleRate: 44100 })
96+
ok(buf.length > 44, 'encodes AudioBuffer')
97+
let dec = await decode(buf)
98+
is(dec.sampleRate, 44100)
99+
almost(rms(dec.channelData[0]), rms(ch), 0.001, 'rms matches')
100+
})

0 commit comments

Comments
 (0)