A BitCrusher example from the Web Audio API specification, but modified to
15 | demonstrate AudioParam automations. The sound source is a sawtooth oscillator
16 | at 5000Hz. The demo runs for 8 seconds.
22 |
23 | {% include "../../../_includes/example-source-code.njk" %}
24 |
25 |
26 |
27 |
28 | {% endblock %}
29 |
--------------------------------------------------------------------------------
/src/audio-worklet/basic/handling-errors/error-processor.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2017 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | /**
6 | * A processor with an error in its constructor.
7 | *
8 | * @class ConstructorErrorProcessor
9 | * @extends AudioWorkletProcessor
10 | */
11 | class ConstructorErrorProcessor extends AudioWorkletProcessor {
12 | constructor() {
13 | throw new Error(
14 | 'ConstructorErrorProcessor: an error thrown from constructor.');
15 | }
16 |
17 | process() {
18 | return true;
19 | }
20 | }
21 |
22 |
23 | /**
24 | * A processor with an error in its process callback.
25 | *
26 | * @class ProcessErrorProcessor
27 | * @extends AudioWorkletProcessor
28 | */
29 | class ProcessErrorProcessor extends AudioWorkletProcessor {
30 | constructor() {
31 | super();
32 | }
33 |
34 | process() {
35 | throw new Error(
36 | 'ProcessErrorProcessor: an error throw from process method.');
37 | }
38 | }
39 |
40 |
41 | registerProcessor('constructor-error', ConstructorErrorProcessor);
42 | registerProcessor('process-error', ProcessErrorProcessor);
43 |
--------------------------------------------------------------------------------
/src/audio-worklet/basic/handling-errors/index.njk:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: handling-error
4 | title: Handling Errors
5 | parent: audio-worklet
6 | to_root_dir: ../../../
7 | ---
8 |
9 | {% extends "../../../_includes/base.njk" %}
10 |
11 | {% block content %}
12 |
13 |
{{ eleventyNavigation.title }}
14 |
A simple demonstration on how to catch an error from AudioWorkletProcessor
15 | with onprocessorerror event handler in AudioWorkletNode. Open up the console
16 | to see the events being fired.
Demonstrates basic bi-directional communication between AudioWorkletNode and
15 | AudioWorkletProcessor. Open up the console to see the events being fired.
21 |
22 | {% include "../../../_includes/example-source-code.njk" %}
23 |
24 |
25 |
26 |
27 | {% endblock %}
28 |
--------------------------------------------------------------------------------
/src/audio-worklet/basic/message-port/messenger-processor.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | /* global currentTime */
6 |
7 | /**
8 | * A simple MessagePort tester.
9 | *
10 | * @class MessengerProcessor
11 | * @extends AudioWorkletProcessor
12 | */
13 | class MessengerProcessor extends AudioWorkletProcessor {
14 | constructor() {
15 | super();
16 | this._lastUpdate = currentTime;
17 | this.port.onmessage = this.handleMessage_.bind(this);
18 | }
19 |
20 | handleMessage_(event) {
21 | console.log('[Processor:Received] ' + event.data.message +
22 | ' (' + event.data.contextTimestamp + ')');
23 | }
24 |
25 | process() {
26 | // Post a message to the node for every 1 second.
27 | if (currentTime - this._lastUpdate > 1.0) {
28 | this.port.postMessage({
29 | message: '1 second passed.',
30 | contextTimestamp: currentTime,
31 | });
32 | this._lastUpdate = currentTime;
33 | }
34 |
35 | return true;
36 | }
37 | }
38 |
39 | registerProcessor('messenger-processor', MessengerProcessor);
40 |
--------------------------------------------------------------------------------
/src/audio-worklet/basic/noise-generator/index.njk:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: noise-generator-with-modulation
4 | title: Noise generator with modulation
5 | parent: audio-worklet
6 | to_root_dir: ../../../
7 | ---
8 |
9 | {% extends "../../../_includes/base.njk" %}
10 |
11 | {% block content %}
12 |
13 |
{{ eleventyNavigation.title }}
14 |
A simple noise generator with a user-defined AudioParam modulated by an
15 | OscillatorNode. The modulation on a gain parameter creates a tremolo effect.
16 |
A one pole filter implementation with AudioWorkletNode. A noise generator
15 | goes into an one-pole filter and a series of AudioParam automations is in
16 | action to move the filter frequency.
24 |
25 | {% include "../../../_includes/example-source-code.njk" %}
26 |
27 |
28 |
29 |
30 | {% endblock %}
--------------------------------------------------------------------------------
/src/audio-worklet/basic/volume-meter/volume-meter-processor.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | /* global currentTime */
6 |
7 | const SMOOTHING_FACTOR = 0.8;
8 | const FRAME_PER_SECOND = 60;
9 | const FRAME_INTERVAL = 1 / FRAME_PER_SECOND;
10 |
11 | /**
12 | * Measure microphone volume.
13 | *
14 | * @class VolumeMeter
15 | * @extends AudioWorkletProcessor
16 | */
17 | class VolumeMeter extends AudioWorkletProcessor {
18 |
19 | constructor() {
20 | super();
21 | this._lastUpdate = currentTime;
22 | this._volume = 0;
23 | }
24 |
25 | calculateRMS(inputChannelData) {
26 | // Calculate the squared-sum.
27 | let sum = 0;
28 | for (let i = 0; i < inputChannelData.length; i++) {
29 | sum += inputChannelData[i] * inputChannelData[i];
30 | }
31 |
32 | // Calculate the RMS level and update the volume.
33 | let rms = Math.sqrt(sum / inputChannelData.length);
34 | this._volume = Math.max(rms, this._volume * SMOOTHING_FACTOR);
35 | }
36 |
37 | process(inputs, outputs) {
38 | // This example only handles mono channel.
39 | const inputChannelData = inputs[0][0];
40 |
41 | // Post a message to the node every 16ms.
42 | if (currentTime - this._lastUpdate > FRAME_INTERVAL) {
43 | this.calculateRMS(inputChannelData);
44 | this.port.postMessage(this._volume);
45 | this._lastUpdate = currentTime;
46 | }
47 |
48 | return true;
49 | }
50 | }
51 |
52 | registerProcessor("volume-meter", VolumeMeter);
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/lib/em-es6-module.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | /* global Module */
18 |
19 | // EXPORT_ES6 option does not work as described at
20 | // https://github.com/kripken/emscripten/issues/6284, so we have to
21 | // manually add this by '--post-js' setting when the Emscripten compilation.
22 | export default Module;
23 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/shared-buffer/index.njk:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: audioworklet-sharedarraybuffer-and-worker
4 | title: AudioWorklet, SharedArrayBuffer, and Worker
5 | parent: audio-worklet
6 | to_root_dir: ../../../
7 | ---
8 |
9 | {% extends to_root_dir + "_includes/base.njk" %}
10 |
11 | {% block content %}
12 |
13 |
14 |
15 |
{{ eleventyNavigation.title }}
16 |
This example demonstrates how to take advantage of Worker thread and
17 | SharedArrayBuffer in conjunction with AudioWorklet. This pattern is useful
18 | when bringing legacy audio application written in C/C++ into the web
19 | platform.
This example demonstrates how to handle different buffer sizes between the
15 | C++ audio processing kernel (1024 sample frames) and AudioWorkletProcessor
16 | (128 sample frames).
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm-ring-buffer/main.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | const audioContext = new AudioContext();
6 |
7 | const startAudio = async (context) => {
8 | await context.audioWorklet.addModule('ring-buffer-worklet-processor.js');
9 | const oscillator = new OscillatorNode(context);
10 | const ringBufferWorkletNode =
11 | new AudioWorkletNode(context, 'ring-buffer-worklet-processor', {
12 | processorOptions: {
13 | kernelBufferSize: 1024,
14 | channelCount: 1,
15 | },
16 | });
17 |
18 | oscillator.connect(ringBufferWorkletNode).connect(context.destination);
19 | oscillator.start();
20 | };
21 |
22 | // A simplem onLoad handler. It also handles user gesture to unlock the audio
23 | // playback.
24 | window.addEventListener('load', async () => {
25 | const buttonEl = document.getElementById('button-start');
26 | buttonEl.disabled = false;
27 | buttonEl.addEventListener('click', async () => {
28 | await startAudio(audioContext);
29 | audioContext.resume();
30 | buttonEl.disabled = true;
31 | buttonEl.textContent = 'Playing...';
32 | }, false);
33 | });
34 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm-supersaw/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright 2019 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | #!/bin/bash
16 |
17 | DEPS = $(wildcard ./synth_src/*.cpp)
18 |
19 | build: $(DEPS)
20 | @emcc \
21 | --bind \
22 | --post-js ../lib/em-es6-module.js \
23 | -s ENVIRONMENT=shell \
24 | -s SINGLE_FILE=1 \
25 | -s WASM=1 \
26 | -s WASM_ASYNC_COMPILATION=0 \
27 | -s EXPORTED_FUNCTIONS="['_malloc']" \
28 | -o ./synth.wasm.js \
29 | ./synth_src/synth_bind.cc $(DEPS)
30 |
31 | @echo "Build complete: ./synth.wasm.js"
32 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm-supersaw/README.md:
--------------------------------------------------------------------------------
1 | # How to use wasm-supersaw example
2 |
3 | Unlike other AudioWorklet examples in this repository, this examples needs
4 | an additional step to build and compile. Follow the steps below:
5 |
6 | 1. Install Emscripten in your development setup. Follow the instruction:
7 | https://emscripten.org/docs/getting_started/downloads.html
8 |
9 | 2. Run `emcc -v` to confirm the Emscripten installation and its version. This
10 | example needs 3.1.48 or later to work correctly. (See
11 | [this issue](https://github.com/GoogleChromeLabs/web-audio-samples/issues/348)
12 | for details)
13 |
14 | 3. In the terminal, run `make` to build the WASM file.
15 |
16 | 4. Serve `index.html` file in the directoy.
17 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm-supersaw/synth-processor.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | import Module from './synth.wasm.js';
6 | import { FreeQueue } from '../../../lib/free-queue/free-queue.js';
7 |
8 | /* global sampleRate */
9 |
10 | // Web Audio API's render block size
11 | const NUM_FRAMES = 128;
12 |
13 | class SynthProcessor extends AudioWorkletProcessor {
14 | constructor() {
15 | super();
16 | // Create an instance of Synthesizer and WASM memory helper. Then set up an
17 | // event handler for MIDI data from the main thread.
18 | this._synth = new Module.Synthesizer(sampleRate);
19 | this._wasmHeapBuffer = new FreeQueue(Module, NUM_FRAMES, 1, 1);
20 | this.port.onmessage = this._playTone.bind(this);
21 | }
22 |
23 | process(inputs, outputs) {
24 | // The output buffer (mono) provided by Web Audio API.
25 | const outputBuffer = outputs[0][0];
26 |
27 | // Call the render function to write into the WASM buffer. Then clone the
28 | // rendered data in the first channel to process() callback's output
29 | // buffer.
30 | this._synth.render(this._wasmHeapBuffer.getHeapAddress(), NUM_FRAMES);
31 | outputBuffer.set(this._wasmHeapBuffer.getChannelData(0));
32 |
33 | return true;
34 | }
35 |
36 | _playTone(event) {
37 | const isDown = event.data;
38 | isDown ? this._synth.noteOn(60) : this._synth.noteOff(60);
39 | }
40 | }
41 |
42 | registerProcessor('wasm-synth', SynthProcessor);
43 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm-supersaw/synth_src/ChannelContext.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef OBOE_SYNTH_CHANNEL_CONTEXT_H
18 | #define OBOE_SYNTH_CHANNEL_CONTEXT_H
19 |
20 | #include
21 | #include "SynthMark.h"
22 |
23 | class ChannelContext
24 | {
25 | public:
26 | /**
27 | * Set channel bend using the raw 14-bit number extracted from a MIDI message.
28 | * @param bend14
29 | */
30 | void setMidiBend(int bend14) {
31 | const int32_t offset = 1 << 13;
32 | int32_t centeredBend = bend14 - offset;
33 | mBendSemitones = mBendRange * centeredBend * (1.0f / offset);
34 | }
35 |
36 | /**
37 | *
38 | * @return channel bend in semitones
39 | */
40 | synth_float_t getBend() {
41 | return mBendSemitones;
42 | }
43 |
44 | private:
45 | synth_float_t mBendRange = 2.0f; // pitch offset
46 | synth_float_t mBendSemitones = 0.0f; // pitch offset
47 | };
48 | #endif //OBOE_SYNTH_CHANNEL_CONTEXT_H
49 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm-supersaw/synth_src/PitchToFrequency.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #include "PitchToFrequency.h"
18 |
19 | PowerOfTwoTable PitchToFrequency::mPowerTable(64);
20 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm-supersaw/synth_src/SineOscillator.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * This code was translated from the JSyn Java code.
17 | * JSyn is Copyright 2009 Phil Burk, Mobileer Inc
18 | * JSyn is licensed under the Apache License, Version 2.0
19 | */
20 |
21 | #ifndef SYNTHMARK_SINE_OSCILLATOR_H
22 | #define SYNTHMARK_SINE_OSCILLATOR_H
23 |
24 | #include
25 | #include "SynthMark.h"
26 | #include "SynthTools.h"
27 |
28 | class SineOscillator : public SawtoothOscillator
29 | {
30 | public:
31 | SineOscillator()
32 | : SawtoothOscillator() {}
33 |
34 | virtual ~SineOscillator() = default;
35 |
36 | virtual inline synth_float_t translatePhase(synth_float_t phase, synth_float_t phaseIncrement) {
37 | (void) phaseIncrement;
38 | return SynthTools::fastSine(phase * M_PI);
39 | }
40 |
41 | };
42 |
43 | #endif // SYNTHMARK_SINE_OSCILLATOR_H
44 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm-supersaw/synth_src/UnitGenerator.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #include "UnitGenerator.h"
18 |
19 | int32_t UnitGenerator::mSampleRate = SYNTHMARK_SAMPLE_RATE;
20 | synth_float_t UnitGenerator::mSamplePeriod = 1.0f / SYNTHMARK_SAMPLE_RATE;
21 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm/Makefile:
--------------------------------------------------------------------------------
1 | DEPS = SimpleKernel.cc
2 |
3 | build: $(DEPS)
4 | @emcc --bind -O2 \
5 | -s WASM=1 \
6 | -s WASM_ASYNC_COMPILATION=0 \
7 | -s SINGLE_FILE=1 \
8 | SimpleKernel.cc \
9 | -o simple-kernel.wasmmodule.js \
10 | -s MODULARIZE=1 \
11 | -s EXPORT_ES6=1 \
12 | -s EXPORTED_FUNCTIONS="['_malloc']"
13 |
14 | clean:
15 | @rm -f simple-kernel.wasmmodule.js
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm/index.njk:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: audio-worklet-and-web-assembly
4 | title: Audio Worklet and WebAssembly
5 | parent: audio-worklet
6 | to_root_dir: ../../../
7 | ---
8 |
9 | {% extends to_root_dir + "_includes/base.njk" %}
10 |
11 | {% block content %}
12 |
13 |
{{ eleventyNavigation.title }}
14 |
A basic pattern to use Audio Worklet with WebAssembly. The
15 | AudioWorkletProcessor simply bypasses (copies) the audio via the WebAssembly
16 | function.
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/src/audio-worklet/design-pattern/wasm/main.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | const audioContext = new AudioContext();
6 |
7 | const startAudio = async (context) => {
8 | await context.audioWorklet.addModule('wasm-worklet-processor.js');
9 | const oscillator = new OscillatorNode(context);
10 | const bypasser = new AudioWorkletNode(context, 'wasm-worklet-processor');
11 | oscillator.connect(bypasser).connect(context.destination);
12 | oscillator.start();
13 | };
14 |
15 | // A simple onLoad handler. It also handles user gesture to unlock the audio
16 | // playback.
17 | window.addEventListener('load', async () => {
18 | const buttonEl = document.getElementById('button-start');
19 | buttonEl.disabled = false;
20 | buttonEl.addEventListener('click', async () => {
21 | await startAudio(audioContext);
22 | audioContext.resume();
23 | buttonEl.disabled = true;
24 | buttonEl.textContent = 'Playing...';
25 | }, false);
26 | });
27 |
--------------------------------------------------------------------------------
/src/audio-worklet/free-queue/README.md:
--------------------------------------------------------------------------------
1 | # Free Queue
2 |
3 | A lock-free ring buffer implementation for high-performance audio processing
4 | designed to be used on top of the Web Audio API.
5 |
6 | It is based on the single-producer and single-consumer concept, so it can ensure
7 | thread safe concurrency without locks and mutexes, when the following conditions
8 | are satisfied -
9 | 1. There is only one producer, that is only one thread/worker is pushing data
10 | into the buffer.
11 | 2. There is only one consumer, that is only one thread/worker is pulling data
12 | out of the buffer.
13 |
14 | ## API
15 |
16 | ```ts
17 | // Constructor
18 | FreeQueue(size: number, channelCount: number = 1)
19 | // push data into FreeQueue.
20 | // returns true if pushing data is successful otherwise returns false
21 | push(input: Float32Array[], blockLength: number): boolean
22 | // pull data out of FreeQueue
23 | // returns true if pulling data is successful otherwise returns false
24 | pull(input: Float32Array[], blockLength: number): boolean
25 | // returns length of backing buffer
26 | getBufferLength(): number
27 | // returns if frame of given size is available
28 | isFrameAvailable(size: number): boolean
29 | ```
30 |
31 | ## How it works
32 |
33 | This library can be used between two JavaScript Workers or can be used
34 | with WebAssembly. To use WebAssembly with programming languages like C/C++,
35 | an interface can be used to push and pull data from the buffer.
36 | See interface/README.md.
37 |
--------------------------------------------------------------------------------
/src/audio-worklet/free-queue/examples/simple-passthrough/constants.js:
--------------------------------------------------------------------------------
1 | export const KERNEL_LENGTH = 20;
2 | export const RENDER_QUANTUM = 128;
3 | export const FRAME_SIZE = KERNEL_LENGTH * RENDER_QUANTUM;
4 | export const QUEUE_SIZE = 4096;
5 |
--------------------------------------------------------------------------------
/src/audio-worklet/free-queue/examples/simple-passthrough/index.njk:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: simple-passthrough
4 | title: Simple Passthrough Example
5 | parent: audio-worklet
6 | to_root_dir: ../../../../
7 | ---
8 |
9 | {% extends to_root_dir + "_includes/base.njk" %}
10 |
11 | {% block content %}
12 |
13 |
14 |
15 |
{{ eleventyNavigation.title }}
16 |
This example demonstrates how to take advantage of Worker thread and
17 | FreeQueue in conjunction with AudioWorklet. FreeQueue is being used here to
18 | exchange data between AudioWorklet and Worker thread.
19 |
36 | {% endfor %}
37 |
38 | {% endblock %}
39 |
--------------------------------------------------------------------------------
/src/audio-worklet/migration/spn-recorder/README.md:
--------------------------------------------------------------------------------
1 | # Recorder Demo using ScriptProcessorNode
2 | This demonstrates a basic recording app using ScriptProcessorNode.
--------------------------------------------------------------------------------
/src/audio-worklet/migration/worklet-recorder/README.md:
--------------------------------------------------------------------------------
1 | # Audio Worklet Recording Demo
2 |
3 | This demonstrates a basic recording app using Audio Worklet.
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/DrumCell.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2021 Google Inc. All Rights Reserved.
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /**
17 | * An abstraction of the one-shot sampler
18 | *
19 | * @class DrumCell
20 | */
21 | class DrumCell {
22 | /**
23 | * Creates an instance of DrumCell with two required arguments.
24 | *
25 | * @param {Audionode} outputNode The outgoing AudioNode
26 | * @param {AudioBuffer} audioBuffer An AudioBuffer to be played
27 | * @memberof DrumCell
28 | */
29 | constructor(outputNode, audioBuffer) {
30 | this._context = outputNode.context;
31 | this._buffer = audioBuffer;
32 | this._outputNode = outputNode;
33 | }
34 |
35 | /**
36 | * Plays the assigned buffer when called.
37 | *
38 | * @memberof DrumCell
39 | */
40 | playSample() {
41 | const bufferSource =
42 | new AudioBufferSourceNode(this._context, {buffer: this._buffer});
43 | const amp = new GainNode(this._context);
44 | bufferSource.connect(amp).connect(this._outputNode);
45 | bufferSource.start();
46 | }
47 | }
48 |
49 | export default DrumCell;
50 |
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/README.md:
--------------------------------------------------------------------------------
1 | NOTE: This code example is for a Korean tutorial of "Web Audio API 드럼머신 만들기".
2 | For more information, see the
3 | [blog post](https://developer.chrome.com/blog/mother-language-day-2021/) about
4 | International Mother Language Day 2021 from Chrome Developers.
5 |
6 | # Web Audio API 드럼머신 만들기
7 |
8 | [라이브 데모](https://googlechromelabs.github.io/web-audio-samples/demos/mld-drum-sampler/)
9 |
10 | 데모의 정상적인 사용을 위해서는 샘플 파일들이 필요하며, 튜토리얼 비디오에 사용된 오디오 샘플들은
11 | [이 곳](https://github.com/GoogleChromeLabs/web-audio-samples/tree/main/src/demos/mld-drum-sampler)
12 | 에서 다운로드 할 수 있습니다.
13 |
14 | 로컬 웹서버에서의 실험을 위해서는 이 리포지터리를 `git clone`으로 내려받아 사용하는 것을 추천합니다.
15 |
16 | 사용에 문제 혹은 문의 사항이 있을 경우
17 | [이슈 트랙커](https://github.com/GoogleChromeLabs/web-audio-samples/issues)에 의견을
18 | 남겨주세요.
19 |
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/index.njk:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: mld-drum-sampler
4 | title: Web Audio API 드럼머신 만들기
5 | parent: landing
6 | to_root_dir: ../../
7 | ---
8 |
9 | {% extends "../../_includes/base.njk" %}
10 |
11 | {% block content %}
12 |
13 |
NOTE: This code example is for a Korean tutorial of "Web Audio API 드럼머신
26 | 만들기". For more information, see the Chrome Developers
27 | blog
28 | post about International Mother Language Day 2021.
29 |
30 |
31 |
32 |
아래 버튼을 누르고 오디오 파일들이 포함된 로컬 디렉토리를 선택해주세요. 파일 로딩이 완료되면
33 | 키보드를 사용하여 드럼 사운드를 연주할 수 있습니다.
34 |
35 |
36 |
37 |
38 |
39 | {% endblock %}
40 |
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-fx-01.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-fx-01.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-fx-02.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-fx-02.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-hh-01.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-hh-01.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-hh-02.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-hh-02.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-kd-01.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-kd-01.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-kd-02.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-kd-02.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-oh-01.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-oh-01.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-oh-02.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-oh-02.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-perc-01.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-perc-01.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-perc-02.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-perc-02.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-sd-01.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-sd-01.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/drum-sd-02.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/drum-sd-02.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/ir-hall.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/ir-hall.mp3
--------------------------------------------------------------------------------
/src/demos/mld-drum-sampler/samples/samples.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/mld-drum-sampler/samples/samples.zip
--------------------------------------------------------------------------------
/src/demos/panning-reverberation/simple.css:
--------------------------------------------------------------------------------
1 | body {background:#eed;}
2 | h1 {color:#111;}
3 | a {color:blue; text-decoration:none; font-size:125%}
4 | #canvasID {background:#fff;}
5 | #canvasElevationID {background:#fff;}
6 | .bigList {color:blue; font-size:large; font-weight:bold}
7 | .smallList {color:blue; font-size:medium; font-weight:bold}
8 |
--------------------------------------------------------------------------------
/src/demos/pool/images/poolballs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/pool/images/poolballs.png
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/README.md:
--------------------------------------------------------------------------------
1 | # Audio Recorder
2 |
3 | A simple, responsive, progressive web application that records audio clips using the
4 | device's microphone.
5 |
6 | The user interface is built with [Material Components Web](https://material.io/develop/web).
7 | The audio is recorded with the [MediaStream Recording API](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API)
8 | and visualized with an [AnalyserNode](https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode).
9 |
10 | ## Contributing
11 |
12 | This web application is intentionally simple and does not rely on a build step
13 | of any sort.
14 |
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/icons/android-chrome-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/pwa-audio-recorder/icons/android-chrome-192.png
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/icons/android-chrome-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/pwa-audio-recorder/icons/android-chrome-512.png
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/pwa-audio-recorder/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/icons/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/pwa-audio-recorder/icons/favicon.png
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/icons/maskable-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/pwa-audio-recorder/icons/maskable-192.png
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/icons/maskable-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/pwa-audio-recorder/icons/maskable-512.png
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Audio Recorder",
3 | "short_name": "Recorder",
4 | "theme_color": "#d32f2f",
5 | "background_color": "#f5f5f6",
6 | "display": "standalone",
7 | "icons": [
8 | {
9 | "src": "icons/android-chrome-192.png",
10 | "sizes": "192x192",
11 | "type": "image/png"
12 | },
13 | {
14 | "src": "icons/apple-touch-icon.png",
15 | "sizes": "180x180",
16 | "type": "image/png"
17 | },
18 | {
19 | "src": "icons/android-chrome-512.png",
20 | "sizes": "512x512",
21 | "type": "image/png"
22 | },
23 | {
24 | "src": "icons/maskable-192.png",
25 | "sizes": "192x192",
26 | "type": "image/png",
27 | "purpose": "maskable"
28 | },
29 | {
30 | "src": "icons/maskable-512.png",
31 | "sizes": "512x512",
32 | "type": "image/png",
33 | "purpose": "maskable"
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/src/demos/pwa-audio-recorder/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | background-color: #f5f5f6;
4 | --mdc-theme-primary: #d32f2f;
5 | }
6 |
7 | .sound-clips {
8 | display: flex;
9 | flex-direction: column;
10 | row-gap: 1em;
11 | margin: 2em;
12 | }
13 |
14 | .clip {
15 | display: flex;
16 | overflow: hidden;
17 | }
18 |
19 | .clip audio {
20 | flex-grow: 1;
21 | }
22 |
23 | .clip canvas {
24 | display: none;
25 | }
26 |
27 | .clip.clip-recording canvas {
28 | display: block;
29 | }
30 |
31 | .clip-recording .recording-invisible {
32 | display: none;
33 | }
34 |
35 | /* Hide empty state as soon as the first sound clip is added to .sound-clips. */
36 | .sound-clips > * ~ .empty {
37 | display: none;
38 | }
39 |
40 | .empty {
41 | text-align: center;
42 | opacity: 0.2;
43 | margin-top: 4em;
44 | }
45 |
46 | .empty .material-icons {
47 | font-size: 10em;
48 | }
49 |
50 | #record-outline {
51 | position: fixed;
52 | bottom: 2em;
53 | left: 50%;
54 | transform: translateX(-50%);
55 | border-radius: 50%;
56 | }
57 |
58 | .mdc-fab {
59 | background-color: var(--mdc-theme-primary);
60 | }
61 |
62 | .mdc-top-app-bar__title {
63 | padding: 0;
64 | }
65 |
66 | .logo {
67 | padding: 0 5px 0 20px;
68 | }
69 |
70 | audio::-webkit-media-controls-enclosure {
71 | background: none;
72 | }
73 |
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/LED_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/LED_off.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/LED_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/LED_on.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_cancel.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo1.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo1_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo1_loading.gif
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo2.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo2_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo2_loading.gif
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo3.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo3_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo3_loading.gif
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo4.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo4_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo4_loading.gif
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo5.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_demo5_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_demo5_loading.gif
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_load.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_load.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_ok.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_play.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_play_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_play_loading.gif
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_reset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_reset.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_save.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/btn_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/btn_stop.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/button_half.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/button_half.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/button_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/button_off.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/button_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/button_on.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/drop_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/drop_arrow.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/slider_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/slider_thumb.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/slider_track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/slider_track.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/sliderh_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/sliderh_thumb.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/sliderh_track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/sliderh_track.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/tempo_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/tempo_bg.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/tempo_dec.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/tempo_dec.png
--------------------------------------------------------------------------------
/src/demos/shiny-drum-machine/images/tempo_inc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/shiny-drum-machine/images/tempo_inc.png
--------------------------------------------------------------------------------
/src/demos/stress-box/assets/style.css:
--------------------------------------------------------------------------------
1 | canvas {
2 | padding: 0;
3 | margin: 0;
4 | background-color: #333388;
5 | user-select: none;
6 | }
7 |
8 | .log {
9 | font-family: monospace;
10 | font-size: 13px;
11 | margin-bottom: 20px;
12 | }
13 |
--------------------------------------------------------------------------------
/src/demos/stress-box/js/lib.js:
--------------------------------------------------------------------------------
1 | // Copyright 2016 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | /**
6 | * @fileOverview Utility collection for stress testing.
7 | */
8 |
9 | const Lib = {
10 |
11 | getSystemInfo: () => {
12 | let ua = navigator.userAgent;
13 | let M = ua.match(
14 | /(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*([\d\.]+)/i) ||
15 | [];
16 | let tem;
17 | if (/trident/i.test(M[1])) {
18 | tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
19 | return {name:'IE', version: (tem[1] || '')};
20 | }
21 | if (M[1] === 'Chrome') {
22 | tem = ua.match(/\bOPR|Edge\/(\d+)/)
23 | if(tem != null) {
24 | return {name: 'Opera', version: tem[1]};
25 | }
26 | }
27 | M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
28 | if((tem = ua.match(/version\/([\d.]+)/i)) != null) {
29 | M.splice(1, 1, tem[1]);
30 | }
31 | return {
32 | name: M[0],
33 | version: M[1]
34 | };
35 | },
36 |
37 | getLoadingTime: () => {
38 | let timingInfo = performance.timing;
39 | return timingInfo.loadEventStart - timingInfo.navigationStart;
40 | },
41 |
42 | maybe: () => {
43 | return Math.random() < 0.5;
44 | },
45 |
46 | getMousePosition: (element, clickEvent) => {
47 | let rect = element.getBoundingClientRect();
48 | return {
49 | x: clickEvent.clientX - rect.left,
50 | y: clickEvent.clientY - rect.top
51 | };
52 | }
53 | };
54 |
--------------------------------------------------------------------------------
/src/demos/stress-box/js/stack.js:
--------------------------------------------------------------------------------
1 | /**
2 | * [stack description]
3 | * @type {Object}
4 | */
5 | demos.stack = {};
6 |
7 |
8 | /**
9 | * [initWorld description]
10 | * @param {[type]} world [description]
11 | * @return {[type]} [description]
12 | */
13 | demos.stack.initWorld = function (world) {
14 | let sd = new b2BoxDef();
15 | let bd = new b2BodyDef();
16 | bd.AddShape(sd);
17 | sd.density = 1.0;
18 | sd.friction = 0.5;
19 | sd.extents.Set(10, 10);
20 |
21 | let i;
22 | for (i = 0; i < 8; i++) {
23 | bd.position.Set(500/2-Math.random()*2-1, (250-5-i*22));
24 | world.CreateBody(bd);
25 | }
26 | for (i = 0; i < 8; i++) {
27 | bd.position.Set(500/2-100-Math.random()*5+i, (250-5-i*22));
28 | world.CreateBody(bd);
29 | }
30 | for (i = 0; i < 8; i++) {
31 | bd.position.Set(500/2+100+Math.random()*5-i, (250-5-i*22));
32 | world.CreateBody(bd);
33 | }
34 | }
35 |
36 |
37 | /**
38 | *
39 | */
40 | demos.InitWorlds.push(demos.stack.initWorld);
41 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/ClipVertex.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 |
22 |
23 | var ClipVertex = Class.create();
24 | ClipVertex.prototype =
25 | {
26 | v: new b2Vec2(),
27 | id: new b2ContactID(),
28 | initialize: function() {
29 | // initialize instance variables for references
30 | this.v = new b2Vec2();
31 | this.id = new b2ContactID();
32 | //
33 | }};
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/b2Bound.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | var b2Bound = Class.create();
22 | b2Bound.prototype = {
23 | IsLower: function(){ return (this.value & 1) == 0; },
24 | IsUpper: function(){ return (this.value & 1) == 1; },
25 | Swap: function(b){
26 | var tempValue = this.value;
27 | var tempProxyId = this.proxyId;
28 | var tempStabbingCount = this.stabbingCount;
29 |
30 | this.value = b.value;
31 | this.proxyId = b.proxyId;
32 | this.stabbingCount = b.stabbingCount;
33 |
34 | b.value = tempValue;
35 | b.proxyId = tempProxyId;
36 | b.stabbingCount = tempStabbingCount;
37 | },
38 |
39 | value: 0,
40 | proxyId: 0,
41 | stabbingCount: 0,
42 |
43 | initialize: function() {}}
44 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/b2BoundValues.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | var b2BoundValues = Class.create();
22 | b2BoundValues.prototype = {
23 | lowerValues: [0,0],
24 | upperValues: [0,0],
25 |
26 | initialize: function() {
27 | // initialize instance variables for references
28 | this.lowerValues = [0,0];
29 | this.upperValues = [0,0];
30 | //
31 | }}
32 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/b2BufferedPair.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | var b2BufferedPair = Class.create();
22 | b2BufferedPair.prototype = {
23 | proxyId1: 0,
24 | proxyId2: 0,
25 |
26 | initialize: function() {}}
27 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/b2ContactPoint.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | // We use contact ids to facilitate warm starting.
22 | var b2ContactPoint = Class.create();
23 | b2ContactPoint.prototype =
24 | {
25 | position: new b2Vec2(),
26 | separation: null,
27 | normalImpulse: null,
28 | tangentImpulse: null,
29 | id: new b2ContactID(),
30 | initialize: function() {
31 | // initialize instance variables for references
32 | this.position = new b2Vec2();
33 | this.id = new b2ContactID();
34 | //
35 | }};
36 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/b2Manifold.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | // A manifold for two touching convex shapes.
22 | var b2Manifold = Class.create();
23 | b2Manifold.prototype =
24 | {
25 | initialize: function(){
26 | this.points = new Array(b2Settings.b2_maxManifoldPoints);
27 | for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++){
28 | this.points[i] = new b2ContactPoint();
29 | }
30 | this.normal = new b2Vec2();
31 | },
32 | points: null,
33 | normal: null,
34 | pointCount: 0};
35 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/b2OBB.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | // A manifold for two touching convex shapes.
22 | var b2OBB = Class.create();
23 | b2OBB.prototype =
24 | {
25 | R: new b2Mat22(),
26 | center: new b2Vec2(),
27 | extents: new b2Vec2(),
28 | initialize: function() {
29 | // initialize instance variables for references
30 | this.R = new b2Mat22();
31 | this.center = new b2Vec2();
32 | this.extents = new b2Vec2();
33 | //
34 | }};
35 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/b2PairCallback.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | var b2PairCallback = Class.create();
22 | b2PairCallback.prototype =
23 | {
24 | //virtual ~b2PairCallback() {}
25 |
26 | // This returns the new pair user data.
27 | PairAdded: function(proxyUserData1, proxyUserData2){return null},
28 |
29 | // This should free the pair's user data. In extreme circumstances, it is possible
30 | // this will be called with null pairUserData because the pair never existed.
31 | PairRemoved: function(proxyUserData1, proxyUserData2, pairUserData){},
32 | initialize: function() {}};
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/b2Proxy.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | var b2Proxy = Class.create();
22 | b2Proxy.prototype = {
23 | GetNext: function(){ return this.lowerBounds[0]; },
24 | SetNext: function(next) { this.lowerBounds[0] = next /*& 0x0000ffff*/; },
25 |
26 | IsValid: function(){ return this.overlapCount != b2BroadPhase.b2_invalid; },
27 |
28 | lowerBounds: [/*uint*/(0), /*uint*/(0)],
29 | upperBounds: [/*uint*/(0), /*uint*/(0)],
30 | overlapCount: 0,
31 | timeStamp: 0,
32 |
33 | userData: null,
34 |
35 | initialize: function() {
36 | // initialize instance variables for references
37 | this.lowerBounds = [/*uint*/(0), /*uint*/(0)];
38 | this.upperBounds = [/*uint*/(0), /*uint*/(0)];
39 | //
40 | }}
41 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/collision/shapes/b2MassData.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | var b2MassData = Class.create();
26 | b2MassData.prototype =
27 | {
28 | mass: 0.0,
29 | center: new b2Vec2(0,0),
30 | I: 0.0,
31 |
32 | initialize: function() {
33 | // initialize instance variables for references
34 | this.center = new b2Vec2(0,0);
35 | //
36 | }}
37 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/dynamics/b2CollisionFilter.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | var b2CollisionFilter = Class.create();
26 | b2CollisionFilter.prototype =
27 | {
28 |
29 | // Return true if contact calculations should be performed between these two shapes.
30 | ShouldCollide: function(shape1, shape2){
31 | if (shape1.m_groupIndex == shape2.m_groupIndex && shape1.m_groupIndex != 0)
32 | {
33 | return shape1.m_groupIndex > 0;
34 | }
35 |
36 | var collide = (shape1.m_maskBits & shape2.m_categoryBits) != 0 && (shape1.m_categoryBits & shape2.m_maskBits) != 0;
37 | return collide;
38 | },
39 |
40 |
41 | initialize: function() {}};
42 | b2CollisionFilter.b2_defaultFilter = new b2CollisionFilter;
43 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/dynamics/b2TimeStep.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | var b2TimeStep = Class.create();
22 | b2TimeStep.prototype =
23 | {
24 | dt: null,
25 | inv_dt: null,
26 | iterations: 0,
27 | initialize: function() {}};
28 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/dynamics/contacts/b2ContactConstraint.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 |
22 |
23 | var b2ContactConstraint = Class.create();
24 | b2ContactConstraint.prototype =
25 | {
26 | initialize: function(){
27 | // initialize instance variables for references
28 | this.normal = new b2Vec2();
29 | //
30 |
31 | this.points = new Array(b2Settings.b2_maxManifoldPoints);
32 | for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++){
33 | this.points[i] = new b2ContactConstraintPoint();
34 | }
35 |
36 |
37 | },
38 | points: null,
39 | normal: new b2Vec2(),
40 | manifold: null,
41 | body1: null,
42 | body2: null,
43 | friction: null,
44 | restitution: null,
45 | pointCount: 0};
46 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/dynamics/contacts/b2ContactConstraintPoint.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 |
22 |
23 | var b2ContactConstraintPoint = Class.create();
24 | b2ContactConstraintPoint.prototype =
25 | {
26 | localAnchor1: new b2Vec2(),
27 | localAnchor2: new b2Vec2(),
28 | normalImpulse: null,
29 | tangentImpulse: null,
30 | positionImpulse: null,
31 | normalMass: null,
32 | tangentMass: null,
33 | separation: null,
34 | velocityBias: null,
35 | initialize: function() {
36 | // initialize instance variables for references
37 | this.localAnchor1 = new b2Vec2();
38 | this.localAnchor2 = new b2Vec2();
39 | //
40 | }};
41 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/dynamics/contacts/b2ContactNode.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 |
22 |
23 | var b2ContactNode = Class.create();
24 | b2ContactNode.prototype =
25 | {
26 | other: null,
27 | contact: null,
28 | prev: null,
29 | next: null,
30 | initialize: function() {}};
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/dynamics/contacts/b2ContactRegister.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 | var b2ContactRegister = Class.create();
22 | b2ContactRegister.prototype =
23 | {
24 | createFcn: null,
25 | destroyFcn: null,
26 | primary: null,
27 | initialize: function() {}};
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/dynamics/joints/b2JointDef.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 |
22 |
23 | var b2JointDef = Class.create();
24 | b2JointDef.prototype =
25 | {
26 |
27 | initialize: function()
28 | {
29 | this.type = b2Joint.e_unknownJoint;
30 | this.userData = null;
31 | this.body1 = null;
32 | this.body2 = null;
33 | this.collideConnected = false;
34 | },
35 |
36 | type: 0,
37 | userData: null,
38 | body1: null,
39 | body2: null,
40 | collideConnected: null}
41 |
--------------------------------------------------------------------------------
/src/demos/stress-box/third-party/box2d/dynamics/joints/b2JointNode.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2007 Erin Catto http:
3 | *
4 | * This software is provided 'as-is', without any express or implied
5 | * warranty. In no event will the authors be held liable for any damages
6 | * arising from the use of this software.
7 | * Permission is granted to anyone to use this software for any purpose,
8 | * including commercial applications, and to alter it and redistribute it
9 | * freely, subject to the following restrictions:
10 | * 1. The origin of this software must not be misrepresented; you must not
11 | * claim that you wrote the original software. If you use this software
12 | * in a product, an acknowledgment in the product documentation would be
13 | * appreciated but is not required.
14 | * 2. Altered source versions must be plainly marked, and must not be
15 | * misrepresented the original software.
16 | * 3. This notice may not be removed or altered from any source distribution.
17 | */
18 |
19 |
20 |
21 |
22 |
23 | var b2JointNode = Class.create();
24 | b2JointNode.prototype =
25 | {
26 |
27 | other: null,
28 | joint: null,
29 | prev: null,
30 | next: null,
31 |
32 |
33 | initialize: function() {}}
34 |
--------------------------------------------------------------------------------
/src/demos/visualizer/shaders/common-vertex.shader:
--------------------------------------------------------------------------------
1 | // The common vertex shader used for the frequency and sonogram visualizations
2 | attribute vec3 gPosition;
3 | attribute vec2 gTexCoord0;
4 |
5 | varying vec2 texCoord;
6 |
7 | void main()
8 | {
9 | gl_Position = vec4(gPosition.x, gPosition.y, gPosition.z, 1.0);
10 | texCoord = gTexCoord0;
11 | }
12 |
--------------------------------------------------------------------------------
/src/demos/visualizer/shaders/frequency-fragment.shader:
--------------------------------------------------------------------------------
1 | // Frequency fragment shader
2 | #ifdef GL_ES
3 | precision mediump float;
4 | #endif
5 |
6 | varying vec2 texCoord;
7 | uniform sampler2D frequencyData;
8 | uniform vec4 foregroundColor;
9 | uniform vec4 backgroundColor;
10 | uniform float yoffset;
11 |
12 | void main()
13 | {
14 | vec4 sample = texture2D(frequencyData, vec2(texCoord.x, yoffset));
15 | if (texCoord.y > sample.a) {
16 | // if (texCoord.y > sample.a + 1 || texCoord.y < sample.a - 1) {
17 | discard;
18 | }
19 | float x = texCoord.y / sample.a;
20 | x = x * x * x;
21 | gl_FragColor = mix(foregroundColor, backgroundColor, x);
22 | }
23 |
--------------------------------------------------------------------------------
/src/demos/visualizer/shaders/sonogram-fragment.shader:
--------------------------------------------------------------------------------
1 | // Sonogram fragment shader
2 | #ifdef GL_ES
3 | precision mediump float;
4 | #endif
5 |
6 | varying vec2 texCoord;
7 |
8 | uniform sampler2D frequencyData;
9 | uniform vec4 foregroundColor;
10 | uniform vec4 backgroundColor;
11 | uniform float yoffset;
12 |
13 | void main()
14 | {
15 | float x = pow(256.0, texCoord.x - 1.0);
16 | float y = texCoord.y + yoffset;
17 |
18 | vec4 sample = texture2D(frequencyData, vec2(x, y));
19 | float k = sample.a;
20 |
21 | // gl_FragColor = vec4(k, k, k, 1.0);
22 | // Fade out the mesh close to the edges
23 | float fade = pow(cos((1.0 - texCoord.y) * 0.5 * 3.1415926535), 0.5);
24 | k *= fade;
25 | vec4 color = k * vec4(0,0,0,1) + (1.0 - k) * backgroundColor;
26 | gl_FragColor = color;
27 | }
28 |
--------------------------------------------------------------------------------
/src/demos/visualizer/shaders/sonogram-vertex.shader:
--------------------------------------------------------------------------------
1 | // The vertex shader used for the 3D sonogram visualization
2 |
3 | attribute vec3 gPosition;
4 | attribute vec2 gTexCoord0;
5 | uniform sampler2D vertexFrequencyData;
6 | uniform float vertexYOffset;
7 | uniform mat4 worldViewProjection;
8 | uniform float verticalScale;
9 |
10 | varying vec2 texCoord;
11 |
12 | void main()
13 | {
14 | float x = pow(256.0, gTexCoord0.x - 1.0);
15 | vec4 sample = texture2D(vertexFrequencyData, vec2(x, gTexCoord0.y + vertexYOffset));
16 | vec4 newPosition = vec4(gPosition.x, gPosition.y + verticalScale * sample.a, gPosition.z, 1.0);
17 | gl_Position = worldViewProjection * newPosition;
18 | texCoord = gTexCoord0;
19 | }
20 |
--------------------------------------------------------------------------------
/src/demos/visualizer/shaders/waveform-fragment.shader:
--------------------------------------------------------------------------------
1 | // Waveform fragment shader
2 | #ifdef GL_ES
3 | precision mediump float;
4 | #endif
5 |
6 | varying vec2 texCoord;
7 | uniform sampler2D frequencyData;
8 | uniform vec4 foregroundColor;
9 | uniform vec4 backgroundColor;
10 | uniform float yoffset;
11 |
12 | void main()
13 | {
14 | vec4 sample = texture2D(frequencyData, vec2(texCoord.x, yoffset));
15 | if (texCoord.y > sample.a + 0.01 || texCoord.y < sample.a - 0.01) {
16 | discard;
17 | }
18 | float x = (texCoord.y - sample.a) / 0.01;
19 | x = x * x * x;
20 | gl_FragColor = mix(foregroundColor, backgroundColor, x);
21 | }
22 |
--------------------------------------------------------------------------------
/src/demos/wavetable-synth-2/README.md:
--------------------------------------------------------------------------------
1 | # Local Development
2 |
3 | - `cd` to `wavetable-synth-2` directory.
4 | - Use `python3 -m http.server` for now.
5 |
--------------------------------------------------------------------------------
/src/demos/wavetable-synth-2/sound/matrix-reverb6.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/wavetable-synth-2/sound/matrix-reverb6.wav
--------------------------------------------------------------------------------
/src/demos/wavetable-synth-2/style/style.css:
--------------------------------------------------------------------------------
1 | /* For fonts */
2 | body {
3 | font-family: 'Inter', sans-serif;
4 | font-optical-sizing: auto;
5 | font-weight: 400;
6 | font-style: normal;
7 | min-height: 100vh;
8 | color: #d1d5db;
9 | background-color: #30353a;
10 | }
11 |
12 | .header {
13 | display: flex;
14 | justify-content: center;
15 | align-items: center;
16 | padding: 20px;
17 | }
18 |
19 | .synth-container {
20 | display: flex;
21 | flex-direction: column;
22 | justify-content: center;
23 | align-items: center;
24 | font-family: sans-serif;
25 | gap: 20px;
26 | /* flex-wrap: wrap; Allow wrapping if needed */
27 | padding: 20px;
28 | }
29 |
30 | .footer {
31 | font-size: small;
32 | display: flex;
33 | justify-content: center;
34 | align-items: center;
35 | padding: 20px;
36 | }
37 |
38 | knob-simple {
39 | width: 90px; /* Example width */
40 | height: 120px; /* Example height */
41 | }
42 |
43 | matrix-sequence-2d {
44 | /* Updated tag name */
45 | display: block; /* Make it a block element */
46 | width: 600px; /* Example width */
47 | max-width: 600px;
48 | height: 300px; /* Example height */
49 | border: 1px solid #ccc;
50 | cursor: crosshair;
51 | margin-bottom: 20px;
52 | touch-action: none; /* Prevent default touch actions like scrolling */
53 | }
54 |
--------------------------------------------------------------------------------
/src/demos/wavetable-synth/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoogleChromeLabs/web-audio-samples/8de65f6daa6bea0cdc5583a1833e6da981aa5f73/src/demos/wavetable-synth/images/loading.gif
--------------------------------------------------------------------------------
/src/demos/wavetable-synth/lib/buffer-loader.js:
--------------------------------------------------------------------------------
1 | function BufferLoader(context, urlList, callback) {
2 | this.context = context;
3 | this.urlList = urlList;
4 | this.onload = callback;
5 | this.bufferList = new Array();
6 | this.loadCount = 0;
7 | }
8 |
9 | BufferLoader.prototype.loadBuffer = function(url, index) {
10 | // Load buffer asynchronously
11 | var request = new XMLHttpRequest();
12 | request.open("GET", url, true);
13 | request.responseType = "arraybuffer";
14 |
15 | var loader = this;
16 |
17 | request.onload = function() {
18 | // Asynchronously decode the audio file data in request.response
19 | loader.context.decodeAudioData(
20 | request.response, function(buffer) {
21 | if (!buffer) {
22 | alert('error decoding file data: ' + url);
23 | return;
24 | }
25 | loader.bufferList[index] = buffer;
26 | if (++loader.loadCount == loader.urlList.length) loader.onload(loader.bufferList);
27 | }, function(error) {
28 | console.error('decodeAudioData error', error);
29 | });
30 | }
31 |
32 | request.onerror = function() {
33 | alert('BufferLoader: XHR error');
34 | }
35 |
36 | request.send();
37 | }
38 |
39 | BufferLoader.prototype.load = function() {
40 | for (var i = 0; i < this.urlList.length; ++i)
41 | this.loadBuffer(this.urlList[i], i);
42 | }
43 |
--------------------------------------------------------------------------------
/src/demos/wavetable-synth/lib/global-effects.js:
--------------------------------------------------------------------------------
1 | function GlobalEffects(context) {
2 | this.context = context;
3 |
4 | // Create dynamics compressor to sweeten the overall mix.
5 | var compressor = context.createDynamicsCompressor();
6 | compressor.connect(context.destination);
7 |
8 | var convolver = context.createConvolver();
9 |
10 | convolver.connect(compressor);
11 |
12 | // BPM delay through delayWaveShaper feedback loop
13 | var bpmDelay = new BpmDelay(context);
14 |
15 | bpmDelay.delay.connect(compressor);
16 |
17 | var delayFeedback = context.createGain();
18 | delayFeedback.gain.value = 0.5;
19 | bpmDelay.delay.connect(delayFeedback);
20 | delayWaveShaper = new WaveShaper(context);
21 |
22 | delayFeedback.connect(delayWaveShaper.input);
23 | delayWaveShaper.output.connect(bpmDelay.delay);
24 |
25 | this.compressor = compressor;
26 | this.convolver = convolver;
27 | this.bpmDelay = bpmDelay;
28 | this.delayFeedback = delayFeedback;
29 | this.delayWaveShaper = delayWaveShaper;
30 |
31 | this.setDelayGrunge(4.0);
32 | }
33 |
34 | GlobalEffects.prototype.setDelayFeedback = function(x) {
35 | this.delayFeedback.gain.value = x;
36 | }
37 |
38 | GlobalEffects.prototype.setDelayGrunge = function(driveDb) {
39 | this.delayWaveShaper.setDrive(Math.pow(10, 0.05*driveDb));
40 | }
41 |
42 | GlobalEffects.prototype.setConvolverBuffer = function(buffer) {
43 | this.convolver.buffer = buffer;
44 | }
45 |
--------------------------------------------------------------------------------
/src/demos/wavetable-synth/simple.css:
--------------------------------------------------------------------------------
1 | body {background:#eed;}
2 | h1 {color:#111;}
3 | a {color:blue; text-decoration:none; font-size:125%}
4 | #canvasID {background:#fff;}
5 | #canvasElevationID {background:#fff;}
6 | .bigList {color:blue; font-size:large; font-weight:bold}
7 | .smallList {color:blue; font-size:medium; font-weight:bold}
8 |
--------------------------------------------------------------------------------
/src/experiments/index.njk:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: experiments
4 | title: Experiments
5 | parent: landing
6 | to_root_dir: ../
7 | ---
8 |
9 | {% extends "../_includes/base.njk" %}
10 |
11 | {% block content %}
12 |
13 |
14 |
Experiments
15 |
TODO: Experiments
16 |
17 |
18 | {% for section in experiments_data %}
19 |
Press "Start Audio" button to start the test. The test will play 3 segments
15 | (3 seconds each) of the ConstantSourceNode with a DC offset of 0.5. This
16 | source is spatialized by the PannerNode with HRTF. Ideally, the spatialization
17 | should not cause any artifacts. (e.g. glitches, sudden changes)
Press "Start Audio" button to start the test. Check if you can hear any
15 | audio glitches from your eadbuds or a headset. See
16 | Issue 331682035 for more details.
17 |
18 |
Refresh the page to run the test again.
19 |
20 |
21 |
22 | {% include "../../_includes/example-source-code.njk" %}
23 |