Skip to content

Some work in progress on running the web-platform-tests suite for WebAudio #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1acdd32
Copy over some web-platform-tests
orottier Nov 25, 2023
b98fd01
Run the WPT webaudio test harness for our bindings
orottier Nov 25, 2023
66fdf55
refactor: move wpt as npm script
b-ma Nov 27, 2023
ced86f1
chore: use programmatic API to run wpt
b-ma Nov 27, 2023
7f9cd2e
chore: clean wpt files
b-ma Nov 27, 2023
b27bc9c
chore: build in debug mode when running wpt
b-ma Nov 27, 2023
e8835d6
Merge branch 'main' into feature/wpt-harness
b-ma Nov 28, 2023
0eb0b7e
test: add analyser node wpt test + disciminate errors of error types …
b-ma Nov 28, 2023
8ff8d03
test: add some options for wpt tests
b-ma Nov 28, 2023
acfbb2e
Avoid some wpt crashes by providing stub implementations
orottier Nov 28, 2023
99bfa66
Replace wpt webaudio suite with git submodule
orottier Nov 29, 2023
81e52ed
Skip crashtests and resources in web platform tests
orottier Nov 29, 2023
ce30937
Add more stubs to prevent the wpt from crashing
orottier Nov 30, 2023
edad866
Add bindings for AudioListener
orottier Nov 30, 2023
072baef
Revert unrelated changes to iir-filter example
orottier Nov 30, 2023
876c654
fix: lazily instantiate listener
b-ma Dec 2, 2023
5d24303
Revert "Add bindings for AudioListener"
orottier Dec 2, 2023
23e2cf0
Merge remote-tracking branch 'origin/feat/audio-listener' into featur…
orottier Dec 2, 2023
edc7b50
Update results of template generation
orottier Dec 2, 2023
3406ec7
Improve suspend/resume stub, use pending promise instead of resolved
orottier Dec 2, 2023
e57fd25
OfflineAudioContext now takes &mut for startRendering
orottier Dec 2, 2023
5892b7d
Revert "OfflineAudioContext now takes &mut for startRendering"
orottier Dec 3, 2023
4dddcf5
Merge remote-tracking branch 'origin/refactor/offline-audio-context' …
orottier Dec 3, 2023
e675723
Revert other changes for OfflineAudioContext being consumed
orottier Dec 3, 2023
686c466
Merge remote-tracking branch 'origin/main' into feature/wpt-harness
orottier Dec 6, 2023
babd5bd
Remove printlns
orottier Dec 6, 2023
4374dd9
Attempting to get OfflineAudioContext.suspend to work
orottier Dec 6, 2023
1ed0c50
make callback run without crashing
b-ma Dec 7, 2023
8f4d454
feat: implement async startRendering, susped and resume for OfflineAu…
b-ma Dec 21, 2023
3461cd9
Merge branch 'main' into feature/offline-context-suspend
b-ma Dec 22, 2023
17770ef
refactor: cleaning
b-ma Dec 22, 2023
56ff66e
fmt
b-ma Dec 22, 2023
df44e9f
OfflineAudioContext renamed suspend_at -> suspend
orottier Dec 27, 2023
a1d7a3e
Merge pull request #50 from ircam-ismm/feature/offline-context-suspend
orottier Dec 27, 2023
c24af51
Implement deprecated AudioListener setPosition, setOrientation
orottier Dec 27, 2023
ca9014e
Update the wpt submodule to my own fork for now
orottier Dec 27, 2023
2633aed
Upgrade to web-audio-api-rs 0.39 and reinstate lto setting
orottier Dec 27, 2023
edb3441
feat: implement all audio param attributes
b-ma Dec 28, 2023
fd4d710
fix: typo
b-ma Dec 28, 2023
1a3e918
fix: expose OfflineAudioContext::state
b-ma Dec 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "wpt"]
path = wpt
url = git@github.com:orottier/wpt.git
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ version = "0.14.0"
crate-type = ["cdylib"]

[dependencies]
napi = {version="2.13", features=["napi6"]}
napi = {version="2.13", features=["napi6", "tokio_rt"]}
napi-derive = "2.13"
web-audio-api = "0.38"
web-audio-api = "0.39"
# web-audio-api = { path = "../web-audio-api-rs" }

[target.'cfg(all(any(windows, unix), target_arch = "x86_64", not(target_env = "musl")))'.dependencies]
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,26 @@ The npm `postversion` script rely on [`cargo-bump`](https://crates.io/crates/car
cargo install cargo-bump
```

## Running the web-platform-test suite

Follow the steps for 'Manual Build' first. Then checkout the web-platform-tests submodule with:

```
git submodule init
git submodule update
```

Then run:

```
npm run wpt # build in debug mode and run all wpt test
npm run wpt:only # run all wpt test without build
npm run wpt -- --list # list all wpt test files
npm run wpt -- --filter <string> # apply <string> filter on executed/listed wpt tests
```

Avai

## License

[BSD-3-Clause](./LICENSE)
105 changes: 105 additions & 0 deletions bin/wpt-harness.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import path from 'path';
import wptRunner from 'wpt-runner';
import chalk from 'chalk';
import { program } from 'commander';

import * as nodeWebAudioAPI from '../index.mjs';

program
.option('--list', 'List the name of the test files')
.option('--with_crashtests', 'Also run crashtests')
.option('--filter <string>', 'Filter executed OR listed test files', '.*');

program.parse(process.argv);

const options = program.opts();

// -------------------------------------------------------
// Some helpers
// -------------------------------------------------------
const INDENT_SIZE = 2;

function indent(string, times) {
const prefix = " ".repeat(times);
return string.split("\n").map(l => prefix + l).join("\n");
}

// -------------------------------------------------------
// WPT Runner configuration options
// -------------------------------------------------------
const testsPath = 'wpt/webaudio';
const rootURL = 'webaudio';

// monkey patch `window` with our web audio API
const setup = window => {
Object.assign(window, nodeWebAudioAPI);

// seems required (weirdly...), cf. `the-audiobuffer-interface/audiobuffer.html`
window.Float32Array = Float32Array;
}

const filterRe = new RegExp(`${options.filter}`);

const filter = (name) => {
if (!options.with_crashtests && name.includes('/crashtests/')) {
return false;
}
if (name.includes('/resources/')) {
return false;
}
if (filterRe.test(name)) {
if (options.list) {
console.log(name);
return false;
} else {
return true;
}
} else {
return false;
}
};

// reporter, adapted from default console reporter
// https://github.com/domenic/wpt-runner/blob/master/lib/console-reporter.js
let numPass = 0;
let numFail = 0;
let typeErrorFail = 0;

const reporter = {
startSuite: name => {
console.log(`\n ${chalk.bold.underline(path.join(testsPath, name))}\n`);
},
pass: message => {
numPass += 1;
console.log(chalk.dim(indent(chalk.green("√ ") + message, INDENT_SIZE)));
},
fail: message => {
if (/threw "Error" instead of/.test(message)) {
typeErrorFail += 1;
console.log(chalk.bold.yellow(indent(`| ${message}`, INDENT_SIZE)));
} else {
numFail += 1;
console.log(chalk.bold.red(indent(`\u00D7 ${message}`, INDENT_SIZE)));
}
},
reportStack: stack => {
// console.log(chalk.dim(indent(stack, INDENT_SIZE * 2)))
},
};

// -------------------------------------------------------
// Run test suite
// -------------------------------------------------------
try {
const failures = await wptRunner(testsPath, { rootURL, setup, filter, reporter });

console.log(`\n ${chalk.bold.underline('RESULTS:')}`);
console.log(chalk.bold(` - # pass: ${numPass}`));
console.log(chalk.bold(` - # fail: ${numFail}`));
console.log(chalk.bold(` - # type error issues: ${typeErrorFail}`));

process.exit(failures);
} catch (e) {
console.error(e.stack);
process.exit(1);
}
46 changes: 39 additions & 7 deletions examples/offline.mjs
Original file line number Diff line number Diff line change
@@ -1,23 +1,55 @@
import { AudioContext, OfflineAudioContext } from '../index.mjs';

const offline = new OfflineAudioContext(1, 44100, 44100);
const offline = new OfflineAudioContext(1, 48000, 48000);

const osc = offline.createOscillator();
osc.connect(offline.destination);
osc.frequency.value = 220;
osc.start(0);
osc.stop(1);
offline.suspend(128 / 48000).then(() => {
console.log("suspend");

const osc = offline.createOscillator();
osc.connect(offline.destination);
osc.frequency.value = 220;
osc.start(0);

console.log("resume");
offline.resume();
});

const buffer = await offline.startRendering();
console.log("buffer duration:", buffer.duration);

// dirty check the audio buffer
const channelData = buffer.getChannelData(0);

for (let i = 0; i < 48000; i++) {
// before suspend the graph is empty
if (i < 128) {
if (channelData[i] !== 0) {
throw new Error('should be zero')
}
// first sine sample is zero
} else if (i === 128) {
if (channelData[i] !== 0) {
throw new Error('should be zero')
}
} else {
// should ha ve a sine wave, hopefully without zero values :)
if (channelData[i] === 0) {
throw new Error(`should not be zero ${i}`);
console.log(channelData[i])
}
}
}

const latencyHint = process.env.WEB_AUDIO_LATENCY === 'playback' ? 'playback' : 'interactive';
const online = new AudioContext({ latencyHint });

const src = online.createBufferSource();
// src.loop = true;
src.buffer = buffer;
src.loop = true;
src.connect(online.destination);
src.start();

await new Promise(resolve => setTimeout(resolve, 1000));
await new Promise(resolve => setTimeout(resolve, 2000));

await online.close();
Loading